void e switch case

Buongiorno a tutti, proseguendo con le mie sperimentazioni come al solito mi fermo su alcune cose che non so, perciò chiedo a voi. Fermo restando che credo di aver capito come funziona lo Switch case e il Void() , dopo vari esperimenti non capisco perchè se dal case chiamo una funzione Void() alcune volte funziona, alcune volte non parte nemmeno e alcune volte parte fa un ciclo del Void e poi si ferma. Anche se inserendo un Serial.print di controllo mi conferma che sono ancora dentro alla condizione chiamata. Il problema che ho al momento è che chiamo un Void quando chiamo una posizione del case, mi fa un ciclo del Void e poi si ferma, nonostante io sia ancora dentro alla posizione del chiamata. Ho provato a mettere un if un while ecc, ma tutto resta come se non ci fossero, ovvero il ciclo si ferma dopo una esecuzione. Vi chiedo il perchè di tutto ciò e se potete darmi delle spiegazioni

Grazie

Ciao kemosabesay....dato che alcuni presupposti della tua domanda non sono corretti...o almeno non sono chiari...prima di tutto è bene precisare che per "void" si intende quello che una funzione od un metodo ti ritornano con l'istruzione "return". Più precisamente con void si intende che la funzione NON ha ritorno...e quindi può anche non essere presente il "return". cioè, per fare alcuni esempi semplici, puoi avere:

void funzione1()...nessun ritorno
char funzione2()...ritorna un char
int funzione3()...ritorna un numero nel range degli int

quindi se nel tuo switch uno dei case deve far eseguire una funzione con ritorno void, ma anche qualsiasi altra, e questa non viene eseguita o viene eseguita a raffica ...stai gestendo male lo switch...e come ci arrivi...magari c'è un if prima.

un “Void” non lo chiami :slight_smile:

una qualsiasi funzione che tu crei deve possedere i seguenti parametri:

  1. tipo di dato restituito dalla funzione
  2. nome della funzione
  3. coppia di parentesi con all’interno:
    a) nulla se non vi sono parametri da passare alla funzione oppure:
    b) tipo per primo parametro
    c) nome del primo parametro. Se i parametri sono più di uno una virgola e poi si ricomincia dal punto b)
  4. parentesi graffa di apertura
  5. corpo (istruzioni) della funzione
  6. parentesi graffa di chiusura della funzione

il parametro di cui al punto 1) descrive appunto che dato ritorna la funzione che può essere di qualunque tipo, in più se non restituisce nulla si usa il tipo speciale “void” che appunto vuol dire vuoto… nulla.

Ora se il tuo programma chiama una funzione e non funziona (perdona il bisticcio) mostraci il programma e forse ti potremo aiutare…:wink:

edit
preceduto da ORSO :smiley:

Ok , siccome sto cercando di capire come poter programmare le strisce a led ws2812 e strisce RGB, sto cercando in giro alcuni esempi .
poi per fare prove cerco anche di annidare i vari esempi e qui il tutto si ferma, appunto perchè, metto le varie istruzioni dei vari giochi in alcuni Void().

Al momento sto cercando di implementare dei giochi con una applicazione gia fatta :confused: ,con il Bluetooth, che non fa altro che comandare uno switch .

Nella prova sto cercando di mettere un gioco di luci quando premo un tale pulsante che mi rimanda allo Switch dal quale io poi vorrei comandare il tal gioco, solo che dopo un ciclo il gioco si ferma…

/*
 PROJECT: ArduDroid 
 PROGRAMMER: Hazim Bitar (techbitar at gmail dot com)
 DATE: Oct 31, 2013
 FILE: ardudroid.ino
 LICENSE: Public domain
*/
int redPin= 11;
int greenPin = 10;
int bluePin = 9;


#define START_CMD_CHAR '*'
#define END_CMD_CHAR '#'
#define DIV_CMD_CHAR '|'
#define CMD_DIGITALWRITE 10
#define CMD_ANALOGWRITE 11
#define CMD_TEXT 12
#define CMD_READ_ARDUDROID 13
#define MAX_COMMAND 20  // max command number code. used for error checking.
#define MIN_COMMAND 10  // minimum command number code. used for error checking. 
#define IN_STRING_LENGHT 40
#define MAX_ANALOGWRITE 255
#define PIN_HIGH 3
#define PIN_LOW 2
int stato=0;
String inText;

