prime esperienze switch case

ho provato di tutto, ma non riesco a capire dove sbaglio.
questa e' parte di una realizzazione che vorrei fare, ho deciso di fare a piccoli passi per non incasinarmi la vita, e mollare arduino.

#define PIATTO 13 // motore che ruota il piatto per posizionare pezzi sotto le stazioni;
#define tapp  12    // comanda elettrovalvola 1;
#define filling 11 // comanda elettrovalvola staz 2;
#define pos 10       // legge la posizione del piatto;
#define start 9      //avvia il ciclo;
#define pieno 8      //segnala termine stazione 2;
int stato = 1;
void setup() {
  pinMode (PIATTO , OUTPUT);
  pinMode (tapp , OUTPUT);
  pinMode (filling , OUTPUT);
  pinMode (pos , INPUT);
  pinMode (start , INPUT);
  pinMode (pieno , INPUT);
  // put your setup code here, to run once:

}

void loop() {
  digitalRead (pos);
  digitalRead (start);
  digitalRead (pieno);
  // put your main code here, to run repeatedly:
  switch (stato);{
    case 1:
        digitalWrite (PIATTO, HIGH);
        if digitalRead (pos == HIGH) stato = 2;
    break;
    case 2:
        digitalWrite (PIATTO, LOW);
        delay (500);
        digitalWrite (filling, HIGH);
        digitalWrite (tapp, HIGH);
        delay (3000);
        digitalWrite (tapp, LOW);
        if digitalRead (pieno == HIGH) stato = 3;
    break;
    case 3:
        digitalWrite (filling, LOW);
        delay (500);
        digitalWrite (PIATTO,HIGH);
        if digitalRead (pos == HIGH) stato = 2;
    break;

}}

Ciao,
qualche parola in più nella presentazione potevi scriverla!

  1. leggi lo stato dei pin e poi? Leggi questo e poi verifica quello che hai scritto tu
  2. la variabile stato dove viene valorizzata nel loop?
  3. qui trovi il referenze per lo switch...case, leggilo bene e verifica la tua punteggiatura

[Edit]
mi era sfuggito ...
4) visto che sei nel reference, leggi anche questo

Federico

Federico66:
Ciao,
qualche parola in più nella presentazione potevi scriverla!

... anche perché essa dovrebbe servire per quanto descritto al punto 16.7 del REGOLAMENTO ::slight_smile: ... quindi più dettagli ci sono e meglio è !

Guglielmo

gpb01:
... anche perché essa dovrebbe servire per quanto descritto al punto 16.7 del

ero in dubbio se rispondere, ma poi mi sono adattato alla sua presentazione... credo ::slight_smile:

Federico

si tratta di un imbottigliatrice.
in una stazione, scende una canula all'interno della bottiglia, tramite un pistone pneumatico.
in un altra stazione, c'e' la classica tappatrice a corona, anche questa pneumatica.
un piatto girevole in pvc, dove posizionare bottiglie, questo mosso da motoriduttore
in ultimo un finecorsa, induttivo, per posizionare la bottiglia nella stazione.

purtroppo non riesco ad inserire foto al momento.

quando scrivo int stato = 1 non indico che parta da caso 1. giusto?...
e int val = 0 definisce TUTTI i pin bassi?

#define PIATTO 13 // motore che ruota il piatto per posizionare pezzi sotto le stazioni;
#define tapp  12    // comanda elettrovalvola 1;
#define filling 11 // comanda elettrovalvola staz 2;
#define pos 10       // legge la posizione del piatto;
#define start 9      //avvia il ciclo;
#define pieno 8      //segnala termine stazione 2;
int stato = 1;
int val = 0 ;
void setup() {
  pinMode (PIATTO , OUTPUT);
  pinMode (tapp , OUTPUT);
  pinMode (filling , OUTPUT);
  pinMode (pos , INPUT);
  pinMode (start , INPUT);
  pinMode (pieno , INPUT);
  // put your setup code here, to run once:

}

