Jag skriver en timerfunktion som använder funktionen micros () som genererar ett osignerat långt värde. För att kompensera för ett överrullningsvillkor vill jag använda det maximala värdet för den variabla typen. Jag har ett nummer, 4 294 967 295, men förväntade mig att det skulle vara en konstant någonstans.
Finns det en MAX_UNSIGNED_LONG-konstant i Arduino-kompilatorerna någonstans?
Jag har provat det namnet och vet att det förmodligen inte är det. Fortfarande kikar runt.
Svar
Olika limits.h
filer i avr-gcc
hierarkin definierar ULONG_MAX
, vilket kan vara värdet till exempel, på mitt system har sådana filer sökvägar som slutar med hardware/tools/avr/lib/gcc/avr/4.8.1/include-fixed/limits.h
eller med hardware/tools/avr/lib/gcc/avr/4.8.1/install-tools/include/limits.h
och innehåller definitioner som följande.
/* Maximum value an `unsigned long int" can hold. (Minimum is 0). */ #undef ULONG_MAX #define ULONG_MAX (LONG_MAX * 2UL + 1UL)
Obs! LONG_MAX
definieras också i limits.h
.
Obs, aritmetik gjort i en form som
timeDelta = micros() - prevTime;
kommer att vara korrekt (oavsett om micros()
överflödat) under förflutna tider upp till 2³² mikrosekunder, eller cirka 4295 sekunder.
Svar
Du behöver inte ” kompensera för ett överrullningsvillkor ”.
Se mitt svar: https://arduino.stackexchange.com/a/33577/10794
i en Arduino-kompilator?
”Arduino” -kompilatorn är en C ++ – kompilator. Det är utgångspunkten för de flesta frågor. Om du Google för:
maximum unsigned long in c++
hittar du den första länken leder till:
http://www.cplusplus.com/reference/climits/
Genom att det står:
ULONG_MAX Maximum value for an object of type unsigned long int
Svar
Försökte du göra detta ?:
unsigned long maxUnsignedLong = 0UL - 1UL;
eller:
const unsigned long ULONG_MAX = 0UL - 1UL;
Svar
Från nätverk verkar det inte så lätt att hitta rätt svar på det maximala värdet på mikro () på mina egna arduino-kort också.
I mitt fall , verkar som att mikros () rullar omkring var 17: e sekund. Slutligen skrev jag inställningen () för mig själv för att fånga 0x1111111 som det maximala värdet på mikro () enligt följande.
void setup () { Serial.begin( 115200 ); // set the baud rate for writing messages. int go = 1; // set the flag to continue do-while loop; int n, nMin = 0, nMax = 0; // see how many more the numbers of calling micros() to get different value; int d, dMin, dMax; // see the time interval of micros() having different values; unsigned long currT; // the time of current micros() calling unsigned long lastT = micros(); // the time of last micros() calling unsigned long T[200]; // keep tracking 200 different lastT values int it = 0; // use T[it%200] to keep each lastT (circular buffer) do { n = 0; while( (currT=micros()) == lastT ) n++; // get a different value T[ (it++) % 200 ] = currT; // save the value d = currT - lastT; // get the difference if ( d<0 ) { // if micros() rolls over go = 0; // stop this do-while loop Serial.println(); // print new line for ( int i=it-200, j=0; i<it; i++ ) { Serial.printf( "%9x", T[i%200] ); // the last 200 different lastT values if ( ++j%5==0 ) Serial.println(); // } Serial.printf("\nat %d ms lastT 0x%x currT 0x%x n=[%d..%d] d=[%d..%d]\n", millis(), lastT, currT, nMin, nMax, dMin,dMax); } if ( !nMin && !nMax ) nMin = nMax = n, dMin = dMax = d; if ( nMin>n ) { PRINTF( "\nat %d ms nMin %d > n %d ", millis(), nMin, n); nMin = n; } else if ( nMax<n ) { PRINTF( "\nat %d ms nMax %d < n %d", millis(), nMax, n ); nMax = n; } if ( dMin>d ) dMin = d; else if ( dMax<d ) dMax = d; lastT = currT; } while( go ); }
Kommentarer
- förfina kommentaren från " int n, nMin = 0, nMax = 0; "
- Nej, det här är helt fel . Se arduino.cc/en/Reference/Micros där en övergångstid på cirka 70 minuter ges, vilket matchar maximalt en osignerad lång i mikrosekunder, omvandlad till minuter (faktiskt 71 och en halv minut)
- Tja, jag ' har sett övergångstiden på cirka 70 minuter. Men jag vet verkligen inte ' varför, på mitt wifi-pojke esp32-kort rullar micros () -samtalet var 17: e sekund. Kan du avbilda den?
- Den här typen av " fånga den i lagen " experimentet är felaktig till att börja med , men blandas sedan vidare i AVR vs ESP-skillnader – till exempel skulle den här koden inte ' inte ens vara giltig på en AVR, där% d skulle tolka en osignerad lång fel – det kanske " nästan " arbetar på en ESP32, men skulle ändå blanda ihop sign-biten. Du borde verkligen läsa dokumentationen eller källans källkod.
- Jag upptäckte att min wifiboy esp32 faktiskt körs på 240 MHz. Så det maximala osignerade långa värdet på makron () 0xffffffff / 240 är 0x1111111. Det här är precis vad jag fick. Tack så mycket!