Skip to content

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

@henrykim1004

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.

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