Aiuto per sistemare una parte di codice

Buona sera a tutti, ho scritto un codice nel quale effettuo alcuni controlli, tra cui controllo se un pulsante viene premuto, e in caso affermativo porto in HIGH un pin.
La parte di codice che effettua il controllo è la seguente:

val = digitalRead(BUTTON);  // legge il valore dell'input e lo conserva  
  // SEZIONE PULSANTE
  // compare the buttonState to its previous state
  if (val != lastButtonState) {
    // if the state has changed, increment the counter
    if (val == LOW) {
      // if the current state is HIGH then the button
      // wend from off to on:
      buttonPushCounter++;
      Serial.println("on");
      Serial.print("numero di volte premuto:  ");
      Serial.println(buttonPushCounter);
      // DOPPIO COTROLLO
      if (value > 0) {  
      digitalWrite(ON, LOW); // relè collegato alla pompa
  }
      
  } 
    else {
      // if the current state is LOW then the button
      // wend from on to off:
      Serial.println("off"); 
      digitalWrite(ON, HIGH);
    }
  }
  // save the current state as the last state, 
  //for next time through the loop
  lastButtonState = val;
delay(500); // tempo di aggiornamento

Il problema è: Non so per quale motivo, ogni TOT secondi il relè viene accitato in automatico per qualche secondo...
Sapreste spiegarmi il motivo? :smiley:

Ivan_Isk:
Sapreste spiegarmi il motivo? :smiley:

Non so perché tutti non sanno la causa di un errore, ma sanno benissimo che é dentro in una piccola parte dello sketch che allegano.

No, non so spiegarti il motivo perché non conosco tutto il Sketch e perché non conosco il circuito.

Potrebbe essere un errore di programmazione un errore sul circuito una resistenza Pullup che manca, qualche disturbo ecc ecc ecc

Ciao Uwe

Grazie per aver risposto, nessun problema, ecco lo sketch completo:

/*
2013-11-29 -- finalmente i primi risultati
2014-02-10 -- dopo avere brucito tutto, mi sono arrivati i componenti di cui necessito
Applicazione realizzata da Ivan Scordato
Contatti: ivanwebmaster@rocketmail.com
*/
#include <SoftwareSerial.h> // includo la libreria per la comunicazione seriale
#include <EEPROM.h> // includo la libreria per effettuare le operazioni nella Eeprom

// l'indirizzo nell'Eeprom in cui sono memorizzate le erogazioni disponibili
int address = 3;
byte value;

// Variables will change:
int buttonPushCounter = 0;   // counter for the number of button presses
int val = 0;         // current state of the button
int lastButtonState = 0;     // previous state of the button

SoftwareSerial mySerial(10, 11); // imposto i pin per la comunicazione seriale
// Collegare i pin nel seguente modo: RX=>11 TX=>10

#define BUTTON 8 // pin di input dove è collegato il pulsante
#define ON 2 // relè collegato alla pompa
#define SI 3 // led verde, se ci sono erogazioni disponibili
#define NO 4 // led rosso, se non ci sono erogazioni disponibili
#define WORK 5

void setup()
{
  pinMode(ON, OUTPUT);
  pinMode(SI, OUTPUT);
  pinMode(NO, OUTPUT);
  pinMode(BUTTON, INPUT);     // imposta il pin digitale come input  
  digitalWrite(BUTTON, HIGH); // resistenza pull-down

   mySerial.begin(9600); // setto la comunicazione per i bluetooth
   mySerial.println("--- Ivan Scordato Creation --- ivanscordato@pinguweb.com");
   mySerial.print("\n");
   delay(1000);
}


