Switch case string

come mai questo non funziona?

 String lett_port = parz.substring(4,5); 

 switch (lett_port)
  { 
    case "A":
...  
    break;

    case "B":  
...
    break;

    case "C":
...  
    break;

    case "D":
...  
    break;
    
  }

Eppure la sintassi del c++ è corretta, l'ide non contine il case con le stringhe?

mi da questo errore error: switch quantity not an integer vuole solo interi

ciao

Sì, va solo con gli interi.
Funziona se converti quel carattere in un char, perché il char è un byte di tipo signed, quindi "A" lo fai diventare 'A' (nota i singoli apici) e così il test case 'A' vale come case 65 eccc

Riprova come dice leo72, usando charAt(n)

char lett_port = parz.charAt(4);    // carattere alla posizione 4
switch (lett_port)
{ case 'A': 
  ...  
  break;
  case 'B':

Ho dovuto per forza usare il char grazie .... fatto.

Però mi nasce un altro problema, i case non sono funzioni separate a quanto pare le variabili si disturbano tra loro (diciamolo in termini terra terra)

String Dbit = parz.substring(5,6)+"0";  
  char thisChar[Dbit.length()];
  Dbit.toCharArray(thisChar, Dbit.length()) ;
  byte a = atoi(thisChar);   //trovo l'intero 
  
  char char_lett = parz.charAt(4);    // carattere alla posizione 4
  
switch (char_lett)
{ 
  case 'A': 
  byte my_port = PINA;
  byte B[] = {22,23,24,25,26,27,28,29};  //pin corrispondenti al PORT_A
  if(bitRead(PORTA, a) == 0) bitWrite(my_port, a, 1); else bitWrite(my_port, a, 0);
  if(bitRead(DDRA, a) == 0) BitChange(Port[0], my_port, B, 0); else PORTA = my_port;  
  break;
   
  case 'C': 
  byte my_port = PINC;
  byte B[] = {37,36,35,34,33,32,31,30};  //pin corrispondenti al PORT_C   
  if(bitRead(PORTC, a) == 0) bitWrite(my_port, a, 1); else bitWrite(my_port, a, 0);
  if(bitRead(DDRC, a) == 0) BitChange(Port[2], my_port, B, 2); else PORTC = my_port;
  break; 
  
  case 'D': 
  byte my_port = PIND;
  byte B[] = {21,20,19,18,99,99,99,38};  //pin corrispondenti al PORT_D
  if(bitRead(PORTD, a) == 0) bitWrite(my_port, a, 1); else bitWrite(my_port, a, 0);
  if(bitRead(DDRD, a) == 0) BitChange(Port[3], my_port, B, 3); else PORTD = my_port;
  break; 
  
  case 'G': 
  byte my_port = PING;
  byte B[] = {41,40,39,99,99,99,99,99};  //pin corrispondenti al PORT_G  
  if(bitRead(PORTG, a) == 0) bitWrite(my_port, a, 1); else bitWrite(my_port, a, 0);
  if(bitRead(DDRG, a) == 0) BitChange(Port[5], my_port, B, 5); else PORTG = my_port;
  break; 
  
  /*
  case 'E': 
  case 'H':
  ecc...*/ 
}

se li separo in singoli void l'array b[] lavora bene.
Questi byte B[] = {n,n,n,n,n,n,n,n}; dichiarati all'inizio sketch mi occuperebbero 72k messi così ne prendo 8 solo quando mi serveno
Ora chiedo è possibile usare un #define che non mi occupi la mem flash riservata alle variabili?

ciao

pablos:
Ho dovuto per forza usare il char grazie .... fatto.

Però mi nasce un altro problema, i case non sono funzioni separate a quanto pare le variabili si disturbano tra loro (diciamolo in termini terra terra)

Non ho capito.
Lo switch..case è un sostituto di una sequenza di if. Che significa "le variabili si disturbano tra loro"?

se li separo in singoli void l'array b[] lavora bene.
Questi byte B[] = {n,n,n,n,n,n,n,n}; dichiarati all'inizio sketch mi occuperebbero 72k messi così ne prendo 8 solo quando mi serveno
Ora chiedo è possibile usare un #define che non mi occupi la mem flash riservata alle variabili?

ciao

Puoi salvare i dati in Flash con PROGMEM, poi però devi usare una funzione apposita per recuperarli.
Leggi qui:
http://www.arduino.cc/en/Reference/PROGMEM
http://www.nongnu.org/avr-libc/user-manual/group__avr__pgmspace.html

Lo switch..case è un sostituto di una sequenza di if. Che significa "le variabili si disturbano tra loro"?

significa che con gli IF messi così:

if(lett_port == "C") {
  byte my_port = PINC;
  byte B[] = {37,36,35,34,33,32,31,30};   
  if(bitRead(PORTC, a) == 0) bitWrite(my_port, a, 1); else bitWrite(my_port, a, 0);
  if(bitRead(DDRC, a) == 0) BitChange(Port[2], my_port, B, 2); else PORTC = my_port;
}

if(lett_port == "D") {
  byte my_port = PIND;
  byte B[] = {21,20,19,18,99,99,99,38};
  if(bitRead(PORTD, a) == 0) bitWrite(my_port, a, 1); else bitWrite(my_port, a, 0);
  if(bitRead(DDRD, a) == 0) BitChange(Port[3], my_port, B, 3); else PORTD = my_port;
}

come vedi le variabili
byte my_port = PINn;
byte B[] = {n,n,n,n,n,n,n
sono dichiarate e distrutte dentro ciascun IF, lo switch.case invece è una funzione unica che non mi permette di ripetere la stessa variabile quindi vanno ovviamente nominate differentemente.
Perciò la domanda era:
eventuali define array viengono caricati su flash o su SRAM?
perchè su flash mi viene bene su sram no ...

Puoi salvare i dati in Flash con PROGMEM

si la conosco, ma alla fine preferisco avere uno sketch disordinato ma più veloce

grazie

pablos:
come vedi le variabili
byte my_port = PINn;
byte B[] = {n,n,n,n,n,n,n
sono dichiarate e distrutte dentro ciascun IF, lo switch.case invece è una funzione unica che non mi permette di ripetere la stessa variabile quindi vanno ovviamente nominate differentemente.

Ah, ho capito. Ti riferivi allo spazio di visibilità dei nomi.

Perciò la domanda era:
eventuali define array viengono caricati su flash o su SRAM?
perchè su flash mi viene bene su sram no ...

La #define altro non è che una direttiva per il compilatore. Gli dice di sostituire una parte del codice con un'altra, non di dove metterla.
Se definisci una costante, questa rimarrà in Flash.

Se definisci una costante, questa rimarrà in Flash.

Quindi

const float pi = 3.14; viene messa su flash
float pi = 3.14; viene messa su sram
#define MioPin 32 viene messa su flash

è corretto?

pablos:
const float pi = 3.14; viene messa su flash

No nella ram, const indica solo che è una costante e non che deve andare nella flash, per questo devi usare progmem, questo vale per avr gcc, per altri compilatori la cosa può essere diversa.

float pi = 3.14; viene messa su sram

Si.

#define MioPin 32 viene messa su flash

Ni, la #define comporta una sostituzione della word MioPin con il valore 32 direttamente nell'istruzione, p.e. "a = MioPin;" diventa "a = 32;" durante la compilazione, il vantaggio è che il codice usa un indirizzamento diretto invece di uno indiretto, ovvero meno istruzioni assembly, però non è detto che sia sempre così, tocca valutare caso per caso.

Dal manuale delle avr libc

A Note On const

Many users bring up the idea of using C's keyword const as a means of declaring data to be in Program Space. 
Doing this would be an abuse of the intended meaning of the const keyword.
Const is used to tell the compiler that the data is to be "read-only". 
It is used to help make it easier for the compiler to make certain transformations, or to help the compiler check for incorrect usage of
those variables.
For example, the const keyword is commonly used in many functions as a modifier on the parameter type.
This tells the compiler that the function will only use the parameter as read-only and will not modify the contents of the parameter variable.
Const was intended for uses such as this, not as a means to identify where the data should be stored.
If it were used as a means to define data storage, then it loses its correct meaning (changes its semantics) in other situations
such as in the function parameter example.

Pito
Grazie

x iscrizione

Vero del case/if
ti si uguaglia se metti le graffe:

switch (char_lett)
{ case 'A': 
  {  byte my_port = PINA;
     byte B[] = {22,23,24,25,26,27,28,29};  //pin corrispondenti al PORT_A
     if(bitRead(PORTA, a) == 0) bitWrite(my_port, a, 1); else bitWrite(my_port, a, 0);
     if(bitRead(DDRA, a) == 0) BitChange(Port[0], my_port, B, 0); else PORTA = my_port;  
  }
  break;

Non ci avevo pensato, racchiudendole tra graffe vengono isolate le varie funzioni .... perfetto va alla grande grazie :slight_smile:
Il discorso define e occupazione della mem è un altra faccenda, per ora va bene così

Sono cieco io oppure nella guida di riferimento
http://arduino.cc/en/Reference/SwitchCase
non c'è scritto che va solo con gli interi?

Non sarebbe meglio aggiungerlo?

yes, si dovrebbe specificare anche secondo me

Concordo. Essendo il Reference rivolto ai novizi, non si dovrebbe dare per scontato.

1 Like

leo chi ha potere di modifica sul reference ? ti puoi fare carico tu di una richiesta ufficiale di modifica ?

C'è una sezione del forum apposita dove fare le segnalazioni:
http://arduino.cc/forum/index.php/board,24.0.html

:wink: http://arduino.cc/forum/index.php/topic,160679.msg1202625.html#msg1202625

Bravo Testato, protestiamo :slight_smile:
Vogliamo lo "Switch case string"!!!! o scioperiamo!
:smiley: :smiley: