Sto scrivendo una funzione timer che utilizza la funzione micros () che genera un valore lungo senza segno. Per compensare una condizione di roll over, vorrei utilizzare il valore massimo per quel tipo di variabile. Ho un numero, 4.294.967.295, ma mi aspettavo che fosse una costante da qualche parte.
Cè una costante MAX_UNSIGNED_LONG nei file del compilatore Arduino da qualche parte?
Ho provato con quel nome e so che probabilmente non è quello. Sto ancora cercando di dare unocchiata.
Risposta
Vari limits.h
file nella avr-gcc
gerarchia definiscono ULONG_MAX
, che potrebbe essere il valore Ad esempio, sul mio sistema tali file hanno percorsi che terminano con hardware/tools/avr/lib/gcc/avr/4.8.1/include-fixed/limits.h
o con hardware/tools/avr/lib/gcc/avr/4.8.1/install-tools/include/limits.h
e contengono definizioni come le seguenti.
/* Maximum value an `unsigned long int" can hold. (Minimum is 0). */ #undef ULONG_MAX #define ULONG_MAX (LONG_MAX * 2UL + 1UL)
Nota, LONG_MAX
è definito anche in limits.h
.
Nota, laritmetica eseguita in una forma come
timeDelta = micros() - prevTime;
sarà corretta (indipendentemente dal fatto che micros()
overflow) per tempi trascorsi fino a 2³² microsecondi o circa 4295 secondi.
Risposta
Non “è necessario” compensare una condizione di rollover “.
Vedi la mia risposta: https://arduino.stackexchange.com/a/33577/10794
in un compilatore Arduino?
Il compilatore “Arduino” è un compilatore C ++. Questo è il punto di partenza per la maggior parte delle domande. Se utilizzi Google per:
maximum unsigned long in c++
Troverai il primo link che porta a:
http://www.cplusplus.com/reference/climits/
In quanto dice:
ULONG_MAX Maximum value for an object of type unsigned long int
Risposta
Hai provato a farlo ?:
unsigned long maxUnsignedLong = 0UL - 1UL;
o:
const unsigned long ULONG_MAX = 0UL - 1UL;
Risposta
Dalla rete, mi sembra, non è così facile trova la risposta giusta anche per il valore massimo di micros () delle mie schede arduino.
Nel mio caso , sembra che micros () rotoli circa ogni 17 secondi. Infine, ho scritto Setup () per me stesso per prendere 0x1111111 come valore massimo di micros () come segue.
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 ); }
Commenti
- perfeziona il commento di " int n, nMin = 0, nMax = 0; "
- No, è completamente sbagliato . Vedi arduino.cc/en/Reference/Micros , viene fornito un tempo di rollover di circa 70 minuti, che corrisponde al massimo di un lungo senza segno in microsecondi, convertito in minuti (in realtà 71 minuti e mezzo)
- Bene, ' ho visto il tempo di rollover di circa 70 minuti. Ma, davvero non ' so perché, sulla mia scheda esp32 wifi boy, la chiamata micros () si ripete ogni 17 secondi circa. Potresti immaginarlo?
- Questo tipo di " coglierlo in flagrante " è imperfetto allinizio , ma poi si confonde ulteriormente nelle differenze tra AVR e ESP – ad esempio, questo codice non ' potrebbe nemmeno essere valido su un AVR, dove% d interpreterebbe erroneamente un long senza segno – potrebbe " quasi " funziona su un ESP32, ma confonderebbe comunque il bit di segno. Dovresti davvero leggere la documentazione, o il codice sorgente del core.
- Ho scoperto che in realtà il mio wifiboy esp32 funziona a 240 Mhz. Quindi il valore lungo massimo senza segno delle macro () 0xffffffff / 240 è 0x1111111. Questo è esattamente quello che ho ottenuto. Grazie mille!