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.
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;
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.