void setup() {
  Serial.begin(9600);
  Serial.println("ArduDroid 0.12 Alpha by TechBitar (2013)");
  Serial.flush();
  pinMode(redPin, OUTPUT);
  pinMode(greenPin, OUTPUT);
  pinMode(bluePin, OUTPUT);
}

void loop()
{
  Serial.flush();
  int ard_command = 0;
  int pin_num = 0;
  int pin_value = 0;

  char get_char = ' ';  //read serial

  // wait for incoming data
  if (Serial.available() < 1) return; // if serial empty, return to loop().

  // parse incoming command start flag 
  get_char = Serial.read();
  if (get_char != START_CMD_CHAR) return; // if no command start flag, return to loop().

  // parse incoming command type
  ard_command = Serial.parseInt(); // read the command
  
  // parse incoming pin# and value  
  pin_num = Serial.parseInt(); // read the pin
  pin_value = Serial.parseInt();  // read the value

  // 1) GET TEXT COMMAND FROM ARDUDROID
  if (ard_command == CMD_TEXT){   
    inText =""; //clears variable for new input   
    while (Serial.available())  {
      char c = Serial.read();  //gets one byte from serial buffer
      delay(5);
      if (c == END_CMD_CHAR) { // if we the complete string has been read
        // add your code here
        break;
      }              
      else {
        if (c !=  DIV_CMD_CHAR) {
          inText += c; 
          delay(5);
        }
      }
    }
  }

  // 2) GET digitalWrite DATA FROM ARDUDROID
  if (ard_command == CMD_DIGITALWRITE){  
    if (pin_value == PIN_LOW) pin_value = LOW;
    else if (pin_value == PIN_HIGH) pin_value = HIGH;
    else return; // error in pin value. return. 
    set_digitalwrite( pin_num,  pin_value);  // Uncomment this function if you wish to use 
    return;  // return from start of loop()
  }

  // 3) GET analogWrite DATA FROM ARDUDROID
  if (ard_command == CMD_ANALOGWRITE) {  
    analogWrite(  pin_num, pin_value ); 
    // add your code here
    return;  // Done. return to loop();
  }

  // 4) SEND DATA TO ARDUDROID
  if (ard_command == CMD_READ_ARDUDROID) { 
    char send_to_android[] = "Place your text here." ;
     Serial.println(send_to_android);   // Example: Sending text
    Serial.print(" Analog 0 = "); 
    Serial.println(analogRead(A0));  // Example: Read and send Analog pin value to Arduino
    return;  // Done. return to loop();
  }
}

// 2a) select the requested pin# for DigitalWrite action
void set_digitalwrite(int pin_num, int pin_value)

{
  switch (pin_num) {
  case 13:
color();

  /*pinMode(13, OUTPUT);
    digitalWrite(13, pin_value);  
    // add your code here*/
 
  
   
    break;
  case 12:
    pinMode(12, OUTPUT);
    digitalWrite(12, pin_value);   
    // add your code here       
    break;
  case 11:
    pinMode(11, OUTPUT);
    digitalWrite(11, pin_value);         
    // add your code here 
    break;
  case 10:
    pinMode(10, OUTPUT);
    digitalWrite(10, pin_value);         
    // add your code here 
    break;
  case 9:
    pinMode(9, OUTPUT);
    digitalWrite(9, pin_value);         
    // add your code here 
    break;
  case 8:
    pinMode(8, OUTPUT);
    digitalWrite(8, pin_value);         
    // add your code here 
    break;
  case 7:
    pinMode(7, OUTPUT);
    digitalWrite(7, pin_value);         
    // add your code here 
    break;
  case 6:
    pinMode(6, OUTPUT);
    digitalWrite(6, pin_value);         
    // add your code here 
    break;
  case 5:
    pinMode(5, OUTPUT);
    digitalWrite(5, pin_value); 
    // add your code here       
    break;
  case 4:
    pinMode(4, OUTPUT);
    digitalWrite(4, pin_value);         
    // add your code here 
    break;
  case 3:
    pinMode(3, OUTPUT);
    digitalWrite(3, pin_value);         
    // add your code here 
    break;
  case 2:
    pinMode(2, OUTPUT);
    digitalWrite(2, pin_value); 
    // add your code here       
    break;      
    // default: 
    // if nothing else matches, do the default
    // default is optional
  } 
}
void color(){
 
    
  
    setColor(255, 0, 0); // Red Color
  delay(1000);
  setColor(0, 255, 0); // Green Color
  delay(1000);
  setColor(0, 0, 255); // Blue Color
  delay(1000);
  setColor(255, 255, 255); // White Color
  delay(1000);
  setColor(170, 0, 255); // Purple Color
  delay(1000); 
  setColor(0, 0, 0); // Black Color
  delay(1000);       
  }
void setColor(int redValue, int greenValue, int blueValue) {
  analogWrite(redPin, redValue);
  analogWrite(greenPin, greenValue);
  analogWrite(bluePin, blueValue);
}

Per esempio ho cercato il modo di inserire il Void color() quando premo 13, ma fa un ciclo e si ferma, poi quando ri premo 13 il ciclo riparte per una volta e il tutto si ferma…come mai?

Il loop viene eseguito a raffica inizializzando sempre pin_num a 0. Appena c'è qualcosa sulla seriale le cose rallentano e succede questo: Leggi dalla seriale tra cui anche il valore che metti su pin_num, poi c'è lo switch che se pin_num è 13 esegue color() che fa il giro di sequenza cambiando i colori ogni secondo, alla fine del ciclo il loop termina e viene rieseguito ripartendo da pin_num = 0 in attesa che venga riscatenato tutto con un input da seriale.

Ho chiarito qualcosa o peggiorato la situazione?

ok, ma per esempio se io clicco sul tasto 12, il led 12 rimane acceso finchè non lo ripremo, è questo che non mi torna....

Grazie

ciao...secondo me il programma che hai postato si riferisce alla "vecchissima" versione dell'IDE di arduino dove la Serial.flush() aveva un significato...ora ne ha uno totalmente doverso...poi, permettimi di dire, non è conveniente prendere un programma fatto, non capire cosa fa e come lo fa e perchè lo fa, inserire o modificare "a caso" e poi chiedersi perche non funziona !? Se non hai "sicurezza" di cosa fanno e come funzionano certe "istruzioni" fai delle prove semplici per snocciolare il loro comportamento...è più semplice capire perchè una cosa sola non funziona che una cosa su mille. altro aspetto fondamentale...lo "scope" delle variabili...cioè dove e quando sono disponibili...se crei variabili globali sai che queste manterranno il loro ultimo valore assegnato (fino a spegnimento di arduino...locali...vengono create all'ingresso della sezione specifica del programma e "distrutte" quando ne esci...quindi il loro valore è temporaneo. Consiglio...se devi eseguire dei test per impratichirti...inserisci delle Serial.print() nei posti dove vuoi capire cosa sta succedendo...e così ti ritrovi un riferimento a video...se stampa ci sei, e ti dice quello che vuoi sapere, se non stampa non ci sei...e allora vai a cercare il perchè...ma fino a che non hai padronanza...una cosa per volta.

Da qualche parte fai

digitalWrite(12, LOW);

se la risposta è no nessuno spegne l'uscita del pin 12, quindi resta acceso.

cominciamo col semplificare il semplificabile

    if (pin_value == PIN_LOW) pin_value = LOW;
    else if (pin_value == PIN_HIGH) pin_value = HIGH;

qui praticamente dici: se il valore di pin_value è 2 (valore di PIN_LOW) allora pin_value = 0 se il valore di pin_value è 3 (valore di PIN_HIGH) allora pin_value = 1

ma allora non è più semplice eliminare le 2 costanti e inviare da seriale direttamente o 0 (zero) o 1 (uno)? così elimini anche i due if

per la tua domanda.... come ti hanno gia risposto sopra quando invochi il pin 13 la funzione set_digitalwrite lancia la funzione color la quale fa la sua serie di colori intervallati dal delay di 1 secondo per cui il programma sta fermo li poi come ultimo colore hai setcolor(0,0,0) che vuol dire spegni il led e lui si spegne, la funzione finisce e il comando ritorna allo swich, e qui esegue l'istruzione successiva al color() che è il break per cui esce anche dalla funzione set_digitalwrite e il comando ritorna al loop il quale esegue l'istruzione successiva alla chiamata di set_digitalwrite che è un return per cui il programma riparte dall'inizio del loop e per avere un'altra accensione dei led devi rifare tutta la procedura.

