Jeg skriver en timerfunksjon som bruker micros () -funksjonen som genererer en usignert lang verdi. For å kompensere for en roll-over-tilstand, vil jeg bruke maksimumsverdien for den variabeltypen. Jeg har et tall, 4 294 967 295, men forventet at det skulle være et konstant et sted.
Er det en MAX_UNSIGNED_LONG konstant i Arduino kompilatorfilene et sted?
Jeg har prøvd det navnet og vet at det sannsynligvis ikke er det. Fortsatt pokker.
Svar
Ulike limits.h
filer i avr-gcc
hierarkiet definerer ULONG_MAX
, som kan være verdien For eksempel, på mitt system har slike filer stier som slutter 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
og inneholder definisjoner som følgende.
/* Maximum value an `unsigned long int" can hold. (Minimum is 0). */ #undef ULONG_MAX #define ULONG_MAX (LONG_MAX * 2UL + 1UL)
Merk, LONG_MAX
er også definert i limits.h
.
Merk, aritmetikk utført i en form som
timeDelta = micros() - prevTime;
vil være riktig (uansett om micros()
overfylt) i forløpte tider opptil 2³² mikrosekunder, eller omtrent 4295 sekunder.
Svar
Du trenger ikke «å kompensere for en roll-over-tilstand «.
Se svaret mitt: https://arduino.stackexchange.com/a/33577/10794
i en Arduino-kompilator?
«Arduino» -kompilatoren er en C ++ – kompilator. Det er utgangspunktet for de fleste spørsmål. Hvis du Google for:
maximum unsigned long in c++
Du vil finne at den første lenken fører til:
http://www.cplusplus.com/reference/climits/
I det står det:
ULONG_MAX Maximum value for an object of type unsigned long int
Svar
Forsøkte du å gjøre dette ?:
unsigned long maxUnsignedLong = 0UL - 1UL;
eller:
const unsigned long ULONG_MAX = 0UL - 1UL;
Svar
Fra nettverk, synes jeg, det er ikke så lett å finn det riktige svaret på maksimumsverdien til micros () på mine egne arduino-kort også.
I mitt tilfelle , ser ut til at mikro () ruller rundt hvert 17. sekund. Til slutt skrev jeg oppsettet () for meg selv for å fange 0x1111111 som maksimumsverdien for mikro () som følger.
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
- avgrens kommentaren til " int n, nMin = 0, nMax = 0; "
- Nei, dette er helt feil . Se arduino.cc/en/Reference/Micros der en overføringstid på omtrent 70 minutter er gitt, som samsvarer med maksimumet av en usignert lang i mikrosekunder, konvertert til minutter (faktisk 71 og et halvt minutt)
- Vel, jeg ' har sett overføringstiden på omtrent 70 minutter. Men jeg vet virkelig ikke ' hvorfor, på wifi-gutten min esp32-tavle, ruller micros () -samtalen rundt hvert 17. sekund. Kunne du forestille deg det?
- Denne typen " fanger den i handlingen " eksperimentet er feil til å begynne med , men blir så blandet videre i AVR vs ESP-forskjeller – for eksempel ville denne koden ikke ' ikke engang være gyldig på en AVR, der% d ville feiltolke en usignert lang – det kan " nesten " fungerer på en ESP32, men vil fortsatt blande sign-biten. Du bør virkelig lese dokumentasjonen, eller kildekoden til kjernen.
- Jeg fant ut at wifiboy esp32 faktisk kjører på 240 MHz. Så den maksimale usignerte lange verdien av makroer () 0xffffffff / 240 er 0x1111111. Dette er akkurat hva jeg fikk. Tusen takk!