[Risolto] Switch case.... sto impazzendo

Buongiorno a tutti,

Sto impazzendo con un semplice "Switch Case" che non "accetta" alcuni "case".
Ho provato anche ad impostare manualmente la variabile count = 12 ad inizio loop, prima dello switch, ma non c'è verso, il case 12 non mi viene eseguito. Mi potete per favore dare una mano a risolvere?

Si tratta di giochi di luce, ecco il codice:

#include <Wire.h>

#define blu_1     2
#define red_1     3
#define green_1   4
#define blu_2     5
#define red_2     6
#define green_2   7
#define blu_3     8
#define red_3     9
#define green_3   10
#define blu_4     11
#define red_4     12
#define green_4   13

#define micro A1

int count = 0;
int ritardo = 5;
int ritardo_rotor = 100;
int ritardo_fade = 5;
int r = 0;
int g = 0;
int b = 0;

void setup() {
Serial.begin(9600);
Wire.begin(0x04); //indirizzo I2C dello Slave
Wire.onReceive(receiveEvent);
pinMode (micro, INPUT);

}

void loop() {

  Serial.println (count);
  count = 12;

  switch (count) {

            case 1:
                analogWrite (red_1, 255);
                analogWrite (green_1, 0);
                analogWrite (blu_1, 0);
                break;
            
            case 2:
            
                analogWrite (red_3, 0);
                analogWrite (green_3, 255);
                analogWrite (blu_3, 0);
                break;

            case 3:
                analogWrite (red_4, 0);
                analogWrite (green_4, 0);
                analogWrite (blu_4, 255);
                break;

            case 4:
                analogWrite (blu_1, 0);
                analogWrite (blu_2, 0);
                analogWrite (blu_3, 0);
                analogWrite (blu_4, 0);
                analogWrite (green_1, 0);
                analogWrite (green_2, 0);
                analogWrite (green_3, 0);
                analogWrite (green_4, 0);
                
                for (r=0; r<=255; r++){
                analogWrite (red_1, r);
                analogWrite (red_2, r);
                analogWrite (red_3, r);
                analogWrite (red_4, r);
                delay(ritardo_fade);
                }
                for (r=255; r>=0; r--){
                analogWrite (red_1, r);
                analogWrite (red_2, r);
                analogWrite (red_3, r);
                analogWrite (red_4, r);
                delay(ritardo_fade);
                }
                break;
            
            case 5:
                analogWrite (blu_1, 0);
                analogWrite (blu_2, 0);
                analogWrite (blu_3, 0);
                analogWrite (blu_4, 0);
                analogWrite (red_1, 0);
                analogWrite (red_2, 0);
                analogWrite (red_3, 0);
                analogWrite (red_4, 0);
                
                for (r=0; r<=255; r++){
                analogWrite (green_1, r);
                analogWrite (green_2, r);
                analogWrite (green_3, r);
                analogWrite (green_4, r);
                delay(ritardo_fade);
                }
                for (r=255; r>=0; r--){
                analogWrite (green_1, r);
                analogWrite (green_2, r);
                analogWrite (green_3, r);
                analogWrite (green_4, r);
                delay(ritardo_fade);
                }
                break;
            
            case 6:
                analogWrite (red_1, 0);
                analogWrite (red_2, 0);
                analogWrite (red_3, 0);
                analogWrite (red_4, 0);
                analogWrite (green_1, 0);
                analogWrite (green_2, 0);
                analogWrite (green_3, 0);
                analogWrite (green_4, 0);
                
                for (r=0; r<=255; r++){
                analogWrite (blu_1, r);
                analogWrite (blu_2, r);
                analogWrite (blu_3, r);
                analogWrite (blu_4, r);
                delay(ritardo_fade);
                }
                for (r=255; r>=0; r--){
                analogWrite (blu_1, r);
                analogWrite (blu_2, r);
                analogWrite (blu_3, r);
                analogWrite (blu_4, r);
                delay(ritardo_fade);
                }
                break;
            
            case 7:
                analogWrite (blu_1, 0);
                analogWrite (blu_2, 0);
                analogWrite (blu_3, 0);
                analogWrite (blu_4, 0);
                analogWrite (green_1, 0);
                analogWrite (green_2, 0);
                analogWrite (green_3, 0);
                analogWrite (green_4, 0);
                
                analogWrite (red_1, 255);
                delay(ritardo_rotor);
                analogWrite (red_1, 0);
                analogWrite (red_2, 255);
                delay(ritardo_rotor);
                analogWrite (red_2, 0);
                analogWrite (red_3, 255);
                delay(ritardo_rotor);
                analogWrite (red_3, 0);
                analogWrite (red_4, 255);
                delay(ritardo_rotor);
                analogWrite (red_4, 0);
                break;
            
            case 8:
                analogWrite (blu_1, 0);
                analogWrite (blu_2, 0);
                analogWrite (blu_3, 0);
                analogWrite (blu_4, 0);
                analogWrite (red_1, 0);
                analogWrite (red_2, 0);
                analogWrite (red_3, 0);
                analogWrite (red_4, 0);
                
                analogWrite (green_1, 255);
                delay(ritardo_rotor);
                analogWrite (green_1, 0);
                analogWrite (green_2, 255);
                delay(ritardo_rotor);
                analogWrite (green_2, 0);
                analogWrite (green_3, 255);
                delay(ritardo_rotor);
                analogWrite (green_3, 0);
                analogWrite (green_4, 255);
                delay(ritardo_rotor);
                analogWrite (green_4, 0);
                break;
            
            case 9:
                analogWrite (red_1, 0);
                analogWrite (red_2, 0);
                analogWrite (red_3, 0);
                analogWrite (red_4, 0);
                analogWrite (green_1, 0);
                analogWrite (green_2, 0);
                analogWrite (green_3, 0);
                analogWrite (green_4, 0);
                
                analogWrite (blu_1, 255);
                delay(ritardo_rotor);
                analogWrite (blu_1, 0);
                analogWrite (blu_2, 255);
                delay(ritardo_rotor);
                analogWrite (blu_2, 0);
                analogWrite (blu_3, 255);
                delay(ritardo_rotor);
                analogWrite (blu_3, 0);
                analogWrite (blu_4, 255);
                delay(ritardo_rotor);
                analogWrite (blu_4, 0);
                break;
                
            case 10:
                int sound = analogRead(micro);
                int m_sound = map(sound, 0, 1024, 0, 255);
                //Serial.println (sound);
                //Serial.println (m_sound);
                if (m_sound > 20){
                analogWrite (red_1, m_sound);
                analogWrite (red_2, m_sound);
                analogWrite (red_3, m_sound);
                analogWrite (red_4, m_sound);
                }
                else {
                analogWrite (red_1, 0);
                analogWrite (red_2, 0);
                analogWrite (red_3, 0);
                analogWrite (red_4, 0);
                }
                break;

            case 12:
                analogWrite (red_2, 255);
                break;
            }
}

 void receiveEvent(int data)
{
count = Wire.read();
}

