Ritorno a una funzione

gpb01:
>Damian10: il tasto "Report to Moderator" NON serve per porre domande agli utenti o rispondere a domande, serve per segnalare ai moderatori di TUTTO il forum (in tutto il mondo) un qualche cosa di serio (insulti, volgarità, spam, violazioni al regolamento, ecc.), quindi ... ti pregherei di usarlo solo per tali cose, grazie.

Guglielmo

Si scusami avevo premuto per sbaglio

Standardoil:
... e allora la strada di ripetere il setup è quasi sbagliata, quella di re-settare arduino è certamente sbagliata ...

... anzi, direi proprio che sono due cose che tassativamente NON si fanno e ... sono indice di "pessima" programmazione.

Il "reset" è pensabile in quei casi in cui, magari per un evento esterno imprevedibile, si è perso il controllo del programma (... es. una scarica elettrica che ha fatto impazzire la MCU) e, per queste cose, ci sono meccanismi appositamente studiati (watchdog), in tutti gli altri casi, si deve "strutturare" il programma per fare ciò che è necessario senza dover resettare o riavviare il codice.

Guglielmo

Standardoil:
No, scusa, io vedo due cose:
una certa impreparazione in 'C', nulla di grave: tutti impariamo/abbiamo imparato/impareremo
una certa confusione, e qui forse sbaglio io:
tu vuoi prorpio ri-accendere Arduino (magari per re-inizializzare delle periferiche)? mi sembra di no...
tu vuoi resettare arduino? magari per far ri-partire un programma impiantato? non credo
per quelle che mi sembra di capire tu vuoi che una certa sequenza riparta dall'inizio, senza però che questo sia causa/causato da guasti o malfunzionamenti
e allora la strada di ripetere il setup è quasi sbagliata, quella di re-settare arduino è certamente sbagliata
se sei in una condizione "normale", senza alcuna anomalia ne guasti re-settare o ri-accendere inutilmente è indice di cattiva programmazione, una situazione normale deve venire affrontata con mezzi "normali"
spiga bene cosa vuoi fare, mi raccomando: non "come", ma "cosa"

Vorrei utilizzare un pulsante a pressione (invece di staccare sempre l’alimentazione) per ricominciare dacapo magari dal punto s.tempo ma leggendo diversi commenti vedo che farlo partire da quel punto non si può fare..
quindi vorrei trovare un modo per ricominciare

... guarda che nel loop() basta leggere un pulsante, quando lo premi chiamare una funzione che fa TUTTO quello che vuoi fare e poi termina e si ritornana nel loop() dove viene sempre controllato il pulsante che, se ripremuto, richiama di nuovo la funzione e ... così via.

Guglielmo

gpb01:
... guarda che nel loop() basta leggere un pulsante, quando lo premi chiamare una funzione che fa TUTTO quello che vuoi fare e poi termina e si ritornana nel loop() dove viene sempre controllato il pulsante che, se ripremuto, richiama di nuovo la funzione e ... così via.

Guglielmo

Cosa consigli di fare allora
Creare un void mia funzione () e poi mettere la condizione se premo il pulsante ritorna void setup e richiamando mia funzione (); nella parte interessata
O consigli altro? Magari spiegandomi nel dettaglio

Damian10:
quindi come dovrei strutturarlo ...

void setup()
{ // settaggi, pinMode e altro
  MiaFunz();
}
void loop()
{ // tuo codice
  if( premuto un tasto)
  { MiaFunz();
  }
}
void MiaFunz()
{  // qui il pezzo di codice che vuoi chiamare sia la prima volta da setup() che da pressione tasto
}

MiaFunz() la richiamiamo sia in setup() sia quando devi ripeter quel pezzo di codice, esempio dopo pressione di un tasto

Damian10:
Cosa consigli di fare allora
Creare un void mia funzione () e poi mettere la condizione se premo il pulsante ritorna void setup e richiamando mia funzione (); nella parte interessata
O consigli altro? Magari spiegandomi nel dettaglio

quale parte di "cosa e non come" non ti è chiara?

nid69ita:

void setup()

