fermare loop

Ciao a tutti non riesco a capire come stoppare al meglio l’AVVIO CICLO, ora azzero la variabile NUMEROFOTO
pero non mi sembra la soluzione migliore…GRAZIE :smiley:

//CICLO AUTOMATICO
void AVVIO_CICLO(){
  for(int f=1 ; f< NUMEROFOTO  ; f++){
    STOP_FINECORSA();
    BUZZER();
    SCATTO_D70();
    delay(400);
    lcd.setCursor(13,1);
    lcd.print(f);
    CONTROLLO_DIREZIONE();
    ARMA_DRIVER();
    START_MOTORE();
    STOP_MOTORE();                    
    TIMER_DOLLY();    
  }
}


// AVVIA LA ROTAZIONE:
void START_MOTORE(){
    for(int i=0 ; i<STEPS_NUM  ; i++){
      STOP_FINECORSA();
      digitalWrite(STEPPERPIN, HIGH);   
      delayMicroseconds(STEPS_VEL);
      digitalWrite(STEPPERPIN, LOW);
      delayMicroseconds(STEPS_VEL);
      }
}


// CONTROLLO PULSANTE E FINECORSA DI STOP
void STOP_FINECORSA(){
  STATOFINECORSA = digitalRead(FINECORSA);
  if (STATOFINECORSA == LOW){
    digitalWrite(SLEEP,HIGH);
  }      
  else {
    digitalWrite(SLEEP,LOW);
    NUMEROFOTO = 0;}   
}

Ciao, che intendi per "stoppare al meglio"? la funzione avvio_ciclo esegue n=numerofoto-1 cicli di istruzioni e poi il programma ritorna nel punto in cui è stata chiamata. Dove le hai messe queste 3 funzioni?

potresti usare un poco elegante break; se è quello che ho capito

ciao Dan303

Dalle informazioni date non riesco a afferrare il problema.

Ciao Uwe

In poche parole quando avvio: AVVIO CICLO lui esegue le funzioni al suo interno fino a raggiungere il NUMEROFOTO impostato, io vorrei fermare tutte queste funzioni alla pressione del finecorsa , per questo ho inserito STOP_FINECORSA(); che al suo interno ferma EasyDriver (che gestisce il motore) e setta NUMEROFOTO a 0, facendo cosi il tutto si ferma...pero resto con NUMEROFOTO a 0, e non mi sembra la miglior soluzione per tornare al punto dove è stata chiamata, spero di essere stato più chiaro. grazie

Usa un semaforo. In testa al programma definisci una variabile di controllo:

char semaforo = 1;

All'interno della for controlla il valore di semaforo, che resetti quando necessario in STOP_FINECORSA, e se vale zero usa la break per uscire dal ciclo:

if (semaforo == 0) break;

In questo modo il valore di NUMEROFOTO rimane inalterato.

Effettivamente i BREAK non sono belli. Generalmente per queste cose non si usa un FOR ma un WHILE:

void AVVIO_CICLO(){
int f=1;
boolean esci=false;
    do {
        fai_quello_che_devi_fare;
        if (controlla_condizione) {
            esci=true;
        } else {
            f++;
        }
    while (f<NUMEROFOTO && esci==false);
  }
}

leo72: Effettivamente i BREAK non sono belli.

Potranno anche non essere belli, però è l'istruzione esatta per uscire da un loop al momento desiderato, cioè senza continuare l'iterazione, poi c'è pure la "continue" che fa uscire dal loop al termine dell'iterazione. La break è molto comoda quando esistono varie condizioni che possono portare al termine del loop e si verificano in punti diversi del ciclo, esempio classico la switch dove ogni case è terminato da una break in modo da non continuare ulteriormente il controllo se la condizione è vera.

Sì, negli switch/case sono necessari ma non ho capito però perché: in teoria dovrebbe essere il linguaggio che, vedendo un nuovo case, termina l'esecuzione del precedente. In altri linguaggi è così, mi pare un limite questo.

Ciao Leo72 Non é detto; il case puoi usare senza break quando vuoi che sia eseguito quello di un case e quello sucessivo.

esempio stupido:

switch (var) {
    case 3:
       i++;
    case 2:
      i++;
    case 1:
       i++;
    }

restituisce un numero nella variabile i uguale a var.

Ciao Uwe