Così ad occhio non vedo nulla che possa non far eseguire correttamente lo switch, hai provato a mettere delle Serial.print in ogni case e vedere da dove passa il programma? Magari passa per un altro case (anche se sarebbe stranissimo).
Se vedi che entra nel case 12 ma non fa quello che ti aspetti potrai concentrarti sul codice del case 12 e non sul fatto che non entra nel case giusto

Intatnto, nel IDE, con CTRL-T indenta correttamente il codice e poi inserisci all'inizio di OGNI 'case' una Serial.println("Sono nel case xx"); così, analogWrite() a parte, sei SICURO se passi o no in un 'case' e vediamo cosa succede ... ::slight_smile:

Guglielmo

Grazie innanzitutto per le risposte.
Guglielmo la formattazione automatica è fantastica, non la conoscevo!

Ho provato a mettere un Serial.print ad ogni case ed anche all'inizio del loop per sincerarmi che "count" valesse proprio 12. Incredibile, niente da fare! Mi dice che la variabile di controllo vale effettivamente 12, ma il Serial.print messo all'interno del case 12 non scrive nulla!!

Per ora ho risolto con "if" ed "else if", ma sta cosa mi turba!!

Grazie ancora

Non puoi dichiarare delle variabili all'interno dello switch/case.
Sposta sound e m_sound all'esterno e vedrai che funziona come ti aspetti.

cotestatnt:
Non puoi dichiarare delle variabili all'interno dello switch/case.
Sposta sound e m_sound all'esterno e vedrai che funziona come ti aspetti.

Fatto! Funziona!!! Avrò letto decine di articoli su Switch Case, ma questa info non l'ho mai trovata.
Grazie 1000!

Oppure il codice all'interno di un case lo racchiudi tra graffe.

cotestatnt:
Non puoi dichiarare delle variabili all'interno dello switch/case.

... che occhio, complimenti ! Non c'avevo proprio fatto caso ... :-[

Guglielmo

In teoria però dovrebbe dare errore in compilazione (e molti siti facendo ricerca parlano di errore in compilazione e risolvere mettendo fra graffe il pezzo, boh).

nid69ita:
In teoria però dovrebbe dare errore in compilazione ...

... ho provato adesso a compilarlo e, in realtà, compila, ma da una serie di warning significativi che, se l'utente li avesse notati, probabilmente avrebbe capito che qualche cosa non andava ...

/var/folders/q6/1r2cyccx60d9ckl35pk_nb980000gn/T/arduino_modified_sketch_700913/sketch_feb24b.ino: In function 'void loop()':
/var/folders/q6/1r2cyccx60d9ckl35pk_nb980000gn/T/arduino_modified_sketch_700913/sketch_feb24b.ino:228:12: warning: jump to case label [-fpermissive]
       case 12:
            ^~