{ // settaggi, pinMode e altro
  MiaFunz();
}
void loop()
{ // tuo codice
  if( premuto un tasto)
  { MiaFunz();
  }
}
void MiaFunz()
{  // qui il pezzo di codice che vuoi chiamare sia la prima volta da setup() che da pressione tasto
}




MiaFunz() la richiamiamo sia in setup() sia quando devi ripeter quel pezzo di codice, esempio dopo pressione di un tasto

Ok questo è quello che ho inserito nel setup
void setup (){
int hours, minutes, seconds;
lcd.begin(16, 2);
Serial.begin(9600);
tone1.begin(Buzzer);
pinMode(ledGreen, OUTPUT);
pinMode(ledRed, OUTPUT);
/////////////////////////
pinMode(pulsante, INPUT);
MiaFunzione();
/////////////////////////
char key;
boolean cancel;
do
{
cancel = false;
lcd.clear();
lcd.setCursor(0,0);
buttonBip(100);
lcd.print("Sistema attivo");
digitalWrite(ledGreen, HIGH);
delay(500);
digitalWrite(ledGreen, LOW);
lcd.setCursor (0,1);
lcd.print ("S.tempo.");

Void loop ();
Ovviamente tutto il mio codice più la seguente condizione

If (digitalRead(pulsante)== high);{
MiaFunzione ();}
In fine in
Void MiaFunzione () {

lcd.clear();
lcd.setCursor(0,0);
buttonBip(100);
lcd.print("Sistema attivo");
digitalWrite(ledGreen, HIGH);
delay(500);
digitalWrite(ledGreen, LOW);
lcd.setCursor (0,1);
lcd.print ("S.tempo.");

Dimentico qualcosa ?

>Damian10: ti ricordo che in conformità al regolamento, punto 7, devi editare il tuo post (quindi NON scrivendo un nuovo post, ma utilizzando il bottone More -> Modify che si trova in basso a destra del tuo post) e racchiudere il codice all'interno dei tag CODE (... sono quelli che in edit inserisce il bottone con icona fatta così: </>, tutto a sinistra) esattamente così come ha fatto nid69ita!

In pratica, tutto il tuo codice dovrà trovarsi racchiuso tra due tag: [code] _il _tuo_ codice_ [/code] così da non venire interpretato e non dare adito alla formazione di caratteri indesiderati o cattiva formattazione del testo. Grazie.

Guglielmo

Primo sistema il codice come richiesto.
Poi, hai inserito molti errori (il C vede la differenza tra maiuscole e minuscole void e non Void ad esempio; non puoi scrivere i comandi come ti pare), mancano graffe e poi ; a casaccio.
Inoltre siamo partiti male, dici che non serviva postare tutto il codice ed invece è NECESSARIO. Nel setup fai quel giro in un do{} e non sappiamo quando o come ne esci. E vuoi ripetere anche quel do ? Capisci che non è chiaro quel che vuoi fare, soprattutto se metti pezzi di codice.

nid69ita:
Primo sistema il codice come richiesto.
Poi, hai inserito molti errori (il C vede la differenza tra maiuscole e minuscole void e non Void ad esempio; non puoi scrivere i comandi come ti pare), mancano graffe e poi ; a casaccio.

Appunto, per me con i vari discorsi di funzioni, loop e quant'altro gli state confondendo le idee.. :wink:
Io continuo ad essere per Occam: se collega sto cacchio di pulsante a RESET qual è il problema scusate? Il tutto si riavvia da capo (e non è mi ca Windows che per ripartire i vogliono MINUTI), è solamente un contatore per la bomba di soft air, quindi ragazzi, ennamosù, facciamogliela facile!

Nel setup fai quel giro in un do{}

Praticamente DO, LAm, REm, SOL7?
:smiley:

docdoc:
... se collega sto cacchio di pulsante a RESET qual è il problema scusate?

... sei sempre per delle pessime soluzioni del tutto diseducative !!! :stuck_out_tongue_closed_eyes: :stuck_out_tongue_closed_eyes: :stuck_out_tongue_closed_eyes:

Guglielmo

Non so se stai scherzando, ma non vedo perché sia una "pessima" soluzione, persino "diseducativa" suggerire di utilizzare un pin esistente, con lo scopo per il quale è stato previsto...
Il tutto sommato poi al fatto che non parliamo di una persona particolarmente esperta.
Boh

#include <Keypad.h>
#include <LiquidCrystal.h>
#include <Tone.h>
#include <Timer.h>
#define pound 14

Timer counter;
//LiquidCrystal lcd(A5,A4,A3,A2,A1,A0);
LiquidCrystal lcd(A0,A1,A2,A3,A4,A5);

int DefuseTimer = 0; // set tempo 0
Tone tone1;
int oldS = 0;
int nbBoucle = 0;


const int ledGreen = 3;
const int ledRed = 4;
////////////////////////
const int pulsante = 5;
int val = 0;
////////////////////////

char password[10]; 
int currentLength = 0; 
int i = 0; 
char entered[10];
int passwordLength;
int nbtry = 1;
int currentTry = nbtry;
const int Buzzer = 2;

const byte ROWS = 4; //four rows
const byte COLS = 4; //three columns
char keys[ROWS][COLS] = {
  {'1','2','3','A'},
  {'4','5','6','B'},
  {'7','8','9','C'},
  {'*','0','#','D'}
};


byte rowPins[ROWS] = {13, 12, 11, 10};
byte colPins[COLS] = {9, 8, 7, 6}; 

Keypad keypad = Keypad( makeKeymap(keys), rowPins, colPins, ROWS, COLS );
boolean b600s = true;
boolean b300s = true;
boolean b120s = true;
boolean b60s = true;
boolean b30s = true;
boolean b10s = true;


void setup ()
{

  int hours, minutes, seconds;
  lcd.begin(16, 2);
  Serial.begin(9600);
  tone1.begin(Buzzer);
  pinMode(ledGreen, OUTPUT);
  pinMode(ledRed, OUTPUT);
  char key;
  boolean cancel;
  do
  {
    cancel = false;
    lcd.clear();
    lcd.setCursor(0,0);
    buttonBip(100);
    lcd.print("Sistema attivo");
    digitalWrite(ledGreen, HIGH);
    delay(500);
    digitalWrite(ledGreen, LOW);
    lcd.setCursor (0,1); // sets cursor to 2nd line
    lcd.print ("S.tempo.");

    if (counter.hours >= 10)
    
    lcd.setCursor (8,1);
    //Heures
    hours = readHours();
    if (hours == -1)
      cancel = hours;
    else
      lcd.setCursor(10,1);
      lcd.print(":");
      
    
    //Minutes
    if (cancel == false)
    {
      minutes = readMinutes();
      if (minutes == -1)
        cancel = true;
      else
        lcd.print(":");
    }
    
    //Secondes
    if (cancel == false)
    {
      seconds = readSeconds();
      if (seconds == -1)
        cancel = true;
    }
    
    if (cancel == false)
    {
      do
        key = keypad.waitForKey();
      while (key != '#' && key != '*');
      buttonBip(100);
      if (key == '*')
        cancel = true;
    }
    
  }
  while (cancel == true);
  delay (500);
  counter.setTime(hours, minutes, seconds);
  
  lcd.clear();
  lcd.setCursor(0,0);
  lcd.print("Inserire codice: ");
  while ((currentLength < 1 || key != '#'))
  { 
    
    lcd.setCursor(currentLength, 1);
    //lcd.cursor();
    key = keypad.getKey();
    if (key != NO_KEY)
    {
      buttonBip(100);
      if (key!='#' && key != '*' && currentLength < 8)
      { 
        lcd.print(key);
        password[currentLength] = key;
        ++currentLength;
        passwordLength = currentLength;
      }
      else if (key == '*')
      {
        lcd.clear();
        lcd.setCursor(0,0);
        lcd.print("Inserire codice: ");
        currentLength = 0;
        passwordLength = currentLength;
      }
    }
  }
  //Serial.print("rad:bomb:planted");
  delay(500);
  lcd.clear();
  currentLength = 0;
}

void loop()
{

  timer();
  
  currentLength = 0;
  lcd.clear();
  lcd.setCursor(0,0);
  lcd.print("Codice: ");
  
  boolean lec_code = true;
  char code[8];
  int i = 0;
  char key2;
    
  while (lec_code == true)
  {
    timer();
    
    key2 = keypad.getKey();
    if (key2 != NO_KEY)
      buttonBip(100);
      
    if (key2 == '#' || i >= 8)
      lec_code = false;
    else if (key2 == '*')
    {
      currentLength = 0;
      lcd.clear();
      lcd.setCursor(0,0);
      lcd.print("Codice: ");
    }
    else                  
    if (key2 != NO_KEY && currentLength < 8)    
    {
      entered[currentLength] = key2;
      currentLength++;
      delay(100);
      lcd.noCursor();
      lcd.setCursor(currentLength + 7, 0);
      lcd.print(key2);
      lcd.setCursor(currentLength + 8, 0);
      lcd.cursor();
    }
  }
  
  boolean correct = true;
  for (int j = 0; j < currentLength; ++j)
    if (entered[j] != password[j])
      correct = false;
      
  if (correct == true && passwordLength == currentLength)
  {
    Defused();
  }
  else if (currentLength >= 1)
  {
    lcd.noCursor();
    lcd.clear();
    lcd.home();
    lcd.print("Password Errata!");
    buttonBip(100);
    delay(300);
    buttonBip(100);
    --currentTry;
    if (currentTry == 0)
      Boom();
    lcd.setCursor(0, 1);
    lcd.print("Tentativo : ");
    lcd.print(currentTry);
    delay(1500);
    currentLength = 0;
  }     
}
//--------------------------------- Timer --------------------------------
prima parte di codice privo di modifiche

seconda e ultima parte del codice riparte appunto da
-----------------------------------------------timer---------------------------------------------

void timer()
{ 
  if (counter.seconds == 0 && counter.minutes == 10 && counter.hours == 0 && b600s == true) {Serial.print("rad:bomb:600s"); b600s = false;}   
  if (counter.seconds == 0 && counter.minutes == 5 && counter.hours == 0 && b300s == true) {Serial.print("rad:bomb:300s"); b300s = false;}
  if (counter.seconds == 0 && counter.minutes == 2 && counter.hours == 0 && b120s == true) {Serial.print("rad:bomb:120s"); b120s = false;}
  if (counter.seconds == 0 && counter.minutes == 1 && counter.hours == 0 && b60s == true) {Serial.print("rad:bomb:60s"); b60s = false;}
  if (counter.seconds == 30 && counter.minutes == 0 && counter.hours == 0 && b30s == true) {Serial.print("rad:bomb:30s"); b30s = false;}
  if (counter.seconds == 10 && counter.minutes == 0 && counter.hours == 0 && b10s == true) {Serial.print("rad:bomb:10s"); b10s = false;}
  
  ++nbBoucle;
  
  
  if (((counter.seconds > 10 && counter.minutes < 1 && counter.hours < 1) || (counter.minutes >= 1 || counter.hours >= 1)) && oldS != counter.seconds)
  {
    oldS = counter.seconds;
    timeBip(100); 
    led(15);
    }
  else if (counter.seconds <= 10 && counter.seconds > 5 && counter.minutes < 1 && counter.hours < 1 && nbBoucle >= 15)
  {
    nbBoucle = 0;
    timeBip(100);
    led(15); 
    }
  else if (counter.seconds <= 5 && counter.seconds > 3 && counter.minutes < 1 && counter.hours < 1 && nbBoucle >= 10)
  {
    nbBoucle = 0;
    timeBip(100);
    led(15);
    }
  else if (counter.seconds <= 3 && counter.minutes < 1 && counter.hours < 1 && nbBoucle >= 5)
  {
    nbBoucle = 0;
    timeBip(100);
    led(15);
    }
  
  refreshTimeLcd();
  
  if (counter.decrement(millis()))
  {
    Boom ();
  }
  
  lcd.noCursor();
  delay(10); // waits for a second
  delay(10); // waits for a second
}


//--------------------------------- LCD --------------------------------
void refreshTimeLcd()
{
  lcd.setCursor (0,1); // sets cursor to 2nd line
  lcd.print ("Tempo:");
  if (counter.hours >= 10)
  {
    lcd.setCursor (7,1);
    lcd.print (counter.hours);
  }
  if (counter.hours < 10) 
  {
    lcd.setCursor (7,1);
    lcd.write ("0");
    lcd.setCursor (8,1);
    lcd.print (counter.hours);
  }

  lcd.print (":");

  if (counter.minutes >= 10)
  {
    lcd.setCursor (10,1);
    lcd.print (counter.minutes);
  }
  if (counter.minutes < 10) 
  {
    lcd.setCursor (10,1);
    lcd.write ("0");
    lcd.setCursor (11,1);
    lcd.print (counter.minutes);
  }
    
  lcd.print (":");

  if (counter.seconds >= 10) 
  {
    lcd.setCursor (13,1);
    lcd.print (counter.seconds);
  }
  if (counter.seconds < 10) 
  {
    lcd.setCursor (13,1);
    lcd.write ("0");
    lcd.setCursor (14,1);
    lcd.print (counter.seconds);
  } 
}

//--------------------------------- Heures --------------------------------
int readHours ()
{
  char key;
  char hour[3];
  int hours;
  for (int i=0; i<2; ++i)
  {
    do
    {
      key = keypad.waitForKey();
      if (key != NO_KEY)
        buttonBip(100);
    }
    while (key == NO_KEY || key == '#');

    if (key == '*')
      return -1;
      
    hour[i] = key;
    lcd.print(key);
  }
  hour[2] = '\0';
  hours = atoi(hour);
  return hours; 
}

//--------------------------------- Minutes --------------------------------
int readMinutes ()
{
  char stTemp[2];
  char key;
  char minute[3];
  int minutes;
  for (int i=0; i<2; ++i)
  {
    do
    {
      key = keypad.waitForKey();
      if (key != NO_KEY)
        buttonBip(100);
      if (key == '*')
        return -1;
      sprintf(stTemp,"%c",key);
    }
    while (key == NO_KEY || key == '*' || key == '#' || ((atoi(stTemp)) >= 6 && i == 0));
    minute[i] = key;
    lcd.print(key);
  }
  minute[2] = '\0';
  minutes = atoi(minute);
  return minutes;
}

//--------------------------------- Secondes --------------------------------
int readSeconds ()
{
  char stTemp[2];
  char key;
  char second[3];
  int seconds;
  for (int i=0; i<2; ++i)
  {
    do
    {
      key = keypad.waitForKey();
      if (key != NO_KEY)
        buttonBip(100);
      if (key == '*')
        return -1;
      sprintf(stTemp,"%c",key);
    }
    while (key == NO_KEY || key == '*' || key == '#' || (atoi(stTemp) >= 6 && i == 0));
    second[i] = key;
    lcd.print(key);
  }
  second[2] = '\0';
  seconds = atoi(second);
  return seconds;
}

//--------------------------------- Boom -------------------------------------
void Boom ()
{
  
  lcd.noCursor();
  lcd.clear();
  lcd.home();
  lcd.print(".Bomba..Esplosa.");
  lcd.setCursor (0,1);
  lcd.print("..Ricominciare..!");
   digitalWrite(ledGreen, LOW);
  digitalWrite(ledRed, HIGH); 
  tone1.play(NOTE_F2, 3000);
  delay(8000);
   while (1)
   delay(100000);
    
    
}

//--------------------------------- Defused ----------------------------------
void Defused ()
{
  
  lcd.noCursor();
  lcd.clear();
  lcd.home();
  lcd.print("Bomba disat.");
  digitalWrite(ledGreen, HIGH);
  digitalWrite(ledRed, LOW);
  refreshTimeLcd();
  buttonBip(200);
  delay(300);
  buttonBip(200);
  delay(300);
  buttonBip(200);
  currentLength = 0;
  while (1)
  delay(1000000);
          
}
//--------------------------------- led ----------------------------------
void led (int mills)
{
  digitalWrite(ledRed, HIGH);
  delay(15);
  digitalWrite(ledRed, LOW);
  //delay(15);
  }
  


//---------------------------------- timeBip ---------------------------------
void timeBip (int mills)
{
  tone1.play(NOTE_F7, mills);
}

//---------------------------------- buttonBip ---------------------------------
void buttonBip (int mills)
{
  tone1.play(NOTE_A7, mills);
}

Ma se è grande per metterlo come testo, mandalo come allegato no?
In basso, "Attachments and other options".

compila?

Damian10:

...

Okay il codice, ma la risposta alla domanda ?
Da quale punto (inizio) della setup() a quale punto (fine) della setup vuoi ripetere ?
Dal punto iniziale al punto finale, lo tagli e lo metti in una void MiaFunz() {}
e al posto di quel blocco metti la chiamata MiaFunz();

Presumo da char key; fino alla graffa chiusa del do{

void setup ()
{ lcd.begin(16, 2);
  Serial.begin(9600);
  tone1.begin(Buzzer);
  pinMode(ledGreen, OUTPUT);
  pinMode(ledRed, OUTPUT);
  MiaFunz();   
  //Serial.print("rad:bomb:planted");
  delay(500);
  lcd.clear();
  currentLength = 0;
}

void MiaFunz()
{ int hours, minutes, seconds;
  char key;
  boolean cancel;
  do
  {
    cancel = false;
    lcd.clear();
    lcd.setCursor(0,0);
    buttonBip(100);
    lcd.print("Sistema attivo");
    digitalWrite(ledGreen, HIGH);
    delay(500);
    digitalWrite(ledGreen, LOW);
    lcd.setCursor (0,1); // sets cursor to 2nd line
    lcd.print ("S.tempo.");
    if (counter.hours >= 10)
    lcd.setCursor (8,1);
    //Heures
    hours = readHours();
    if (hours == -1)
      cancel = hours;
    else 
    { lcd.setCursor(10,1);
      lcd.print(":");
    }
    //Minutes
    if (cancel == false)
    { minutes = readMinutes();
      if (minutes == -1)
        cancel = true;
      else
        lcd.print(":");
    }
    //Secondes
    if (cancel == false)
    { seconds = readSeconds();
      if (seconds == -1) cancel = true;
    }
    if (cancel == false)
    { do
      { key = keypad.waitForKey();
      } while (key != '#' && key != '*');
      buttonBip(100);
      if (key == '*') cancel = true;
    }
  } while (cancel == true);
  delay (500);
  counter.setTime(hours, minutes, seconds);
  lcd.clear();
  lcd.setCursor(0,0);
  lcd.print("Inserire codice: ");
  while ((currentLength < 1 || key != '#'))
  { lcd.setCursor(currentLength, 1);
    //lcd.cursor();
    key = keypad.getKey();
    if (key != NO_KEY)
    {
      buttonBip(100);
      if (key!='#' && key != '*' && currentLength < 8)
      { 
        lcd.print(key);
        password[currentLength] = key;
        ++currentLength;
        passwordLength = currentLength;
      }
      else if (key == '*')
      {
        lcd.clear();
        lcd.setCursor(0,0);
        lcd.print("Inserire codice: ");
        currentLength = 0;
        passwordLength = currentLength;
      }
    }
  }
}

A me pare ci siano un bel pò di errori comunque nel tuo programma.
Ad esempio cancel è variabile boolean, accetta solo true e false, che senso ha nel tuo codice la if che se hour è -1 allora cancel = hours; ?? Come può cancel essere un valore se booleano ??

nid69ita:
A me pare ci siano un bel pò di errori comunque nel tuo programma.
Ad esempio cancel è variabile boolean, accetta solo true e false, che senso ha nel tuo codice la if che se hour è -1 allora cancel = hours; ?? Come può cancel essere un valore se booleano ??

Ti spiego meglio ho tolto alcune funzioni e alcuni pezzi di codice sono rimasti ma non mi influenzano il funzionamento di tutto il resto è poi Ho più codici scritti tra cui uno quasi finito e come potete capire siccome ci lavoro ancora preferisco lavorare sui codici di prova