void loop()
{
   while (mySerial.available())
   {
       char dato= mySerial.read(); // "dato" è il valore che viene ricevuto dalla seriale
       switch(dato)
       {
         // sezione di ricarica
         case 'r25': // Se voglio ricaricare 25 caffè,
         {
            // setto il valore 25
            int val = 26;
            // leggo valore precedente
            int value = EEPROM.read(address);
            // aggiungo il valore 25 a quello precedente
            EEPROM.write(address, val+value);
            // lampeggio led WORK
               digitalWrite(WORK, HIGH);   // turn the LED on (HIGH is the voltage level)
              delay(2000);               // wait for a second
              digitalWrite(WORK, LOW);    // turn the LED off by making the voltage LOW
          
           // stampo sulla porta seriale che l'operazione è avvenuta correttamente
            mySerial.print("OK... RICARICA DI 25 EFFETTUATA");
            mySerial.print("\n");
            mySerial.print(val+value, DEC);
           break;
         }
         
         case 'r50': // Se voglio ricaricare 50 caffè,
         {
            // setto il valore 50
            int val = 50;
            // leggo valore precedente
            int value = EEPROM.read(address);
            // aggiungo il valore 50 a quello precedente
            EEPROM.write(address, val+value);
            // lampeggio led WORK
               digitalWrite(WORK, HIGH);   // turn the LED on (HIGH is the voltage level)
              delay(2000);               // wait for a second
              digitalWrite(WORK, LOW);    // turn the LED off by making the voltage LOW
          
           // stampo sulla porta seriale che l'operazione è avvenuta correttamente
            mySerial.print("OK... RICARICA DI 50 EFFETTUATA");
            mySerial.print("\n");
            mySerial.print(val+value, DEC);
           break;
         }
         // fine sezione di ricarica
         
         // inizio sezione di reset
         case 'reset': // Se voglio azzerare i caffè,
         {
            // leggo valore precedente
            int value = EEPROM.read(address);
            // azzero le erogazioni disponibili
            EEPROM.write(address, value-value);
            // lampeggio led WORK
               digitalWrite(WORK, HIGH);   // turn the LED on (HIGH is the voltage level)
              delay(2000);               // wait for a second
              digitalWrite(WORK, LOW);    // turn the LED off by making the voltage LOW
          
           // stampo sulla porta seriale che l'operazione è avvenuta correttamente
            mySerial.print("OK... RESET EFFETTUATO");
            mySerial.print("\n");
           break;
         }
         // fine sezione di reset
         // inizio sezione di test
         case 'test1': // Se voglio testare un caffè,
         {
            // faccio un caffè
               digitalWrite(ON, HIGH);   // eccito il relè
              delay(4000);               // per 4 secondi
              digitalWrite(WORK, LOW);    // turn the LED off by making the voltage LOW
          
           // stampo sulla porta seriale che l'operazione è avvenuta correttamente
            mySerial.print("OK... RESET EFFETTUATO");
            mySerial.print("\n");
           break;
         }
         // fine sezione di test
// fine controlli

       } // fine switch      
   } // close while 
   
   int value = EEPROM.read(address);
                           mySerial.print("Erogazioni ancora disponibili: ");                           
                           mySerial.print(value-1, DEC);
                           mySerial.print("\n");
                           mySerial.print("");
               
   if((value > 1)){ // se ci sono caffè disponibili
       // digitalWrite(ON, LOW); // relè collegato alla pompa
       digitalWrite(SI, HIGH); // Accendo il led verde
       digitalWrite(NO, LOW); // Accendo il led rosso
   }
      if((value < 1)){ // se non ci sono caffè disponibili
       digitalWrite(ON, HIGH); // relè collegato alla pompa
       digitalWrite(NO, HIGH); // Accendo il led rosso
       digitalWrite(SI, LOW); // Accendo il led verde
   }
   
   val = digitalRead(BUTTON);  // legge il valore dell'input e lo conserva  
  // SEZIONE PULSANTE
  // compare the buttonState to its previous state
  if (val != lastButtonState) {
    // if the state has changed, increment the counter
    if (val == LOW) {
      // if the current state is HIGH then the button
      // wend from off to on:
      buttonPushCounter++;
      Serial.println("on");
      Serial.print("number of button pushes:  ");
      Serial.println(buttonPushCounter);
      // DOPPIO COTROLLO
      if (value > 0) {  
      digitalWrite(ON, LOW); // relè collegato alla pompa
    int value = EEPROM.read(address);
            // elimino una erogazione
            EEPROM.write(address, value-1);        
  }
      
  } 
    else {
      // if the current state is LOW then the button
      // wend from on to off:
      Serial.println("off"); 
      digitalWrite(ON, HIGH);
    }
  }
  // save the current state as the last state, 
  //for next time through the loop
  lastButtonState = val;
delay(500); // tempo di aggiornamento
}

La resistenza di pull-up non serve.
Il circuito è abbastanza semplice...
Un pulsante collegato a GND e Digital pin 2, relay (ma anche un led) collegato al Digital pin 3