nel caso del pin 12 appunto dopo aver acceso il led la funzione set_digitalwrite non fa più nulla e il return la fa terminare per cui il comando ritorna al loop ma nessuna istruzione fa spegnere il led fino a quando tu non iserirai i valori * 12 e 2 nella seriale.

io capisco che fare le prove serva, e di sicuro se prendo qualche esempio in giro è appunto per fare delle prove…

a parte questo, il funzionamento del case penso di averlo capito, solo che mi ferma quando succede qualcosa di particolare.

Infatti ho fatto una domanda che dalle prove mi risulta corretta: ovvero se tolgo la mia modifica e lascio l’originale

{
  switch (pin_num) {
  case 13:
   pinMode(13, OUTPUT);
    digitalWrite(13, pin_value);  
    // add your code here

quando mando sul bluetooth cliccando sul tasto 13 del telefono il led 13 si accende e resta acceso, se poi ripremo il tasto 13 il led 13 si spegne.

appunto perchè sopra ho queste variabili di controllo_:

// 2) GET digitalWrite DATA FROM ARDUDROID
  if (ard_command == CMD_DIGITALWRITE){  
    if (pin_value == PIN_LOW) pin_value = LOW;
    else if (pin_value == PIN_HIGH) pin_value = HIGH;
    else return; // error in pin value. return. 
    set_digitalwrite( pin_num,  pin_value);  // Uncomment this function if you wish to use 
    return;  // return from start of loop()
  }

Fin qui sbaglio qualcosa nel ragionamento???

Grazie

Ciao Patrik, quello che non mi torna è il fatto che sia che io prema 13 o 12 o altro, finchè non li ripremo ho sempre pin_value a 1 , solo che se ci metto il void si ferma se ci metto digitawrite no.....questo non capisco

La App del telefono l'ho trovata pronta da installare e quini non la posso cambiare, e il file che sto provando è l'esempio allegato

Grazie

la app, secondo me, ad ogni pigiata ritornerà alternativamente HIGH e LOW per avere l'esatto comportamento che hai rilevato tu. Quelle che ho visto io per fare prove usano i tasti in toggle, cioè oscillano tra i due valori ad ogni pigiata. Se vuoi che il led si spenga devi farlo tu e se non mi sono sbagliato, devi barare sul valore ritornato dalla app.

si infatti, ad ogni pigiata cambia stato, appunto per questo mi domando come mai se invece che l’accensione del led metto il void, il void si ferma

Grazie

Il led 12 si accende, rimane acceso, ricomincia il loop e aspetta un nuovo comando; color() fa i colori, poi spegne (0,0,0), ricomincia il loop e aspetta un nuovo comando...

Ciao Datman, allora, ho tolto la riga spegne(0,0,0), ma rimane sull’ultimo colore inviato e resta li ferma.

Scusa ma se il case , nel quale ho inserito un serial che mi dice in che stato è il pin_num e il pin_value, mi dice che 13 è a 1, vuol dire che finche il 13 non è a 0 non dovrebbe fermarsi .

Anche quando inserisco il digital del led infatti resta acceso finchè il pin_value non va a 0

Grazie

fermo un attimo…lo switch serve a valutare il valore di una variabile …nel tuo caso valuta il valore di pin_num che è LOCALE al loop e che ad ogni ciclo prende il valore “0”…tu con la tua app da telefono, ad ogni pigiata di un pulsante o quello che è, invii una stringa di dati…quindi se la seriale in arduino contiene delle informazioni, appunto ricevute dal tuo telefono, salva questi dati nelle varie variabili locali, tra cui pin_num, che passerà da “0” ad un altro valore…questo valore viene valutato dal case…se il valore è 13 allora esegue la funzione color()…finita la funzione pin_num torna a valere “0” SUBITO!
ATTENZIONE: questa riga di codice

  if (Serial.available() < 1) return; // if serial empty, return to loop().

fino a che non c’è qualche cosa nella seriale NON fa eseguire tutto il resto del codice…
vuoi testare…mettici, una alla volta, una Serial.print(“qualche cosa”) subito prima e poi subito dopo…non inviare nulla…e poi invia un comando.

PS: per subito intendo ad inzio loop()…dato che appena eseguito color(), case 13 dello switch, la va il programma.

Eh, sì! pin_num viene dichiarato e posto =0 a ogni inizio di loop!

Seguendo i vostri consigli sonoarrivato a questo, ma non funge, nel senso che si blocca lo stesso e che il pin_num non torna a 0

Vi chiedo se sono sulla buona strada o sto sbagliando tutto

Grazie

/*
 PROJECT: ArduDroid 
 PROGRAMMER: Hazim Bitar (techbitar at gmail dot com)
 DATE: Oct 31, 2013
 FILE: ardudroid.ino
 LICENSE: Public domain
*/
int redPin= 12;
int greenPin = 11;
int bluePin = 10;

 int ContatoreStato = 0;                   // conta il numero di volte che il pulsante è premuto buttonPushCounter 
int StatoPin_value = 0;                              // stato corrente del pulsante
int StatoPin_valuePrecedente = 0; 

#define START_CMD_CHAR '*'
#define END_CMD_CHAR '#'
#define DIV_CMD_CHAR '|'
#define CMD_DIGITALWRITE 10
#define CMD_ANALOGWRITE 11
#define CMD_TEXT 12
#define CMD_READ_ARDUDROID 13
#define MAX_COMMAND 20  // max command number code. used for error checking.
#define MIN_COMMAND 10  // minimum command number code. used for error checking. 
#define IN_STRING_LENGHT 40
#define MAX_ANALOGWRITE 255
#define PIN_HIGH 3
#define PIN_LOW 2
int stato=0;
String inText;

int pin_num;
int pin_value;

void setup() {
  Serial.begin(9600);
  Serial.println("ArduDroid 0.12 Alpha by TechBitar (2013)");
 // Serial.flush();
  pinMode(redPin, OUTPUT);
  pinMode(greenPin, OUTPUT);
  pinMode(bluePin, OUTPUT);
}

void loop()
{

 // Serial.flush();
  int ard_command = 0;
  int pin_num = 0;
  int pin_value = 0;

  char get_char = ' ';  //read serial

  // wait for incoming data
  if (Serial.available() < 1) return; // if serial empty, return to loop().

  // parse incoming command start flag 
  get_char = Serial.read();
  if (get_char != START_CMD_CHAR) return; // if no command start flag, return to loop().

  // parse incoming command type
  ard_command = Serial.parseInt(); // read the command
  
  // parse incoming pin# and value  
  pin_num = Serial.parseInt(); // read the pin
  pin_value = Serial.parseInt();  // read the value

  // 1) GET TEXT COMMAND FROM ARDUDROID
  if (ard_command == CMD_TEXT){   
    inText =""; //clears variable for new input   
    while (Serial.available())  {
      char c = Serial.read();  //gets one byte from serial buffer
      delay(5);
      if (c == END_CMD_CHAR) { // if we the complete string has been read
        // add your code here
        break;
      }              
      else {
        if (c !=  DIV_CMD_CHAR) {
          inText += c; 
          delay(5);
        }
      }
    }
  }

  // 2) GET digitalWrite DATA FROM ARDUDROID
  if (ard_command == CMD_DIGITALWRITE){  
    if (pin_value == PIN_LOW) pin_value = LOW;
    else if (pin_value == PIN_HIGH) pin_value = HIGH;
    else return; // error in pin value. return. 
   set_digitalwrite( pin_num,  pin_value);  // Uncomment this function if you wish to use 
    return;  // return from start of loop()
  }

  // 3) GET analogWrite DATA FROM ARDUDROID
  if (ard_command == CMD_ANALOGWRITE) {  
    analogWrite(  pin_num, pin_value ); 
    // add your code here
    return;  // Done. return to loop();
  }

  // 4) SEND DATA TO ARDUDROID
  if (ard_command == CMD_READ_ARDUDROID) { 
    char send_to_android[] = "Place your text here." ;
     Serial.println(send_to_android);   // Example: Sending text
    Serial.print(" Analog 0 = "); 
    Serial.println(analogRead(A0));  // Example: Read and send Analog pin value to Arduino
    return;  // Done. return to loop();
  }
}

// 2a) select the requested pin# for DigitalWrite action
void set_digitalwrite(int pin_num, int pin_value)

{
   StatoPin_value=pin_value;
ContatoreStato=pin_num;
if (ContatoreStato <=13){ContatoreStato =0;}
 if (StatoPin_value!= StatoPin_valuePrecedente){
  if ( StatoPin_value == HIGH ) {
    ContatoreStato++;
 
  switch (pin_num) {
  case 13:
 /*  pinMode(13, OUTPUT);
    digitalWrite(13, pin_value);  
    // add your code here*/
    Serial.println (pin_num);
   Serial.println (pin_value); 
 
  setColor(255, 0, 0); // Red Color
  delay(1000);
  setColor(0, 255, 0); // Green Color
  delay(1000);
  setColor(0, 0, 255); // Blue Color
  delay(1000);
  setColor(255, 255, 255); // White Color
  delay(1000);
  setColor(170, 0, 255); // Purple Color
  delay(1000); 
    



   
    break;
  case 12:
    pinMode(12, OUTPUT);
    digitalWrite(12, pin_value);   
    // add your code here 
    Serial.println (pin_num);
   Serial.println (pin_value);       
    break;
  case 11:
    pinMode(11, OUTPUT);
    digitalWrite(11, pin_value);         
    // add your code here 
    Serial.println (pin_num);
   Serial.println (pin_value); 
    break;
  case 10:
    pinMode(10, OUTPUT);
    digitalWrite(10, pin_value);         
    // add your code here 
    Serial.println (pin_num);
   Serial.println (pin_value); 
    break;
  case 9:
    pinMode(9, OUTPUT);
    digitalWrite(9, pin_value);         
    // add your code here 
    Serial.println (pin_num);
   Serial.println (pin_value); 
    break;
  case 8:
    pinMode(8, OUTPUT);
    digitalWrite(8, pin_value);         
    // add your code here
Serial.println (pin_num);
   Serial.println (pin_value); 
    break;
  case 7:
    pinMode(7, OUTPUT);
    digitalWrite(7, pin_value);         
    // add your code here 
    break;
  case 6:
    pinMode(6, OUTPUT);
    digitalWrite(6, pin_value);         
    // add your code here 
    break;
  case 5:
    pinMode(5, OUTPUT);
    digitalWrite(5, pin_value); 
    // add your code here       
    break;
  case 4:
    pinMode(4, OUTPUT);
    digitalWrite(4, pin_value);         
    // add your code here 
    break;
  case 3:
    pinMode(3, OUTPUT);
    digitalWrite(3, pin_value);         
    // add your code here 
    break;
  case 2:
    pinMode(2, OUTPUT);
    digitalWrite(2, pin_value); 
    // add your code here       
    break;      
    // default: 
    // if nothing else matches, do the default
    // default is optional
  } 
 }
 }

}
/*void color(){
 
    
  
    setColor(255, 0, 0); // Red Color
  delay(1000);
  setColor(0, 255, 0); // Green Color
  delay(1000);
  setColor(0, 0, 255); // Blue Color
  delay(1000);
  setColor(255, 255, 255); // White Color
  delay(1000);
  setColor(170, 0, 255); // Purple Color
  delay(1000); 
  setColor(0, 0, 0); // Black Color
  delay(1000);       
  }*/
void setColor(int redValue, int greenValue, int blueValue) {
  analogWrite(redPin, redValue);
  analogWrite(greenPin, greenValue);
  analogWrite(bluePin, blueValue);
}
int pin_num;
int pin_value;

void setup() {
...
}
void loop(){
  int ard_command = 0;
  int pin_num = 0;
  int pin_value = 0
  ...

qui ora tu hai creato due variabili globali intere pin_num e pin_value e poi ne hai create altre 2 locali sempre intere con lo stesso nome all'interno del loop quindi nel tuo programma è come se non fosse cambiato nulla...

ma a me ancora sfugge che cosa vuoi ottenere dal programma esattamente?

in pratica vorrei che quando per esempio premo 13 e quindi entra nel case 13, continui a ciclare tutti i setcolor finchè non ripremo 13 e quindi uscendo da quel ciclo

Grazie