Visualizzazione su monitor seriale anomala [Risolto]

Buongiorno a tutti.

E' il mio primo post per cui chiedo da subito scusa per ogni eventuale errore che, se mi farete presente, cercherò di correggere per le occasioni future.
Premetto anche che non sono un esperto di Arduino ma mi sto divertendo a sperimentare.

Vengo al problema.
Utilizzo un Arduino UNO con il relativo IDE.
Ho iniziato a scrivere il codice con l'obiettivo di contare le volte che cambia stato un sensore (nel mio caso un sensore di prossimità).
Poi ho voluto visualizzare su monitor seriale questo dato.
E poi ancora volevo che non si visualizzasse in uno scrolling continuo ma solo una volta, nel momento di cambio di stato del sensore... e qui è sorto il problema.
Il codice che vi posto di seguito mi dà come risultato sul monitor seriale che quando pongo la mano davanti al sensore mi incrementa la variabile di conteggio ogni mezzo secondo circa (tranne i primi 2/3 cicli) e quando tolgo la mano si ferma.

//REV.1
const int pinSensore = 7; // pin a cui è collegato il sensore
const int pinLed = 12;    // pin a cui è collegato il led
int VCntgg;           // Pongo a zero la variabile di conteggio VCntgg che deve essere visualizzata nella seriale
int VCcl;             // Pongo a zero la variabile VCcl che conterà i cicli di loop per evitare l'incremento continuo di VCntgg

void setup()
{
  // inizializzazione del pin sensore, led e seriale
  pinMode(pinSensore, INPUT);
  pinMode(pinLed, OUTPUT);
  // attivazione del monitor seriale
  Serial.begin(9600);
}

void loop()
{
  // conservo nella variabile val lo stato del sensore
  int val = digitalRead(pinSensore);

  // il sensore legge la differenza di colore "nero/bianco"
  // verifica dello stato del sensore
  
  if (val == LOW)
  {
      digitalWrite(pinLed, HIGH);   // accende il led
      VCcl = ++VCcl;               // incrementa la variabile VCcl di 1 ad ogni loop finchè il sensore resta LOW
  }
      
  if (val == HIGH)
  {
    digitalWrite(pinLed, LOW);   // spegne il led
    VCcl = 0;                     // riporta a zero la variabile VCcl
  }

  if (VCcl == 1)                  // solo se è al primo ciclo di loop con led LOW
  {
      VCntgg = ++VCntgg;         // incrementa il conteggio
      Serial.print("Pezzi: ");   // stampa sulla seriale
      Serial.println(VCntgg);
      Serial.println(VCcl);
  }
}

Nel monitor ho fatto visualizzare anche la variabile VCcl che dovrebbe contare i loop eseguiti, ma questa resta sempre a 1. Ecco un esempio di cosa compare:

07:07:01.752 -> Pezzi: 21
07:07:01.752 -> 1
07:07:01.752 -> Pezzi: 22
07:07:01.798 -> 1
07:07:02.290 -> Pezzi: 23
07:07:02.290 -> 1
07:07:02.791 -> Pezzi: 24
07:07:02.791 -> 1
07:07:03.292 -> Pezzi: 25
07:07:03.345 -> 1
07:07:03.845 -> Pezzi: 26
07:07:03.845 -> 1

Se però al codice aggiungo una linea di visualizzazione sul monitor seriale al di fuori di un istruzione IF, ad esempio “Serial.println(VCntgg);” allora esegue i conteggi correttamente e mi visualizza i dati richiesti quando pongo la mano davanti al sensore, ma c’è uno scrolling continuo dell’istruzione aggiunta.

Qualcuno sa spiegarmene il motivo o dove sto sbagliando?

Grazie fin da subito.

Intanto, al posto di VCcl = ++VCcl; metti solo VCcl++; ed al posto di VCntgg = ++VCntgg; metti solo VCntgg++; che è più pulito e più corretto.

Considera poi che il loop() gira mooooolto veloce ed un int, come hai dichiarato tu VCcl e VCntgg arriva solo a 32767 ... che, alla velocità a cui gira il luoop, è un'attimo se 'val' rimane LOW per un po' di tempo ... dopo di che, riparte da zero va in overflow e riparte da -32768 a decrescere verso lo zero per poi ripetere il ciclo.

Piuttosto io farei un controllo del tipo ... se 'val' prima era HIGH ed ora è diventato LOW, allora incremeta VCcl ed aspetta che 'val' torni ad HIGH prima di conteggiare di nuovo ... in questo modo il conteggio è indipendente dal tempo che 'val' sta LOW :wink:

Guglielmo

Innanzitutto grazie per la rapida risposta.

Intanto, al posto di VCcl = ++VCcl; metti solo VCcl++; ed al posto di VCntgg = ++VCntgg; metti solo VCntgg++; che è più pulito e più corretto.

Chiaro. Consiglio che seguirò.

Considera poi che il loop() gira mooooolto veloce ed un int, come hai dichiarato tu VCcl e VCntgg arriva solo a 32767 ... che, alla velocità a cui gira il luoop, è un'attimo se 'val' rimane LOW per un po' di tempo ... dopo di che, riparte da zero.

Si, avevo considerato questa ipotesi ma credevo di essere in errore ... Molto bene saperlo.
Chiedo: riparte da zero o da -32768 come ho letto da qualche parte?

Piuttosto io farei un controllo del tipo ... se 'val' prima era HIGH ed ora è diventato LOW, allora incremeta VCcl ed aspetta che 'val' torni ad HIGH prima di conteggiare di nuovo ... in questo modo il conteggio è indipendente dal tempo che 'val' sta LOW

Anche a questo ci avevo pensato ma volevo prima capire cosa mi sfuggiva. Però sono contento che del tuo suggerimento perché vuol dire che dopotutto sto percorrendo la strada giusta. Appena ho un po' di tempo provo.

Grazie!

Mario

bubino:
... Chiedo: riparte da zero o da -32768 come ho letto da qualche parte?

Si, si, scusa, corretto quanto hai letto, va in overflow e quindi diventa -32768 a salire fino ad arrivare a 0, dopo di che il ciclo ricomincia :slight_smile:

01111111 11111111 + 00000000 00000001 = 10000000 0000000 che è appunto pari a -32768

Correggo anche il mio post che è fuorviante :wink:

Guglielmo

This topic was automatically closed 120 days after the last reply. New replies are no longer allowed.