Sì ma sono casi ipotetici e poco logici. Basta fare i=var ed ho ottenuto lo stesso risultato impiegando molto meno codice. O forse ci sono altri risvolti che non conosco, non conoscendo bene il C? Boh.. :blush:

Il break non è altro che un JMP, nel caso del case probabilmente il codice viene compilato con una serie di BREQ (brench if equals) cioè una serie di IF in C che saltano a dei puntatori. Eseguito il codice dopo questi puntatori però non viene inserito il JMP verso la fine del case in modo automatico perchè è più comodo cosi; nel caso infatti si debba eseguire la stessa funzione se la variabile (ad esempio) è uguale a 0,1,2 basta scrivere:

switch (prova) {
  case 0:
  case 1:
  case 2: 
     funzione...
     break;
  case 3:
    funzione2...
    break;
.....
}

questa non la sapevo. però aiutami a capire, andrebbe un break dopo la funzione per poi continuare con i case 3,4, etc..? o il brake si mette solo alla fine dei case?

Ok ora ho sistema ed inserito il break; In tal caso se hai le condizioi 0,1 o 2 viene eseguita la stessa funzione e poi terminato il case o viene eseguito il caso 3(se verificato) e avanti così.

perfetto! grazie della spiegazione. ora capisco un pò di errori che facevo…

uwefed: Ciao Leo72 Non é detto; il case puoi usare senza break quando vuoi che sia eseguito quello di un case e quello sucessivo.

esempio stupido:

switch (var) {
    case 3:
       i++;
    case 2:
      i++;
    case 1:
       i++;
    }

restituisce un numero nella variabile i uguale a var.

Ciao Uwe

SI ma in questo modo si perde utilità dello switch che nasce per avere al suo interno controli booleani che sono mutuamente esclusivi tra loro. Oltretutto il codice diventa poco leggibile...

In effetti l'utilità dello switch è dubbia ed in alcuni linguaggi moderni è stato completamente tolto di mezzo (ad esempio in python).

Dico la mia, poi ognuno la pensi come vuole. Probabilmente essendo il C un linguaggio che ha diversi decenni sulle spalle, mostra in alcuni suoi costrutti questa sua vecchiezza: lo switch, secondo me, è uno di questi. Io preferisco lo stile del blocco in automatico alla fine del case, come ad esempio nel Gambas (che ha un SELECT CASE e CASE multi-opzione: CASE 1 TO 4, ad esempio), al posto dello stile C a "ruota libera" finché non viene incontrato un BREAK. Poi sono gusti e questo è un parere molto IMHO.

xelendilx:

uwefed: Ciao Leo72 Non é detto; il case puoi usare senza break quando vuoi che sia eseguito quello di un case e quello sucessivo.

esempio stupido:

switch (var) {
    case 3:
       i++;
    case 2:
      i++;
    case 1:
       i++;
    }

restituisce un numero nella variabile i uguale a var.

Ciao Uwe

SI ma in questo modo si perde utilità dello switch che nasce per avere al suo interno controli booleani che sono mutuamente esclusivi tra loro. Oltretutto il codice diventa poco leggibile...

In effetti l'utilità dello switch è dubbia ed in alcuni linguaggi moderni è stato completamente tolto di mezzo (ad esempio in python).

è utile per risparmiare righe di codice negli if se alla fine riguardano una stessa variabile. così, invece di scrivere if()... else if()... else si mette uno switch() case 1: break; case 2: break; default: break;

superlol: è utile per risparmiare righe di codice negli if se alla fine riguardano una stessa variabile. così, invece di scrivere if()... else if()... else si mette uno switch() case 1: break; case 2: break; default: break;

Sopratutto permette di risparmiare molte istruzione assembly e di conseguenza cicli macchina, ovvero una switch con le relative case: break è molto più efficiente di una cascata di if. E' vero che il C è anzianotto, ma perché non provate a chiedervi perché è il linguaggio universalmente usato per scrivere i sistemi operativi e gli altri linguaggi ?

Vero, su questo hai ragione. Ma il fatto che sia semplice, stabile, sicuro, affidabile, performante non significa che non abbia limiti e/o carenze. ;) Tutto qui, poi non voglio mettermi a criticare per il gusto di farlo, solo voglio far presente che lo switch per me funziona in maniera buffa.