Il problema credo che sia nella sezione del pulsante solo perchè il controllo viene effettuato su esso..
Qualche idea? :~
Grazie,
Ivan

char dato= mySerial.read();    // "dato" è il valore che viene ricevuto dalla seriale
       switch(dato)
       {
         // sezione di ricarica
         case 'r25': // Se voglio ricaricare 25 caffè,
         {
....

La variabile dato puó assumere numeri da 0 a 255 ma non una stringa percui 'r25' non verrá mai trovato ne un alto case di quel switch.

La pompa dell acqua funziona quando ON é HIGH o quando é LOW?

case 'test1': // Se voglio testare un caffè,
         {
            // faccio un caffè
               digitalWrite(ON, HIGH);   // eccito il relè

in questo case manca lo spegnimento del pin che pilota il relé.

if((value < 1)){ // se non ci sono caffè disponibili
       digitalWrite(ON, HIGH); // relè collegato alla pompa

Ti manca il debounce del pulsante. Aggiungi un delay(10); dopo
val = digitalRead(BUTTON);

Io sketch attiva la pompa finche il pulsante é premuto. Non sarebbe meglio spegnere la pompa dopo x secondi?

Non ho trovato niente che spiega il problema della pompa che parte da sola.

Che pulsante stai usando; come hai cablato tutto? ci sono per caso fili che si toccano?
Come piloti il relé? con un transistore? I LED hanno delle resistenze?

Ciao Uwe

uwefed:

char dato= mySerial.read();    // "dato" è il valore che viene ricevuto dalla seriale

switch(dato)
       {
         // sezione di ricarica
         case 'r25': // Se voglio ricaricare 25 caffè,
         {
....



La variabile dato puó assumere numeri da 0 a 255 ma non una stringa percui 'r25' non verrá mai trovato ne un alto case di quel switch.

La pompa dell acqua funziona quando ON é HIGH o quando é LOW?


case 'test1': // Se voglio testare un caffè,
         {
            // faccio un caffè
               digitalWrite(ON, HIGH);   // eccito il relè



in questo case manca lo spegnimento del pin che pilota il relé.



if((value < 1)){ // se non ci sono caffè disponibili
       digitalWrite(ON, HIGH); // relè collegato alla pompa




Ti manca il debounce del pulsante. Aggiungi un delay(10); dopo 
val = digitalRead(BUTTON); 

Io sketch attiva la pompa finche il pulsante é premuto. Non sarebbe meglio spegnere la pompa dopo x secondi?

Non ho trovato niente che spiega il problema della pompa che parte da sola. 

Che pulsante stai usando; come hai cablato tutto? ci sono per caso fili che si toccano?
Come piloti il relé? con un transistore? I LED hanno delle resistenze?

Ciao Uwe

Ciao, il pulsante è meccanico, perciò non posso spegnare la pompa dopo x secondi ma devo per forza sapere quando cambia lo stato...
La verità è che neanche io riesco a capire il motivo per cui risulta esserci quaesto problema...
Ecco in allegato il circuito che ho utilizzato

Ivan_Isk:
... char dato= mySerial.read(); // "dato" è il valore che viene ricevuto dalla seriale
switch(dato)
{
// sezione di ricarica
case 'r25': // Se voglio ricaricare 25 caffè,
...
case 'r50': // Se voglio ricaricare 50 caffè,

Qualche idea? :~
Grazie, Ivan

Idea? Una, studiati il C :grin:
A parte gli scherzi, cosa conosci il Basic? Stai ragionando come un linguaggio che ha le stringhe.
E' tutto errato, il C non ha le stringhe.

  1. la mySerial.read() ti legge UN solo carattere di quelli inviati.
  2. se metti una frase tra apostrofi singoli il C accetta ma in realtà è solo valido il primo carattere
    'r50' per il C è solo 'r'
  3. per una frase costante intesa come sequenza di caratteri devi usare i doppi apici "r50"
  4. lo switch accetta il confronto solo fra cifre numeriche, non su stringhe.
  5. in C NON puoi confrontare una stringa (intesa come vettore/array di caratteri) direttamente, devi usare una funzione di confronto tipo strcmp(s1,s2)

Per Arduino esiste la classe String che è un oggetto che incapsula un array di caratteri, ma è pesante per Arduino e molte volte porta ad esaurire la poca memoria. Utilizza le stringhe del C ovvero array/vettore di caratteri terminato da carattere 0 o null '\0'