Problema: avvio sketch solo dopo pressione reset

Ciao a tutti, ho recentemente fatto un programma per gestire un timer che pilota un relè. Lo sketch in sè funziona correttamente in tutte le sue funzioni ma il problema è un altro: se scollego arduino e poi lo ricollego alla usb del computer o ad un'alimentazione esterna, lo sketch non parte e devo premere RESET per avviare il programma (che poi funziona tranquillamente). Elenco brevemente la configurazione: -arduino UNO r2 -display LCD -sei pushbuttons con resistenze pulldown da 10k -un buzzer pilotato da un transistor su un pin -un led simbolico al posto del relè che non ho ancora. Le connessioni sono tutte da tutorial tranne uno scambio d'assegnazione pin del display, perchè mi serviva l'interrupt del pin 2. Qualche idea?? Grazie a tutti :)

Dimenticavo lo sketch

/*


*/
#include <LiquidCrystal.h>
//pin di controllo pulsanti:
int set = 10;
int up = 9;
int dwn = 8;
int mem = 7;
int clr = 2;
int start = A1;
int buz = A0;
int rly =13;
//cifre del timer:
int timer[]={0,0,0,0,0};
int zero[]={0,0,0,0,0};
int m[]={5,5,0,5,5};
//parametri buzzer:(frequenza f, durata tbuz)
int f = 2000;
int tbuz =100;
int flag=0;
int tempo=0;
int tempoRes=0;

int debounce=300;
int soglia=10;

LiquidCrystal lcd(12, 11, 5, 4, 3, 6);//ATTENZIONE: riassegnando ad un altro pin il 5 dell'lcd non funziona correttamente


void setup(){
  pinMode(start, INPUT);
  pinMode(set, INPUT);
  pinMode(up, INPUT);
  pinMode(dwn, INPUT);
  pinMode(clr, INPUT);
  pinMode(mem, INPUT);
  pinMode(buz, OUTPUT);
  pinMode(rly, OUTPUT);
  lcd.begin(16, 2);

//messaggio di benvenuto
  lcd.setCursor(0,0);
  lcd.print("TIMER BROMOGRAFO");
  tone(buz,f,tbuz);
  delay(1000);
  
}
//§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§
void loop(){  
   setFunc();
///INIZIO ROUTINE DI ACCENSIONE E CONTEGGIO TIMER///
   boolean counter=1;
 while(counter==1){
   boolean START0=digitalRead(start);
   boolean CLR0=digitalRead(clr);   
   delay(50); //debounce
   boolean START1=digitalRead(start);
   boolean CLR1=digitalRead(clr);

   if(CLR0==LOW && CLR1==HIGH){
   counter=0;
   }
   if(START0==LOW && START1==HIGH){
       //conversione dati timer in minuti
           int M=(timer[0]*10)+(timer[1]);
           int S=(timer[3]*10)+(timer[4]);                         
           tempo=(M*60)+S; //tempo convertito in secondi       
         counterFunc(tempo);
         counter=0;
       }
   }
  
  


  
}//END LOOP
//§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§§

