Working with Microseconds lazarus / 8-Other ---------------------------------------------------------------------- enko · 2017-08-18 19:13 Im starting to work with Rasperry Pi3 devices and I'm study this C code : Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i /********************************    Ultra Sonic Raning module Pin VCC should*  be connected to 5V power.******************************/#include #include #include  #define Trig    0#define Echo    1 void ultraInit(void){        pinMode(Echo, INPUT);        pinMode(Trig, OUTPUT);} float disMeasure(void){        struct timeval tv1;        struct timeval tv2;        long time1, time2;    float dis;         digitalWrite(Trig, LOW);        delayMicroseconds(2);         digitalWrite(Trig, HIGH);        delayMicroseconds(10);      //发出超声波脉冲        digitalWrite(Trig, LOW);                                                                      while(!(digitalRead(Echo) == 1));        gettimeofday(&tv1, NULL);           //获取当前时间         while(!(digitalRead(Echo) == 0));        gettimeofday(&tv2, NULL);         //获取当前时间         time1 = tv1.tv_sec * 1000000 + tv1.tv_usec;   //微秒级的时间        time2  = tv2.tv_sec * 1000000 + tv2.tv_usec;         dis = (float)(time2 - time1) / 1000000 * 34000 / 2;  //求出距离         return dis;} int main(void){        float dis;         if(wiringPiSetup() == -1){ //when initialize wiring failed,print messageto screen                printf("setup wiringPi failed !");              return 1;         }         ultraInit();                while(1){                dis = disMeasure();                printf("%0.2f cm\n\n",dis);                delay(300);        }       return 0;}  to interact with gpio i'm using h2wiringpi.pas (digitalWrite, DigitalRead, delayMicroseconds), to calcolate time difference I'm using a function found in this forum : Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i function GetTickCount: Cardinal;var  tv: ptimeval;begin  fpgettimeofday(tv, nil);  Result := int64(tv.tv_sec) * 1000000 + tv.tv_usec;end; when the programm execute GetTickCount I've an Access Violation Can anyone help me ? ---------------------------------------------------------------------- Thaddy · 2017-08-18 19:24 GetTickCount64 is standard in sysutils... example RPi3 code: Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i uses sysutils;beginwriteln(GetTickCount64);end. Your own code contains lots of mistakes, btw: Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i //  use the above code instead because it faster, monotonic and cross-platform.. but this is your corrected code.function GetTickCount:qword;  // it is twice the size of a cardinal!! And unsigned!var  tv: ptimeval;begin  fpgettimeofday(tv, nil); // sure about nil?......?? Also wrong anyway fpgettimeofday returns microsecond resolution NOT nanoseconds. This is also the acces violation...   Result := tv.tv_sec * 1000000 + tv.tv_usec; // is enough. You cast to a signed int64 and return a 32 bit type cardinal.... Won't overflow for a couple of million yearsend; ---------------------------------------------------------------------- enko · 2017-08-19 10:38 Thanks Thaddy for your answer Using your function GetTickCount revisited I continue to have Access Violation. I copy and paste your function GetTickCount revisited in a new console program Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i program Project1;uses SysUtils, Unix, baseunix; function GetTickCount:qword;  // it is twice the size of a cardinal!! And unsigned!var  tv: PTimeVal;  tz: PTimeZone;begin  tz := nil;  fpgettimeofday(tv, tz); // sure about nil?......?? Also wrong anyway fpgettimeofday returns microsecond resolution NOT nanoseconds. This is also the acces violation...  Result := tv.tv_sec * 1000000 + tv.tv_usec; // is enough. You cast to a signed int64 and return a 32 bit type cardinal.... Won't overflow for a couple of million yearsend; begin  writeln(GetTickCount);end.     I have some error and warning on compiling project1.lpr(10,20) Warning: Local variable "tv" does not seem to be initialized project1.lpr(11,16) Error: Illegal qualifier project1.lpr(11,16) Hint: may be pointer dereference is missing project1.lpr(11,15) Error: Incompatible types: got "ptimeval" expected "QWord" project1.lpr(11,16) Fatal: Syntax error, ";" expected but "identifier TV_SEC" found googling "free pascal  fpgettimeofday" ALL examples / code are passing to the fpgettimeofday function the PTimeZone = nil Note i'm using lazarus version installed on a Raspberry Pi3 Have you any precious suggestion ? Thanks ---------------------------------------------------------------------- enko · 2017-08-19 10:44 Also Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i uses sysutils;beginwriteln(GetTickCount64);end.  On compiling I have Error: Identifier not found "GetTickCount64" ---------------------------------------------------------------------- Thaddy · 2017-08-19 11:12 Quote from: enko on August 19, 2017, 12:44:18 pmAlso Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i uses sysutils;beginwriteln(GetTickCount64);end.  On compiling I have Error: Identifier not found "GetTickCount64" That's very very strange because I wrote the example (and this reply!) from a Raspberry Pi 3. Are you sure you are not using an old version? Did you upgrade to Stretch already? (That has FPC 3.0.0).. That should not be necessary, but at least 3 is still a supported version: Code: [Select]pi@raspberrypi:~/fpcdemos $ fpc -CX -XXs counter.pas Free Pascal Compiler version 3.1.1-r36940 [2017/08/18] for arm Copyright (c) 1993-2017 by Florian Klaempfl and others Target OS: Linux for ARMHF Compiling counter.pas Linking counter 7 lines compiled, 0.9 sec pi@raspberrypi:~/fpcdemos $ ./counter 20724027 Anyway, your homebrew gettickkount is wrong, I am not going to debug that any further. The standard implementation in sysutils looks like this: Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i function GetTickCount64: QWord;var  tp: TTimeVal;  {$IFDEF HAVECLOCKGETTIME}  ts: TTimeSpec;  {$ENDIF}  begin {$IFDEF HAVECLOCKGETTIME}   if clock_gettime(CLOCK_MONOTONIC, @ts)=0 then     begin     Result := (Int64(ts.tv_sec) * 1000) + (ts.tv_nsec div 1000000);     exit;     end; {$ENDIF}  fpgettimeofday(@tp, nil);  Result := (Int64(tp.tv_sec) * 1000) + (tp.tv_usec div 1000);  // look here!end; Since RPi does have HAVECLOCKGETTIME that is the version that gets executed. ---------------------------------------------------------------------- enko · 2017-08-19 11:35 It seems I have an old version ... pi@raspberrypi:~ $ fpc Free Pascal Compiler version 2.6.4+dfsg-4+rpi1 [2014/10/21] for arm ---------------------------------------------------------------------- Eugene Loza · 2017-08-19 11:48 You may do it this way (don't mix records with pointers to records): Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i function GetTickCount: Int64;var  tv: TTimeval;begin  FpGettimeofday(@tv, nil);  Result := Int64(tv.tv_sec) * 1000000 + Int64(tv.tv_usec);end; or Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i function GetTickCount: Int64;var  tv: PTimeval;begin  FpGettimeofday(tv, nil);  Result := Int64(tv^.tv_sec) * 1000000 + Int64(tv^.tv_usec);end; Similar code works fine for me. ---------------------------------------------------------------------- enko · 2017-08-19 12:08 Thaddy can you tell me what I must to do to upgrade FPC e Lazarus IDE to lastest release for RaspBerry ?? Thanks a lot for your patience. ---------------------------------------------------------------------- Thaddy · 2017-08-19 14:03 See Raspberry.org The new Raspbian Stretch comes with fpc 3.0.0 and Lazarus 1.6.2 From fpc 3.0 it is easy to build a new Lazarus from source and also a new FPC 3.0.4. So first advice is to update to latest RaspBian stretch. Then sudo apt-get purge fpc && apt-get  autoremove && sudo apt-get install fpc ---------------------------------------------------------------------- Thaddy · 2017-08-19 14:09 Quote from: Eugene Loza on August 19, 2017, 01:48:31 pmYou may do it this way (don't mix records with pointers to records): Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i function GetTickCount: Int64;var  tv: TTimeval;begin  FpGettimeofday(@tv, nil);  Result := Int64(tv.tv_sec) * 1000000 + Int64(tv.tv_usec);end; or Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i function GetTickCount: Int64;var  tv: PTimeval;begin  FpGettimeofday(tv, nil);  Result := Int64(tv^.tv_sec) * 1000000 + Int64(tv^.tv_usec);end; Similar code works fine for me. Both are wrong. I already gave the correct calculation from the official sources (sysutils). Yours are prone to range checks and overflow.! You should use the version from sysutils. Code: [Select]// for if there is no CLOCK*   fpgettimeofday(@tp, nil);   Result := (Int64(tp.tv_sec) * 1000) + (tp.tv_usec div 1000);  // look here!