Skip to content

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

Description

@henrykim1004

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.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions