SAmeis / pascalio

Input/Output library for Raspberry Pi or any other Linux based microcontroller
Other
29 stars 9 forks source link

Ultrasonic example with HC-SR04 on Orange Pi 5. #13

Open henrykim1004 opened 9 months ago

henrykim1004 commented 9 months ago

I tried pascalio recently on Orange Pi 5.
For ultrasonic example with HC-SR04, existing sample did not work well. So I have fixed it to make it work. This is my working sample made with other time routines. (You may use it to publish.)

========== New Working Ultrasonic Sample on Orange Pi 5 =========

program opi5_hc_sr04;

uses sysutils, pascalio, fpgpio, baseunix, unix, math;

const GPIO_TRIGGER = 52; GPIO_ECHO = 35;

var trigger : TGpioPin; echo : TGpioPin; distance : Double;

procedure millisecondSleep(const ms : real); // uses BaseUnix var // .1 millisecond level sleep (warning 70 microsecond overhead) Reqested, Remaining : TimeSpec; ResultVal : Longint; NanoSecondVal : LongInt; ErrorOverhead : LongInt = 70000; // 70 microsecond overhead begin // 1 milisecond = 1,000,000 nano second NanoSecondVal := round(ms * 1000000 - ErrorOverhead); // Here, enter time to sleep (seconds + nanoseconds) with Reqested do begin tv_sec := 0; tv_nsec := NanoSecondVal; // 100 microseconds = .1 milliseconds end;

// Sleep ResultVal:=(fpNanoSleep(@Reqested,@Remaining));

if ResultVal <> 0 then begin writeln('Remaining nanoseconds : ',Remaining.tv_nsec); writeln('Remaining seconds : ',Remaining.tv_sec); end; end;

procedure DoSigInt(sig: cint); cdecl; begin Writeln('Signal ', sig, ' received.'); raise Exception.Create('Signal received.'); end;

function MeasureDistance: Double; var StartTime: TDateTime; StopTime: TDateTime; TimeElapsed: Extended;

  tvprev, tvcur : timeval;  // for fpgettimeofday
  microgap : Longint;

begin trigger.Value := True; //WriteLn(ErrOutput, 'TRIGGER set to: ', trigger.Value); millisecondSleep(10); trigger.Value := False; //WriteLn(ErrOutput, 'TRIGGER set to: ', trigger.Value);

StartTime := Now;

while not echo.Value do fpgettimeofday(@tvprev, nil);

while echo.Value do fpgettimeofday(@tvcur, nil); // get timestamp AFTER sleep

// Get the gap only for microseconds which is my interest point. microgap := tvcur.tv_usec - tvprev.tv_usec;

Result := microgap / 58; // 58 for cm. For inch, 148 end;

begin // Signal handler for SIG_INT (CTRL+C) FpSignal(SIGINT, @DoSigInt);

// setup GPIO pins trigger := TGpioLinuxPin.Create(GPIO_TRIGGER); trigger.Direction := gdOut; echo := TGpioLinuxPin.Create(GPIO_ECHO ); echo.Direction := gdIn;

try while True do begin distance := MeasureDistance; Writeln(Format('Measured Distance = %4.2f cm', [distance])); Sleep(200); end; except on Exception do WriteLn(ErrOutput, 'Terminated'); end;

trigger.Free; echo.Free; end.