////////////////////////////////////////////////////////////////////////////////////////////////////
//1) funzione SET
void setFunc(){
   boolean setMode=1;//sei in modalità settaggio tempo manuale 
   int contatore=0;

   lcd.clear();
   lcd.setCursor(0,0);
   lcd.print("Set Timer");  
   
   printTimer(0,1,timer);
   int pos=4;
   lcd.setCursor(pos,1);
   lcd.blink();

   while (setMode==1){

   boolean CLR0=digitalRead(clr);   
   delay(50); //debounce
   boolean CLR1=digitalRead(clr);

     
      if(digitalRead(mem)==HIGH){
        int x=0;
        while(digitalRead(mem)==HIGH && x==0){
          delay(100);
          contatore=contatore+1;          
          if(contatore>=soglia){
          x=1;
          }
        }
        
        if(contatore<soglia){
        for(int i=0; i<=4; i++){
        timer[i]=m[i];
        }
        printTimer(0,1,timer);
        pos=4;
        lcd.setCursor(4,1);
        delay(debounce);
        }
        if(contatore>=soglia){
            for(int i=0; i<=4; i++){
            m[i]=timer[i];
            }
            memTimer();
            setFunc();
          
         
        }
        
      }


       if(CLR0==LOW && CLR1==HIGH){
        for(int i=0; i<=4; i++){
        timer[i]=0;//azzero timer
        }
        printTimer(0,1,timer);
        pos=4;
        lcd.setCursor(4,1);
        delay(debounce);
      }
      
      if(digitalRead(up)==HIGH){
        timer[pos]=timer[pos]+1;
        if(pos==0 && timer[pos]>5 || pos==3 && timer[pos]>5){
        timer[pos]=0;         
        }
        else if(timer[pos]>9){
        timer[pos]=0;
        }
        printTimer(0,1,timer);
        lcd.setCursor(pos,1);  
        delay(debounce);
      }
      
      if(digitalRead(dwn)==HIGH){
        timer[pos]=timer[pos]-1;
        if(pos==0 && timer[pos]<0 || pos==3 && timer[pos]<0){
        timer[pos]=5;         
        }
        else if(timer[pos]<0){
        timer[pos]=9;
        }
        printTimer(0,1,timer);
        lcd.setCursor(pos,1);        
        delay(debounce);
      }
      
      
      if(digitalRead(set)==HIGH){
        pos=pos-1;
        if(pos==2){
        pos=1;//serve per saltare i ":"
        }
        if (pos<0){
        pos=4;
        }
        lcd.setCursor(pos,1);
        delay(debounce);
      }

      if(digitalRead(start)==HIGH){
        int a=0;
        for(int i=4;i>=0; i--){
          a= timer[i]+a; //trucchetto che somma cifre timer, se è tutto zero restituisce a=0!!
        }
        if(a==0){//significa che il timer è azzerato
          errorTimer();
          setFunc();
        }
        else{
        lcd.noBlink();
        lcd.clear();
        printTimer(0,1,timer);
        lcd.setCursor(0,0);
        lcd.print(" Premere  Start ");
        setMode=0;//esce dal while        
        }
      }
   }
   
}
////////////////////////////////////////////////////////////////////////////////////////////////////
//5)FUNZIONE COUNTER
void counterFunc(int tmp){
           attachInterrupt(0,emergenceStop, RISING);//pin2 clr

           flag=0;//azzero per sicurezza
           tone(buz,f,tbuz);
           digitalWrite(rly,HIGH);//accendo relè
           lcd.clear();
           lcd.setCursor(0,0);
           lcd.print("accensione neon");
           delay(500);//attesa innesco dei tubi neon VERIFICA TEMPO
           lcd.noDisplay();
           delay(500);
           lcd.display();
           delay(500);
           lcd.clear();          
          
           printTimer(0,1,timer);
           for(int i=tmp;i>0;i--){
             convertTimer(i, 0, 1);
             delay(1000); 
              if(flag==1){
              tempoRes=i;
              i=0;
              }
           }
           detachInterrupt(0);
                         
           if(flag==0){
           printTimer(0,1,zero);
           digitalWrite(rly,LOW);//spengo relè 
           tone(buz,2000,100);
           delay(200);
           tone(buz,f,tbuz);
           delay(1000);
           }
           
           if(flag==1){//se ho attivato interrupt
           lcd.clear();
           lcd.setCursor(0,0);
           lcd.print("      STOP      ");
           //lcd.setCursor(0,1);  //test
           //lcd.print(tempoRes);
           convertTempres(tempoRes);
           delay(2000);//
           } 
}
////////////////////////////////////////////////////////////////////////////////////////////////////
//1)FUNZIONE STAMPA TIMER SU LCD///
//c=colonna, r=riga, t[]=array di 4 elementi contenenti il tempo
void printTimer(int c, int r, int t[5]){
   lcd.setCursor(c,r);
   lcd.print(t[0]);
   lcd.print(t[1]);
   lcd.print(":");
   lcd.print(t[3]);
   lcd.print(t[4]);
}
////////////////////////////////////////////////////////////////////////////////////////////////////
//3) Funzione errore se il tempo non è impostato
void errorTimer(){
  lcd.noBlink();
  lcd.clear();
  lcd.setCursor(0,0);
  lcd.print("   Set  Timer!   ");
  delay(300);
  lcd.noDisplay();
  delay(300);
  lcd.display();
  delay(300);
  lcd.noDisplay();
  delay(300);
  lcd.display();
  delay(600);
  lcd.clear();
}
////////////////////////////////////////////////////////////////////////////////////////////////////
void memTimer(){
  lcd.noBlink();
  lcd.clear();
  lcd.setCursor(0,0);
  lcd.print("     Stored!    ");
  delay(300);
  lcd.noDisplay();
  delay(300);
  lcd.display();
  delay(300);
  lcd.noDisplay();
  delay(300);
  lcd.display();
  delay(600);
  lcd.clear();
}

////////////////////////////////////////////////////////////////////////////////////////////////////
//INTERRUPT////////////////
//blocco conteggio e spegnimento lampada in caso di emergenza
void emergenceStop(){
  digitalWrite(rly, LOW);
  flag=1;
  tone(buz,f,300);

}