/var/folders/q6/1r2cyccx60d9ckl35pk_nb980000gn/T/arduino_modified_sketch_700913/sketch_feb24b.ino:212:14: note:   crosses initialization of 'int m_sound'
          int m_sound = map ( sound, 0, 1024, 0, 255 );
              ^~~~~~~
/var/folders/q6/1r2cyccx60d9ckl35pk_nb980000gn/T/arduino_modified_sketch_700913/sketch_feb24b.ino:211:14: note:   crosses initialization of 'int sound'
          int sound = analogRead ( micro );
              ^~~~~

... anche perché gli segnalava proprio il 'case 12:' e le due dichiarazioni di variabili.

Guglielmo

Scusate, altro piccolo quesito: una volta entrato nel case, posso fare un controllo all'interno di un ciclo for per uscire qualora il case sia nel frattempo sia cambiato, senza aspettare la fine del ciclo? (ho messo questa riga, ma viene ignorata if (count != 12) break;)

Mi dite come si fa a far apparire i Warning in fase di compilazione?

Grazie!!

    case 12:
      for (r = 255; r >= 0; r = r - 10) {
        if (count != 12) break;
        analogWrite (red_1, r);
        analogWrite (red_2, r);
        analogWrite (red_3, r);
        analogWrite (red_4, r);
        analogWrite (green_1, (255 - r));
        analogWrite (green_2, (255 - r));
        analogWrite (green_3, (255 - r));
        analogWrite (green_4, (255 - r));
        delay(ritardo_psyco_2); //5

        analogWrite (red_1, 0);
        analogWrite (red_2, 0);
        analogWrite (red_3, 0);
        analogWrite (red_4, 0);
        analogWrite (green_1, 0);
        analogWrite (green_2, 0);
        analogWrite (green_3, 0);
        analogWrite (green_4, 0);
        analogWrite (blu_1, 0);
        analogWrite (blu_2, 0);
        analogWrite (blu_3, 0);
        analogWrite (blu_4, 0);
        delay(ritardo_psyco);
      }
      break;

Guarda come devono essere le impostazioni (io sono su macOS, ma su Win è uguale)...


... ti ho indicato le due più importanti, ma imposta il tutto come vedi :wink:

Guglielmo

nid69ita:
Per il break dovrebbe funzionare, ma NON dentro ad un ulteriore blocco, quindi prima di quel for

... messo come lo ha messo, se la variabile 'count' diventa diversa da 12, esce dal for ... ma non mi sembra di vedere che 'count' sia modificata all'interno di quel ciclo quindi ... ::slight_smile:

Guglielmo

gpb01:
... messo come lo ha messo, se la variabile 'count' diventa diversa da 12, esce dal for ... ma non mi sembra di vedere che 'count' sia modificata all'interno di quel ciclo quindi ... ::slight_smile:

Guglielmo

Grazie Guglielmo, ho settato le impostazioni per i warning come mi hai indicato.
In realtà il "count" viene ricevuto via I2C da un display touch screen esterno. A seconda del tasto premuto ho un codice diverso che, sulla scheda di potenza gestita da un arduino Mega, gestisce i vari giochi di colore.
Per i giochi con i cicli for, volevo però evitare di aspettare la fine del ciclo qualora nel frattempo avessi premuto un altro pulsante per far partire subito un nuovo gioco di colore...
ps. come si fa ad inserire foto nel forum? Mi chiede di inserire un link, ma da locale posso caricare?

lorenzo_1971:
ps. come si fa ad inserire foto nel forum? Mi chiede di inserire un link, ma da locale posso caricare?

le devi mettere come allegato, massimo 2MByte, dopo di che fai post e poi editi di nuovo il post per correggere dato che ... leggi QUI :wink:

Guglielmo

Ecco il progetto, che ve ne pare?
Il PCB per lo shield del Mega (doppio strato) l'ho disegnato io con EasyEDA e fatto stampare in Cina.
12 canali con Mosfet pilotati in PWM

Grazie per l'aiuto.... tutto sembra funzionare bene!! 8)

... però NON avevi fatto quanto ti ho indicato che, dopo aver allegato e fatto il post post, DEVE essere fatto. Ora ho corretto io, ma, cortesemente, per il futuro, ricordalo. Grazie. :wink:

Guglielmo

gpb01:
... però NON avevi fatto quanto ti ho indicato che, dopo aver allegato e fatto il post post, DEVE essere fatto. Ora ho corretto io, ma, cortesemente, per il futuro, ricordalo. Grazie. :wink:

Guglielmo

Ho tentato, ma non mi appariva il tag della foto [img width]... allora ho modificato la foto impostando la larghezza 500 prima di pubblicarla.

Un consiglio... per i diversi effetti luminosi secondo me ti conviene definirli in modo separato in delle funzioni che poi richiami quando servono, altrimenti fai presto a ritrovarti con uno switch/case chilometrico che poi diventa difficile da gestire/modificare.

lorenzo_1971:
Ho tentato, ma non mi appariva il tag della foto [img width]...

Devi usare il "Quick Edit" dopo aver fatto il post :wink:

Guglielmo