Go Down

Topic: Modificare serie di if ... in case (Read 1 time) previous topic - next topic

ziopippo

Salve ragazzi.
Ho una serie di if del tipo:
Code: [Select]

if (readString.startsWith("GET /?out=0&status=1"))
...

if (readString.startsWith("GET /?out=19&status=1"))

...
...

vorrei sostituirli con un case

ed ho provato in questo modo:
Code: [Select]

char *Sensore; //definisco la variabile per leggere il sensore con JSon


  Sensore = (readString.startsWith(""));
  switch (Sensore)
  {
    case ("GET /?out=0&value="):
    Serial.println ("Apertura comandata");
    break;

    case ("GET /?out=0&status=1"):
    Serial.println ("Leggo apertura tenda");
    break;

    case ("GET /?out=19&status=1"):
    Serial.println ("Leggo potena Kwh");
    break;

     case ("GET /?out=AllTemp"):
    Serial.println ("Leggo le temperature");
    break;

    case ("GET /?out=all"):
    Serial.println ("Stampo i nomi dei sensori");
    break;

     case ("GET /?out=22&status=1"):
    Serial.println ("Alzo la tenda");
    break;

     case ("GET /?out=23&status=1"):
    Serial.println ("Abbasso la tenda");
    break;
  }


Nella compilazione però mi da errore "cannot convert 'String' to 'char*' in assignment". Ovviamente non ho capito bene come leggere questa stringa.
Chi mi illumina?

gpb01

#1
Mar 09, 2018, 07:23 pm Last Edit: Mar 09, 2018, 07:23 pm by gpb01
Guarda che senza aprire un nuovo thrad, potevi tranquillamente correggere quello che avevi già scritto sistemandolo utilizzando il bottone More -> Modify che si trova in basso a destra dei post.

La prossima volta tienilo presente. Grazie.

Guglielmo


Search is Your friend ... or I am Your enemy !

ORSO2001

ciao,

lo switch analizza/considera solo numeri interi (1,2,3 etc)...quindi int, char, byte (no float, no String...salvo fare dei cast o analizzarli con funzioni che ritornano interi); il singolo case invece necessita di "costanti"...quindi numeri (literals) 1 o 2 o 3 etc...o lettere (char) 'a' o 'b' ...od a delle costanti : enumeratori, #define, const...

spero di essermi spiegato.

ziopippo

Deduco quindi che non è fattibile nel mio caso sostituire gli IF con il case.
Se così fosse non capisco il perché mi sia stato consigliato.
Sono ancora più confuso di prima. :s

ORSO2001

ciao,

puoi usare lo switch case...anche se stai maneggiando delle String...dipende da come lo imposti...non ho capito se stai utilizzando String "semplici" oppure delle JSON...per ogni una di queste hai metodi specifici per ottenere "interi" o stati e poterli confrontare.

per esempio...se stai utilizzando Sting "semplici" uno switch case così è accettato:
Code: [Select]
String a = "10";
String b = "11";

void setup() {
  Serial.begin(9600);

  switch (a.toInt()) {
    case 10:
      Serial.println("ciao");
      break;
  }
  switch (b.toInt()) {
    case 11:
      Serial.println("bella");
      break;
  }
}
void loop() {
}


per la JSON dovresti includere l'apposita libreria in arduino e vederti i modi per estrapolare i dati..

ziopippo

ciao,

puoi usare lo switch case...anche se stai maneggiando delle String...dipende da come lo imposti...non ho capito se stai utilizzando String "semplici" oppure delle JSON...per ogni una di queste hai metodi specifici per ottenere "interi" o stati e poterli confrontare.

per esempio...se stai utilizzando Sting "semplici" uno switch case così è accettato:
Code: [Select]
String a = "10";
String b = "11";

void setup() {
  Serial.begin(9600);

  switch (a.toInt()) {
    case 10:
      Serial.println("ciao");
      break;
  }
  switch (b.toInt()) {
    case 11:
      Serial.println("bella");
      break;
  }
}
void loop() {
}


per la JSON dovresti includere l'apposita libreria in arduino e vederti i modi per estrapolare i dati..
Purtroppo sono tutte richieste JSON

ORSO2001

ciao,

ammetto la poca esperienza con le JSON ma questa:
Quote
"GET /?out=23&status=1"
non mi sembra tanto un formato JSON...mi sembra piuttosto una String che va interpretata.
Un esempio di JSON, per arduino, potrebbe essere:
Quote
"{\"sensor\":\"gps\",\"time\":1351824120,\"data\":[48.756080,2.302038]}"
dove hai una chiave "sensor" che contiene una String; una chiave "time" che contiene una long; ed una chiave "data" che contiene un array di float/double.

ziopippo

