millis negativo?!

ciao a tutti,

ho fatto uno sketch che, all’input di un elemento (per adesso sto facendo le prove con un pulsante) riceve la variabile millis(); e la raccoglie in un array. in questo array (lungo 10, così da poter calcolare la frequenza dell’input su un periodo di tempo piuttosto esteso, ordino gli elementi a partire dall’ultimo arrivato, e trascrivo tutti gli altri (first in, last out) spostandoli di uno step a destra.
Tutto ok fino a che non arrivo al secondo 32, dove i valori passano da positivi a negativi(!) per poi ricominciare a salire.

di seguito posto il risultato da serial monitor, più l’estratto di codice che mi dà problemi.

grazie a tutti,

Luca


#define LED 13
#define SENSOR 9

int inputVal;//valore di input del sensore;
int recordBuffer[] = {};//calcolo la media degli ultimi secondi;
int bufferLen = 1;
int pulses = 0;//incrementale;
boolean pressed = false;//verifico lo stato del pulsante al giro precedente;

void setup() {
  pinMode(LED, OUTPUT);
  pinMode(SENSOR, INPUT);
  Serial.begin(9600);
}

void loop() {
  
  inputVal = digitalRead(SENSOR);
  if (inputVal == LOW) {
    digitalWrite(LED, HIGH);
    if (!pressed) {
      updatePulses(millis());
      pressed = true;
    }
   
  } else {
    digitalWrite(LED, LOW);
    if (pressed) {
      pressed = false;
    }
  }
  delay(10);
}

void updatePulses(unsigned long inputTime) {
  pulses++;
  
  /*
  Serial.print(pulses);
  Serial.print(" - ");
  Serial.print(inputTime);
  Serial.print(" - ");
  Serial.println(bufferLen);
  */
  
  for (int i = bufferLen - 1; i > 0; i--) { recordBuffer[i] = recordBuffer[i - 1]; }
  recordBuffer[0] = inputTime;
  for (int i = 0; i < bufferLen; i++) { Serial.print(recordBuffer[i]); Serial.print(" - "); } Serial.println("//");
  if (bufferLen < 10) { bufferLen++; }
}

(questo è l’output del serial monitor)

5185 - //

8283 - 5186 - //

9225 - 8284 - 5120 - //

9810 - 9226 - 8192 - 5120 - //

10613 - 9811 - 9216 - 8192 - 5120 - //

11039 - 10614 - 9728 - 9216 - 8192 - 5120 - //

11494 - 11040 - 10496 - 9728 - 9216 - 8192 - 5120 - //

14926 - 11495 - 11008 - 10496 - 9728 - 9216 - 8192 - 5120 - //

15476 - 14927 - 11264 - 11008 - 10496 - 9728 - 9216 - 8192 - 5120 - //

15945 - 15477 - 14848 - 11264 - 11008 - 10496 - 9728 - 9216 - 8192 - 5120 - //

16621 - 15946 - 15360 - 14848 - 11264 - 11008 - 10496 - 9728 - 9216 - 8192 - //

17232 - 16622 - 15872 - 15360 - 14848 - 11264 - 11008 - 10496 - 9728 - 9216 - //

17689 - 17233 - 16384 - 15872 - 15360 - 14848 - 11264 - 11008 - 10496 - 9728 - //

18446 - 17690 - 17152 - 16384 - 15872 - 15360 - 14848 - 11264 - 11008 - 10496 - //

21354 - 18447 - 17664 - 17152 - 16384 - 15872 - 15360 - 14848 - 11264 - 11008 - //

22773 - 21355 - 18432 - 17664 - 17152 - 16384 - 15872 - 15360 - 14848 - 11264 - //

24391 - 22774 - 21248 - 18432 - 17664 - 17152 - 16384 - 15872 - 15360 - 14848 - //

24839 - 24392 - 22528 - 21248 - 18432 - 17664 - 17152 - 16384 - 15872 - 15360 - //

25376 - 24840 - 24320 - 22528 - 21248 - 18432 - 17664 - 17152 - 16384 - 15872 - //

26852 - 25377 - 24832 - 24320 - 22528 - 21248 - 18432 - 17664 - 17152 - 16384 - //

29794 - 26853 - 25344 - 24832 - 24320 - 22528 - 21248 - 18432 - 17664 - 17152 - //

30771 - 29795 - 26624 - 25344 - 24832 - 24320 - 22528 - 21248 - 18432 - 17664 - //

31418 - 30772 - 29696 - 26624 - 25344 - 24832 - 24320 - 22528 - 21248 - 18432 - //

32032 - 31419 - 30720 - 29696 - 26624 - 25344 - 24832 - 24320 - 22528 - 21248 - //

32570 - 32033 - 31232 - 30720 - 29696 - 26624 - 25344 - 24832 - 24320 - 22528 - //

-32429 - 32571 - 32000 - 31232 - 30720 - 29696 - 26624 - 25344 - 24832 - 24320 - //

-31262 - -32428 - 32512 - 32000 - 31232 - 30720 - 29696 - 26624 - 25344 - 24832 - //

-29510 - -31261 - -32512 - 32512 - 32000 - 31232 - 30720 - 29696 - 26624 - 25344 - //

-28947 - -29509 - -31488 - -32512 - 32512 - 32000 - 31232 - 30720 - 29696 - 26624 - //

-28461 - -28946 - -29696 - -31488 - -32512 - 32512 - 32000 - 31232 - 30720 - 29696 - //

-28007 - -28460 - -29184 - -29696 - -31488 - -32512 - 32512 - 32000 - 31232 - 30720 - //

-27575 - -28006 - -28672 - -29184 - -29696 - -31488 - -32512 - 32512 - 32000 - 31232 - //

frex, francamente non so da cosa dipendere ma.... ti posso dire, dato che il mio attuale progetto si basa TUTTO sulla funzione millis, stasera provo il tuo sketch sul mio arduino e vedrò che succede. Almeno sappiamo se è un problema hardware o di che tipo. Per il momento poco consolante ma.... proviamo.

scusa massimo forse scrivo una banalità ma non ho capito la pagina linkata: non è che supera il valore massimo dell'integer? e perciò riparte da da -32...?

ciao a tutti,

grazie Massimo per il link illuminante. Ci ho messo un po’, - il mio ingegnere di fiducia è particolarmente impegnato negli studi accademici, quindi devo cavarmela da solo :slight_smile: - ma credo di aver isolato il problema.

La soluzione, a dire il vero, è esattamente come ha sintetizzato garinus. La funzione millis() restituisce un valore predefinito del tipo unsigned long, che nella mia prima versione di codice veniva immagazzinato in un array di variabili int. Una volta raggiunto il valore massimo “intorno ai 32mila” → da reference, 32,767, la prima cifra in valore binario diventa 1, ottenendo così il risultato di -32,768.

Posto qui di seguito l’evoluzione del codice di ieri sera, corretto nella parte che non funzionava.
Adesso pare andare tutto bene. Ho notato che durante la copia alcuni dati vengono leggermente modificati, specialmente nel passaggio dal primo al secondo posto nell’array. Temo però che siano dovuti all’imprecisione del segnale in entrata (pulsante semplice).

Grazie ancora a tutti,
Luca

#define LED 13
#define SENSOR 9

int inputVal;//valore di input del sensore;
int pulses = 0;
unsigned long recordBuffer[] = {};//calcolo la media degli ultimi secondi;
int bufferLen = 1;//lunghezza dell'array variabile;
boolean pressed = false;//verifico lo stato del pulsante al giro precedente;

void setup() {
  pinMode(LED, OUTPUT);
  pinMode(SENSOR, INPUT);
  Serial.begin(9600);
}

void loop() {
  
  inputVal = digitalRead(SENSOR);
  if (inputVal == LOW) {
    digitalWrite(LED, HIGH);
    if (!pressed) {
      Serial.print("pressed! // ");
      updatePulses(millis());
      pressed = true;
    }
   
  } else {
    digitalWrite(LED, LOW);
    if (pressed) {
      Serial.println(" // released!");
      pressed = false;
    }
  }
  
  delay(10);
}

void updatePulses(unsigned long inputTime) {
  
  pulses++;
  for (int i = bufferLen - 1; i > 0; i--) { recordBuffer[i] = recordBuffer[i - 1]; }
  recordBuffer[0] = inputTime;
  for (int i = 0; i < bufferLen; i++) { Serial.print(recordBuffer[i]); Serial.print(" - "); } Serial.print("// pulses: "); Serial.print(pulses);
  if (bufferLen < 10) { bufferLen++; }
}