////////////////////////////////////////////////////////////////////////////////////////////////////
//2)FUNZIONE CONVERSIONE TEMPO DA SECONDI PER DISPLAY///
void convertTimer(int t, int c, int r){
  int M= t/60;
  int S= t-(M*60);
  lcd.setCursor(c,r);
  if(M<10){
  lcd.print("0");
  lcd.print(M);
   }
  else if(M>=10){
  lcd.print(M);   
   }
  
  lcd.print(":");
  
  if(S<10){
  lcd.print("0");
  lcd.print(S);
   }
  else if(S>=10){
  lcd.print(S);   
   }
}
///////////////////////////////////////////////////////
//2.1)//conversione timer da secondi a dati in array
void convertTempres(int t){
  int M= t/60;
  int S= t-(M*60);
    if(M<10){
      timer[0]=0;
      timer[1]=M;
    }
    else if(M>=10){
      timer[0]=M/10;
      timer[1]=M-(timer[0]*10);
       }
    if(S<10){
      timer[3]=0;
      timer[4]=S;
    }
    else if(S>=10){
      timer[3]=S/10;
      timer[4]=S-(timer[3]*10);
       }    
}

Stesso problema con arduino mega .. a me andava in timeout ...

1 soluzione : Risolto con il collegamento del trasformatore all'alimentazione

2 : soluzione stacca il pin 5 volt e prova a caricare

3 : ma non e detto che funzioni

premi il tasto reset e rilascialo solo quando il pro ti dice caricamento in corso ..

Cambiato alimentatore di rete con uno non switching e funziona!! Grazie 1000 empty_skull!

certo che i motivi del malfunzionamento mi restano oscuri...

Ho visto che la funzione setFunc è ricorsiva (chiama se stessa) Non è che viene chiamata troppo spesso e ti va tutto in crash?

PaoloP , non per offesa capisco che sono nuovo … ma fino ad ora ho letto e sono stato nell ombra …

se cercherai cose sul connection time out scoprirai che la risposta pin frequente e stacca la 5 volt … :slight_smile:

se fai verificare il codice e dice che ok … e un altro il problema …

empty_skull: se cercherai cose sul connection time out scoprirai che la risposta pin frequente e stacca la 5 volt .. :)

Sarà anche la più frequente però è sbagliata, parlando del classico errore di time out durante la programmazione, comunque il problema lamentato non ha nulla a che vedere con il trasferimento dello sketch visto che riesce a farlo e gli funziona.

Nessuna offesa. :wink:
Io stavo ipotizzando problemi relativi alla memoria satura, ma in effetti è anche possibile che si sottoalimentato.
Sul lato elettronico sono meno ferrato. :disappointed_relieved:

astrobeed .. letto male ragione tu , SCUSA =( PaoloP alla fine ho letto male .. quindi ne io ne te sappiamo la risposta pero dai funziona ora !!

Chiedo scusa a tutti mentre cercavo di capire cose ho risposto al volo e mi sono perso .. vedi che il mio nick name suona bene !!

PaoloP: Ho visto che la funzione setFunc è ricorsiva (chiama se stessa) Non è che viene chiamata troppo spesso e ti va tutto in crash?

in pratica è richiamata solo in particolari condizioni e viene eseguita volta per volta; comunque ripeto che lo sketch funziona per quello che intendevo fare. confesso che dev'essere abbastanza brutto da vedere ma sto ancora imparando :blush: ...tenete conto che arrivo da fortran..credo non sia da aggiungere altro :P :P

A questo punto il problema dev'essere proprio l'alimentazione esterna: facendo un paio di prove rapide con un trafo da 12V-2A connesso su jack dc va tutto a bomba, addirittura è visibilmente più veloce all'avvio, solo che dopo poco il regolatore di tensione dell'arduino scalda. Quindi ora mi sa che ci attacco a monte del jack un bel 7805 o 7809 con un paio di condensatori..che ne dite? il tutto sarà in futuro standalone con micro dedicato quindi vale la pena fare già il circuitino penso

arduric: Quindi ora mi sa che ci attacco a monte del jack un bel 7805 o 7809 con un paio di condensatori..che ne dite? il tutto sarà in futuro standalone con micro dedicato quindi vale la pena fare già il circuitino penso

Il 7805 NON va bene, la tensione di ingresso deve essere > 5v (... altrimenti sotto alimenti il regolatore on-board) ... il 7809 è ok ;)

Guglielmo

Ok, grazie! :) in effetti il 7805 avrebbe senso solo con lo standalone..ho scritto senza pensarci ^^

Sullo stand-alone invece andrà bene il 7805, almeno che non vuoi metterne 2 in cascata: 7809 --> 7805.