Anche la mia esperienza dello Json è prossima allo zero.
Il mio è un codice trovato in rete e riadattato alle mie esigenze.
In ogni caso le mie chiavi sarebbero "out" "status" e "valute"
Nella notte mi è venuta una mezza idea grazie ad uno dei tuoi primi interventi. Appena mi è possibile faccio una prova poi ti aggiorno.

Silente

Comunque sia esiste, e conosci, un modo per confrontare due elementi come quelli. Di conseguenza esiste una soluzione brutale brutale ma efficace:
1)crei un array di quelli elementi contenente in un ordine stabilito tutte le opzioni del programma (gli elementi con i quali confronti il risultato della funzione)
2) scrivi una funzione che, attraverso una for(), legga l'array e lo confronti con il risultato della funzione e, se e quando li trova uguali, restituisca il nunero successivo dell'indice dell'array con il quale ha riscontrato l'ugualglianza. Se non la riscontra restituisce 0.
3) esegui una switch case in base al risultato della funzione che hai creato.

Capito o devo rispiegare?
Dove va un numero va una variabile, una funzione e/o  un test.
Per ottenere devi spiegare

Strumenti/Formattazione automatica fino alla morte!
Cristianesimo:bibbia='C':K&R

gpb01

#9
Mar 10, 2018, 10:34 am Last Edit: Mar 10, 2018, 10:35 am by gpb01
... come al solito si reinventa l'aqua calda ... esiste, moooolto più efficiente, l'apposita funzione in AVR libc (... che è SEMPRE inclusa dall'IDE di Arduino), in string.h, che si chiama memcmp() che permette di fare il confronto di due array di qualsiasi tipo (... o comunque due qualsiasi zone di memoria) ;)

Guglielmo
Search is Your friend ... or I am Your enemy !

ziopippo

In realtà mi era venuta in mente una cosa più semplice e cioè quella di assegnare una costante numerica ad ogni IF e di confrontarla con il case.
Spero di aver reso l'idea della mia folle soluzione...

nid69ita

#11
Mar 10, 2018, 12:32 pm Last Edit: Mar 10, 2018, 12:33 pm by nid69ita
In realtà mi era venuta in mente una cosa più semplice e cioè quella di assegnare una costante numerica ad ogni IF e di confrontarla con il case.
Spero di aver reso l'idea della mia folle soluzione...
No, l'idea non è folle affatto.
La "follia" per me è usare la libreria String (classe String) e non le classiche stringhe (array di char) del C, che come scrive qui sopra @Guglielmo hanno già di loro utili funzioni di confronto.
E' noto che la libreria/classe String usa allocazione dinamica che su una MCU con solo 2Kb di SRAM può dare problemi (micro frammentazione della memoria a causa di alloca/dealloca pezzetti di memoria)
my name is IGOR, not AIGOR

SukkoPera

#12
Mar 10, 2018, 12:33 pm Last Edit: Mar 10, 2018, 12:34 pm by SukkoPera
La cosa più corretta, secondo me, sarebbe estrarre l'ID numerico dalla stringa e poi fare switch. Qualcosa tipo:
Code: [Select]
const char* s = "GET /?out=19&status=1";

int n = 0;  // Alla fine qui ci sarà l'ID estratto
char* p = strstr_P (s, PSTR("?out="));
if (p != NULL) {
  p += 5;
  while (isdigit (*p)) {
    n = n * 10 + *p++ - '\0';
  }
}



Scritto al volo, chissà se funziona...
"Code is read much more often than it is written, so plan accordingly. Design for readability."

Guida rapida a ESP8266: https://goo.gl/kzh62E

ziopippo

Igor grazie per la risposta ma come ho già scritto quello è un codice trovato in rete che faceva ciò che voglio (ovvero rispondere a delle richieste via http da browser o da una app che ho creato ad hoc per android visualizzando alcune temperature o eccitando alcuni relè) e che poi ho riadattato secondo le mie esigenze.
Ho fatto già fatica all'inizio a capirne il funzionamento e sinceramente per adottare il consiglio di Guglielmo non saprei nemmeno da dove iniziare.
Per altre esigenze avevo già condiviso il mio codice su questo forum e qualcuno per velocizzare e snellire le rispote mi ha suggerito di usare il case al posto dei molteplici IF. Pensavo fosse però più indolore... :(

nid69ita

#14
Mar 10, 2018, 12:47 pm Last Edit: Mar 10, 2018, 12:48 pm by nid69ita
Certo lo switch aiuta ma devi fare come suggerisce @sukko appena prima

Solo che @sukko,  non ci sono solo casi con numero ma anche "GET /?out=AllTemp"
un pò complicate le casistiche
my name is IGOR, not AIGOR

Go Up