Go Down

Topic: pressione di un tasto sul telecomando per uscire da un ciclo for (Read 142 times) previous topic - next topic

nanigago

Ciao a tutti, nonostante le svariate ricerche in rete non riesco ad adattare le soluzioni adottate da altri al mio caso specifico, quindi vi chiedo aiuto e mi scuso fin d'ora se la cosa è banale o già spiegata, ma non ci arrivo.
Attraverso un telecomando con una sequenza di switch case decido l'azione che il programma deve compiere. Una di queste azioni è l'avanzamento di un supporto fino al raggiungimento del relativo finecorsa.
Per ovviare al fatto che se premo il pulsante relativo all'avanzamento, il motore avanza a scatti, ogni volta che premo il tasto e non in modo continuo, ho creato una funzione che lo fa muovere in modo continuo, ora mi chiedo e qui sta il nocciolo della domanda come faccio se voglio interrompere il ciclo for all'interno della funzione ripeti_avanti() ? Non riesco a capire dove inserire il break per richiamarlo dall'ultimo case della funzione switch-case e fare in modo che questo mi agisca all'interno della funzione. Allego le porzioni di codice interessate, come sempre vi ringrazio anticipatamente per l'aiuto che potrete fornirmi, grazie

Code: [Select]

void loop()
{
  if(irrecv.decode(&results)) //sto ricevendo un segnale IR?
  {
    Serial.println(results.value, HEX); // mostrami il segnale ricevuto attraverso il serial monitor in hexadecimale
    irrecv.resume();// mi preparo per ricevere il prossimo segnale
  }
  scelta();
}

void scelta(){
  switch(results.value){
    case 0x4075708F:
    ripeti_avanti();
    break;
    case 0x4075A05F:
    ripeti_indietro();
    break;
    case 0x4075807F:
    rotazione_avanti();
    break;
    case 0x4075609F:
    rotazione_indietro();
    break;
    case 0x407512ED:
    ferma_tutto();
    break;
    }
}
void tv_avanti(){
  sensorVal3=digitalRead (limitswitchPinTVfuori);
  if(sensorVal3 != 1){
    goto basta_avanti;
  }
  digitalWrite(9, HIGH);
  digitalWrite(pinDir, HIGH);
  for (int x = 0; x < numStepMotore; x++ ){
    digitalWrite(pinStep, HIGH);
    delayMicroseconds(velocita);
    digitalWrite(pinStep, LOW);
    delayMicroseconds(velocita);
  }
  basta_avanti:
  digitalWrite(9, LOW);
  digitalWrite(pinDir, LOW);
  digitalWrite(pinStep, LOW);
}

void ripeti_avanti(){
  for(int z=0; z<200; z++){
    tv_avanti();
  }
}

maubarzi

non puoi usare lo switch case esterno, ma all'interno del nuovo ciclo devi rileggere l input e fare un nuovo test per uscire dal ciclo
breve perché sono da cell
Nessuna buona azione resterà impunita!

Preistoria -> medioevo -> rinascimento -> risorgimento -> rincoglionimento!

Maurotec

Per quelle operazioni che non richiedono interattivita tramite telecomando puoi usare lo schema attuale, dove nel case: richiami una funzione al cui interno c'è un ciclo. Mentre quando è richiesta una interazione tramite telecomando (come nel caso in cui vuoi fermare ciò che hai iniziato) lo schema attuale non funziona.

Ci sono vari modi di affrontare il problema anche molto complessi e creativi, il nocciolo è che se da dentro il loop avvii un funzione che restituisce il controllo al chiamante (loop()) solo dopo avere terminato un ciclo di operazioni queste non possono essere fermate dal chiamante (loop()). Infatti durante il tempo che la funzioni impiega per svolgere il compito che gli hai dato non puoi interaggire tramite telecomando.

Se la soluzione l'avessi semplice te la mostrerei ma al momento non la ho, vedo anche che usi i for per inviare gli impulsi ad un motore passo passo e questo monopolizza l'uso della CPU rendendo impossibile interaggire tramite telecomando.

Una soluzione richiede una seconda scheda programmata per muovere il motore passo passo, comandata dalla prima scheda (attuale) che gestisce il telecomando e altro, quando ricevi dal telecomando il codice per attivare rotazione_indietro(), questa invia un comando del tipo: muovi indietro di tot passi e termina rapidamente resituendo il controllo al chiamante. Se da telecomando arriva il segnale FERMATUTTO, sollevi un pin collegato tra le due schede e ciò ferma il comando che gli avevi dato prima.

PS:Un modo differente c'è di sicuro ma è da verificare se funziona e coinvolge cose come i Timer Hardware e gli interrupt a questo legati e attivabili.

Ciao.

Datman

Dalla funzione ripeti_avanti(), all'interno del for, bisogna chiamare una funzione che legge il telecomando. Userai tale funzione anche per leggerlo nel loop().
Considera che la lettura del telecomando rallenterà un po' il for.
Hi,I'm Gianluca from Roma.I play&work with electronics since I was16(1984).
After 25yrs of maintenance on cameras&video mixers,since 2013myJob is HDTVstudios design.
Since Jan2015 IPlayWith Arduino:bit.ly/2F3LPWP
Thanks 4 a Karma if U like my answer

nanigago

Grazie a tutti per le risposte, adesso prendendo spunto dai vostri suggerimenti farò qualche prova, grazie ancora.

Go Up