Problema con funzione millis()

Penso di avere un problema con la funzione millis().
Lo sketch che sto testando è il seguente:

  /*
   * 22 febbraio 2024
   * Arduino NANO
   */
   unsigned long previusMillis = 0;
   unsigned long currentMillis = 0;
   const long interval = 10000; // secondi motore attivo
   int SharpPin = A1; // pin A1 connesso a sensore Sharp
   int acquaPin = 2;  // pin D2 per sensore scorrimento acqua
   bool motorePin = 3;  // pin D3 del relè motore
   int valore = 0;  // variabile analogica sensore Sharp
   int erogazioni = 0;
   
  void setup() {
    // Initialize serial and wait for port to open:
    Serial.begin(9600);
    delay(1500); 
  
    pinMode(SharpPin, INPUT);
    pinMode(acquaPin, INPUT_PULLUP);
    pinMode(motorePin, OUTPUT);
    digitalWrite(motorePin, HIGH); // rele caduto
  }
  
  
  void loop() {
    
    currentMillis = millis();
    
    valore = analogRead(SharpPin);
 
    if(valore > 900){  
    Serial.print("Valore:");
    Serial.println(valore);  
      if(currentMillis - previusMillis > interval){
        previusMillis = currentMillis;
        digitalWrite(motorePin, LOW); // relè attivo 
        Serial.print(" Motore:");
        Serial.println(motorePin);
        
    if(digitalRead(acquaPin) == LOW){  
        erogazioni++; 
        Serial.print(" Erogazioni:");
        Serial.println(erogazioni); 
        }
      }
    }
    else{
      digitalWrite(motorePin, HIGH);  
     }
      //delay(1000);
  }

Se il valore letto dal sensore Sharp supera un certo valore(900), dovrebbe partire un motore e rimanere attivo per 10 secondi e poi spegnersi, ma non mi succede.
Sul monitor vedo alcuni parametri tra cui lo stato del relè che attiva il motore ma anche se entro nell'"if" del 900 sul monitor vedo sempre la variabile "motorePin = 1", non mi va LOW, a 0.
Ho il dubbio che ho impostato la funzione millis() in maniera errata ma non so come fare.
Ho forzato la variabile "acquaPin" a massa e vedo sul monitor che la variabile "erogazioni" non incrementa.
Non so più cosa fare.

EzioGi

Intanto:

Poi, la logica dovrebbe essere impostata come:

SE motore spento E lettura alta:
  carica tempo
  accendi motore

SE motore acceso E trascorso tot:
  spegni motore

Anche con le modifiche non funziona ancora.
Lo sketch aggiornato:

  /*
   * 22 febbraio 2024
   * Arduino NANO
   * old bootloader
   */
   unsigned long previusMillis = 0;
   unsigned long currentMillis = 0;
   const long intervallo = 5000; // secondi motore attivo
   int SharpPin = A1; // pin A1 connesso a sensore Sharp
   bool acquaPin = 2;  // pin D2 per sensore scorrimento acqua
   bool motorePin = 3;  // pin D3 del relè motore
   int valore = 0;  // variabile analogica sensore Sharp
   int erogazioni = 0;
   
  void setup() {
    // Initialize serial and wait for port to open:
    Serial.begin(9600);
    delay(1500); 
  
    pinMode(SharpPin, INPUT);
    pinMode(acquaPin, INPUT_PULLUP);
    pinMode(motorePin, OUTPUT);
    digitalWrite(motorePin, HIGH); // rele caduto
  }
  
  void loop() {
    currentMillis = millis();
    
    valore = analogRead(SharpPin);
    if((digitalRead(motorePin) == HIGH) && (valore >= 900)){  
    Serial.print(" valore:");
    Serial.println(valore);  
    
    if(currentMillis - previusMillis >= intervallo){     
        digitalWrite(motorePin, LOW); // relè attivo 
        Serial.print("motore in: ");
        Serial.println(motorePin);
        previusMillis = currentMillis;
       
    /*if(digitalRead(acquaPin) == LOW){  
        erogazioni++; 
        Serial.print(" Erogazioni:");
        Serial.println(erogazioni); 
        }*/
      }
    }
    else if((motorePin == LOW) && (currentMillis - previusMillis >= intervallo)){
      digitalWrite(motorePin, HIGH);  
       Serial.print(" Motore out:");
       Serial.println(motorePin);
     }
      delay(1000);
  }

EzioGi

ATTENTO: i bool sono per valori solo true/false (te lo ha già scritto prima Claudio)

const unsigned long intervallo = 5000;
const byte SharpPin = A1;
const byte acquaPin = 2;        // pin D2 per sensore scorrimento acqua
const byte motorePin = 3;       // HIGH=spento,LOW=acceso