void loop() {
  val = digitalRead (pos);
  val = digitalRead (start);
  val = digitalRead (pieno);
  // put your main code here, to run repeatedly:
  switch (stato);{
    case 1:
        if digitalRead (pos == LOW);
        digitalWrite (PIATTO, HIGH);
        if digitalRead (pos == HIGH) stato = 2;
    break;
    case 2:
        digitalWrite (PIATTO, LOW);
        delay (500);
        digitalWrite (filling, HIGH);
        digitalWrite (tapp, HIGH);
        delay (3000);
        digitalWrite (tapp, LOW);
        if digitalRead (pieno == HIGH) stato = 3;
    break;
    case 3:
        digitalWrite (filling, LOW);
        delay (500);
        digitalWrite (PIATTO,HIGH);
        if digitalRead (pos == HIGH) stato = 2;
    break;

}}

Hai fatto un errore di battitura (o da principiante), c'è un ; di troppo

switch (stato);{

Lo vedi il ; beh non ci deve stare.

PS: Migliora la presentazione così almeno capiamo con chi abbiamo a che fare, diversamente potremmo fare delle deduzioni in base ai post, deduzioni che però sono soggettive e potrebbero non corrispondere alla realtà.

Inoltre il tipo di dato int è grande 16 bit e accetta valori negativi, sei sicuro la variabile di stato debba essere di tipo int?
Oppure è più indicato il tipo byte che è grande 8 bit e non accetta valori negativi.?

Ciao.

ho costruito questa in 4 ore,
e non ne son bastate 8 per scrivere due righe che non vanno..

l'errore di punteggiatura, non era l'unico, infatti nei vari tentativi avevo corretto anche le punteggiature,
( ; )nei (case) invece che (: )
oramai sono andato in palla, e non riesco a ricordare neanche il perchè di alcune funzioni.

int val = 0
restituisce tutti i valori dei pin a 0?

quando passo da uno stato all'altro, i pin alti, rimangono tali fino alla riga in cui li abbasso giusto?

tutte le letture che ho fatto dopo aver scritto queste 4 righe, mi hanno incasinato la testa ancora di piu'

lorenzo17:
ho costruito questa in 4 ore,

Io, tra tempo, attrezzatura, e abilità meccaniche, non ci riuscirei in un mese :stuck_out_tongue:

e non ne son bastate 8 per scrivere due righe che non vanno..

La programmazione non è difficile, ma richiede inevitabilmente (molto) tempo e prove pratiche per digerire i giusti concetti mentali che permettono (poi) di procedere spediti.

l'errore di punteggiatura, non era l'unico, infatti nei vari tentativi avevo corretto anche le punteggiature, ( ; )nei (case) invece che (: )

Sarebbe meglio ripartire da un codice senza errori sintattici (la compilazione deve andare a buon fine), in modo che ci si possa concentrare su quelli semantici (credere che qualcosa faccia una cosa diversa da quella che fa), e poi su quelli logici. Già il fatto di aver scomposto tutto in vari "casi" è comunque un buonissimo inizio, o, se vogliamo, è il giusto "design".

int val = 0
restituisce tutti i valori dei pin a 0?

Quell'istruzione definisce una variabile intera di nome 'val' e le assegna il valore 0, non fa altro. A cosa serva quella variabile dipende da come dove e perché la si usa nel resto del programma. In particolare non capisco cosa vuol dire "restituisce i valori dei pin a zero".

quando passo da uno stato all'altro, i pin alti, rimangono tali fino alla riga in cui li abbasso giusto?

Un pin va alto o basso in seguito all'esecuzione di una digitalWrite, e rimane fisso fino a quando viene eseguita la prossima digitalWrite.

ho costruito questa in 4 ore,
e non ne son bastate 8 per scrivere due righe che non vanno..

:smiley:
Evidentemente hai sottovalutato il compito.
Io se avessi l'attrezzatura ne fare 2 in 4 ore, tutte e due sbagliate che non funzioneranno mai, e dovrei essere contento del risultato poiché non ho subito danni fisici, menomazioni ecc. :smiley:

Se cerchi nel forum "macchine a stati finiti" trovi i post anche di @Claudio_FF e dal codice sembra che tu questo voglia realizzare.

Ti consiglio di usare lo switch case in combinazione con Serial.println("sto eseguendo lo stato 1");
Inoltre non collegare la macchina ad arduino ma al posto di motori elettrovalvole ecc usa dei led.

Sono sicuro che ci arriverai, ma non in 4 ore.

Ciao.

scritto nuovamente, separando i loop

int stato = 1;
#define piatto  13  //motoriduttore posiziona bottiglie sotto stazioni
#define tapp    12  //comanda elettrovalvola tappatrice
#define filling 11  //comanda elettrovalvola riempitrice
#define pos     10  //legge posizione stazioni
#define start   9   //avvia il ciclo
#define pieno   8   //termina ciclo riempimento 
void setup() {
  pinMode (piatto,OUTPUT);
  pinMode (tapp,OUTPUT);
  pinMode (filling,OUTPUT);
  pinMode (pos,INPUT);
  pinMode (start,INPUT);
  pinMode (pieno,INPUT);
  // put your setup code here, to run once:

}

void loop() {
  switch (stato){
    case 1:
      loop 1 ();
    break;
    case 2:
      loop 2 ();
    break;
    case 3:
      loop 3 ();
    break;
  }
  }
  void loop 1 () {
    digitalWrite (piatto, HIGH);
    if digitalRead (pos == HIGH);
    stato = 2;
    }
  void loop 2 ()  {
    digitalWrite (piatto, LOW);
    digitalWrite (filling,HIGH);
    digitalWrite (tapp,HIGH);  // questo loop si ripetera'
    delay (3000);   //
    digitalWrite (tapp,LOW);
      if digitalRead (pieno == HIGH);
      stato = 3;
    
    }
  void loop 3  () {
    digitalWrite (filling, LOW);
    delay (500);
    digitalWrite (piatto,HIGH);
    if digitalRead (pos == HIGH);
    stato = 2;
    
    }
  // put your main code here, to run repeatedly:

}

questa la fila di errori che

Arduino:1.8.1 (Windows 8), Scheda:"Arduino/Genuino Uno"

C:\Users\Utente\Documents\Arduino\sketch_jan18a\sketch_jan18a.ino: In function 'void loop()':

sketch_jan18a:22: error: expected ';' before numeric constant

loop 1 ();

^

sketch_jan18a:25: error: expected ';' before numeric constant

loop 2 ();

^

sketch_jan18a:28: error: expected ';' before numeric constant

loop 3 ();

^

C:\Users\Utente\Documents\Arduino\sketch_jan18a\sketch_jan18a.ino: At global scope:

sketch_jan18a:32: error: expected initializer before numeric constant

void loop 1 () {

^

sketch_jan18a:37: error: expected initializer before numeric constant

void loop 2 () {

^

sketch_jan18a:47: error: expected initializer before numeric constant

void loop 3 () {

^

sketch_jan18a:57: error: expected declaration before '}' token

}

^

exit status 1
expected ';' before numeric constant

Questo report potrebbe essere più ricco di informazioni abilitando l'opzione
"Mostra un output dettagliato durante la compilazione"
in "File -> Impostazioni"

Dura la vita per un principiante con le tue capacità.
Banali errori di sintassi, tocca studiare almeno qualche esempio presente nell'ide e cercare di capire.

C'è una cosa positiva stai usando le macro del preprocessore, quelle con #define in modo corretto e questo è raro accada ad un principiante, ora penso che lo fai con cognizione di causa oppure hai copiato e se hai copiato senza capire hai copiato bene, tocca per il momento copiare bene da altrove.

void loop 1

Per il compilatore non ha alcun significato. Io in libera interpretazione penso che avessi voluto creare una funzione di nome "loop1" che non restituisce nulla al chamante "void". Per essere corretto per il compilatore avresti dovuto scrivere:

void loop1() {

}

Dove () sta ad indicare che è una funzione che non prende argomenti e a rigore ciò andrebbe specificato per chiarezza scrivendo void dentro le parentesi, così:

void loop1( void ) {

}

{} servono per definire il blocco di codice (o porzione) appartenente alla funzione, di nome loop1 che non prende e restituisce nulla.

Questa di più funzioni loop non funziona come credi tu, quindi la scarterei e mi concentrerei sul singolo loop.

loop1, miaVariabile, valoreGrezzo sono identificatori e non possono essere scritti come loop 1, mia Variabile ecc. Se vuoi separare le parole puoi usare _, quindi mia_variabile è corretto.

Ti servono i rudimenti del linguaggio che è molto fiscale, hai visto come fa per un ; nel posto sbagliato.

Ciao.

Ciao.

Ciao.

lorenzo17:
questa la fila di errori che

  • I nomi di variabili / costanti / funzioni non possono contenere spazi (e non devono corrispondere a nomi predefiniti già presenti nel linguaggio).
  • Le condizioni delle istruzioni 'if' vanno racchiuse tra parentesi tonde (vedi link indicato al punto 4 da Federico66 nel post #2)
  • Il ';' termina un'istruzione, quindi se viene messo subito dopo la condizione di un'istruzione 'if', rappresenta un'istruzione nulla (la 'if' è come se non ci fosse).

Consiglio1: anche se 'if' dopo la condizione ammette una istruzione senza parentesi graffe, metterle sempre lo stesso, si evitano tanti problemi difficili da individuare:

if (condizione)
{
    istruzione;
}

Consiglio2: appena configurati i pin come uscite, scrivere subito le digitalWrite con i valori di riposo alla partenza, altrimenti ci si può trovare con cose che si accendono a caso.

Consiglio3: il pin 13 su un ArduinoUNO all'accensione genera uno o più impulsi HIGH, se c'è qualcosa collegato può essere attivato per sbaglio.

Ma non c'era uno, pochi mesi fa, che aveva fatto la macchina a stati finiti universale ?

Adesso lo cerco

Standardoil:
Ma non c'era uno, pochi mesi fa, che aveva fatto la macchina a stati finiti universale ?

Adesso lo cerco

Magari grazie.... (a scopo didattico.. naturalmente :slight_smile:

I nomi di variabili / costanti / funzioni non possono contenere spazi (e non devono corrispondere a nomi predefiniti già presenti nel linguaggio).
Le condizioni delle istruzioni 'if' vanno racchiuse tra parentesi tonde (vedi link indicato al punto 4 da Federico66 nel post #2)
Il ';' termina un'istruzione, quindi se viene messo subito dopo la condizione di un'istruzione 'if', rappresenta un'istruzione nulla (la 'if' è come se non ci fosse).

vero, ho fatto confusione, sono stato tratto in inganno, in quanto i cambiamenti di stato andavano al di fuori delle parentesi,

x maurotec.. ho fatto fatica a capire tutti i consigli. anzi alcuni non li ho proprio capiti. comunque non voglio perdere l'entusiamo, e visto le mie difficoltà (partito da blindare un led a macchina a stati in qualche serata....) mi metto di impegno e per risparmiare tempo, investiro' tempo e denaro con un tutor per qualche ora di lezione.

comunque ora ha caricato tutto il codice. mi preparo una board, poi vedro' cosa devo modificare..

int stato = 1;
#define piatto  7  //motoriduttore posiziona bottiglie sotto stazioni
#define tapp    12  //comanda elettrovalvola tappatrice
#define filling 11  //comanda elettrovalvola riempitrice
#define pos     10  //legge posizione stazioni
#define start   9   //avvia il ciclo
#define pieno   8   //termina ciclo riempimento 

void setup() {
  pinMode (piatto, OUTPUT);
  pinMode (tapp, OUTPUT);
  pinMode (filling, OUTPUT);
  pinMode (pos, INPUT);
  pinMode (start, INPUT);
  pinMode (pieno, INPUT);
  // put your setup code here, to run once:

}

void loop() {
  switch (stato) {
    case 1:
      loop1();
      break;
    case 2:
      loop2();
      break;
      case 3:
      break;
  }
}
void loop1() {
  digitalWrite (piatto, HIGH);
  if (digitalRead (pos == HIGH)) stato = 2;
}
void loop2()  {
  digitalWrite (piatto, LOW);
  digitalWrite (filling, HIGH);
  digitalWrite (tapp, HIGH); // questo loop si ripetera'
  delay (3000);   //
  digitalWrite (tapp, LOW);
  if (digitalRead (pieno == HIGH)) stato = 3;

}
void loop3() {
  digitalWrite (filling, LOW);
  delay (500);
  digitalWrite (piatto, HIGH);
  if (digitalRead (pos == HIGH)) stato = 2;

}
// put your main code here, to run repeatedly:

eccolo
https://forum.arduino.cc/index.php?topic=642978.0

leggila tutta la discussione, perchè è interessante
vi si trovano due differenti soluzioni per una macchina a stati finiti "ad alta flessibilità", (universale non potrà essere mai)

Letto tutta la discussione, e parte di irrorino, oltre la complessita per un neofita come me..
e' da escludere in ogni caso, l'utilizzo del tempo per passare da uno stato all'altro.

intanto:

a quanto pare inizia gia' dallo stato 2.
e nessun altro stato funziona neanche cambiando (stato 2 /3 )

ho scritto le digitalWrite di riposo. ed ho anche messo i digitalRead prima del loop

ora non so se puo' aiutare inserire il serial monitor, o visto la mia inesperienza mi complico la vita.

#define PIATTO 13 // motore che ruota il piatto per posizionare pezzi sotto le stazioni;
#define tapp  12    // comanda elettrovalvola 1;
#define filling 11 // comanda elettrovalvola staz 2;
#define pos 10       // legge la posizione del piatto;
#define start 9      //avvia il ciclo;
#define pieno 8      //segnala termine stazione 2;
byte stato = 1;
// eccole le tre variabili di cui parlo dopo
booleane isPos = false;  // false è uguale a 0, true è uguale a 1
booleane isStart = false;
booleane isPieno = false;
// Per i nomi delle variabili ho deciso di mischiare inglese e italiano, isPieno? tradotto sarebbe "è Pieno?"
// Ovviamene se isPieno viene valutata true (vera) vuole dire che qualcosa è pieno.

void setup() {
  pinMode (PIATTO , OUTPUT);
  pinMode (tapp , OUTPUT);
  pinMode (filling , OUTPUT);
  pinMode (pos , INPUT);
  pinMode (start , INPUT);
  pinMode (pieno , INPUT);
  // put your setup code here, to run once:

}

void loop() {
  //val = digitalRead (pos);
  //val = digitalRead (start);
  //val = digitalRead (pieno);
  // Come vedi salvare il risultato di tre digitalRead nella stessa variabile non ha senso.
  // Servono tre variabili di tipo booleane.
  // put your main code here, to run repeatedly:
  switch (stato) {
    case 1:
        Serial.println("case 1");
        delay(1000);
    break;
    case 2:
        Serial.println("case 2");
        delay(1000);
        
    break;
    case 3:
        Serial.println("case 3");
        delay(1000);
    break;

  }
}

Questo sketch non fa altro che stampare ogni secondo "case 1".
Per potere animare i CASE serve cambiare il valore della variabile di stato.
Comunque purtroppo dovrai affrontare un problema per volta, uno di questi è il rimbalzo
dei contatti elettromeccanici come appunto i pulsanti. Si risolve questo problema sia in modo
elettronico che in modo software. Cerca nel forum discussioni sul "debounce".
Ci sono anche delle librerie che in molti usano con vantaggio per risolvere il debounce.

Ciao.

lorenzo17:
ora non so se puo' aiutare inserire il serial monitor

È l'unico modo per farti dire da Arduino a che punto è arrivato (oltre a collegare ed accendere altri LED di debug). Piuttosto immagino che lo schema sia di principio, visto che le uscite di Arduino non possono alimentare direttamente le bobine dei relé.