La variabile motorePin che cos'è???
E che valore ha? (guarda dove l'hai definita)

Non manca qualcosa in questo if secondo te?

Tre errori di partenza:

  1. Una variabile bool può contenere solo 0 o 1, non 3 o altri valori.
  2. Confusione tra il numero di un pin (eventualmente indicato con una variabile o una costante), e il valore letto o scritto su un pin tramite digital Read o Write.
  3. Disordine nelle parentesi aperte e chiuse con mancato incolonnamento e rientri (indentazione) errati. Questo rende difficilissimo capire cosa fa il programma, e ancora più difficile trovare gli errori. L'IDE permette di formattare il codice a dovere semplicemente con CTRL +T

Per quanto riguarda millis invece, il problema è il momento in cui salvi il tempo di sistema nella variabile previusMillis. Siccome il tempo trascorso è dato da:
currentMillis - previusMillis, e ci interessa il tempo trascorso dal momento di accensione del motore, allora previusMillis deve essere "caricata" con il tempo di sistema nell'esatto momento in cui il motore viene acceso. Infatti avevo scritto:

SE motore spento E lettura alta:
  carica tempo
  accendi motore

O rifatto lo sketch cercando di fare correttamente le modifiche che mi sono state suggerite.
Questo è lo sketch:

#include "arduino_secrets.h"
    /* 
      Sketch generated by the Arduino IoT Cloud Thing "Untitled"
      https://create.arduino.cc/cloud/things/472e2e5a-de8c-4845-ac77-ecbd7000c14b 
    
      Arduino IoT Cloud Variables description
    
      The following variables are automatically generated and updated when changes are made to the Thing
    
      int erogazioni;
    
      Variables which are marked as READ/WRITE in the Cloud Thing will also have functions
      which are called when their values are changed from the Dashboard.
      These functions are generated with the Thing and added at the end of this sketch.
    */
    
    #include "thingProperties.h"
    
    unsigned long precedenteMillis = 0;
    unsigned long correnteMillis = 0;
    const long intervallo = 5000;
    const int sharp = A1; // sensore
    const byte rele = 2;  // (D2) pin 5
    const byte led = 8; // (D8) pin 11 flusso
    const int acqua = 5; // (D5) pin 8
    int soglia =  900;  //  90 uguale a 10 cm
    int valore = 0;
    
     void Azzera(){
        erogazioni = 0; 
        }
      
    void setup() {
      // Initialize serial and wait for port to open:
      Serial.begin(9600);
      // This delay gives the chance to wait for a Serial Monitor without blocking if none is found
      delay(1500); 
    
      // Defined in thingProperties.h
      initProperties();
    
      // Connect to Arduino IoT Cloud
      ArduinoCloud.begin(ArduinoIoTPreferredConnection);
      
      setDebugMessageLevel(2);
      ArduinoCloud.printDebugInfo();
      
      /*==========     Azzera le erogazioni      =================*/
       //ArduinoCloud.addCallback(ArduinoIoTCloudEvent::SYNC, Azzera); 
       
      pinMode(sharp, INPUT);
      pinMode(acqua, INPUT_PULLUP);
      pinMode(rele, OUTPUT);
      digitalWrite(rele, HIGH); // relè caduto
      pinMode(led,OUTPUT);
      digitalWrite(led, HIGH); // led spento
    }
    
    void loop() {
      ArduinoCloud.update();
      correnteMillis = millis();
      
      valore = analogRead(sharp);
      Serial.println(valore);
      if((digitalRead(rele) == HIGH) && (valore >= soglia)){  
         if(correnteMillis - precedenteMillis > intervallo){     
            precedenteMillis = correnteMillis;
            digitalWrite(rele, LOW);  // relè attrato
        }
      }
      else{
        digitalWrite(rele, HIGH);  // relè caduto
        valore = 0;
      }
      delay(1);
    }
    
    
    /*
      Since Erogazioni is READ_WRITE variable, onErogazioniChange() is
      executed every time a new value is received from IoT Cloud.
    */
    void onErogazioniChange()  {
      digitalWrite(led, LOW);
    }

Al posto del Relè ho messo un led per vedere cosa succede, per vedere se rimane acceso per i 5 secondi della variabile"intervallo".
Mi succede che ogni 5 secondi ha un lampo, invece dovrebbe rimanere acceso per 5 secondi e poi spegnersi fino a quando la variabile "soglia" non supera il valore di 900.
Accetto sempre consigli.

EzioGi

Tu devi starci più attento
'Sta roba manco compila
Erogazioni non è globale

Se non ti metti a starci attento a quello che fai non ne esci mica

La logica che ho scritto io:

SE motore spento E lettura alta:
  carica tempo
  accendi motore

SE motore acceso E trascorso tot:
  spegni motore

La logica che hai scritto tu:

SE motore spento E lettura alta:
   SE trascorso tot:
      carica tempo
      accendi motore
ALTRIMENTI:
   spegni motore

Se tolgo la linea di commento a:

e lo compilo stando dentro al Arduino Cloud, me lo compila regolarmente e mi azzera regolarmente il dato ogni volta riparte lo sketch.

EzioGi

Grazie del consiglio, vedo di metterlo in pratica.

Ezio

Ho messo in pratica il tuo consiglio e adesso funziona.
Ho ancora molto da imparare.
Grazie

EzioGi

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