Convertire il valore di una stringa in nome variabile

Ciao,
c'è modo di 'convertire' il valore di una stringa nel nome di una variabile?'
Mi spiego meglio, mi arriva una stringa di richiesta, ad esempio Richiesta = 'OrarioAvvio' il suo valore ovvero 'OrarioAvvio' corrisponde ad una mia variabile, di cui dovrei restituire il valore, c'è modo di fare questa associazione?
Probabilmente sostituendo i valori della stringa con dei numeri potrei facilmente risolvere con un array, ma mi farebbe comodo mantenerne i nomi.

Grazie

bye bye

Non mi risulta, il nome di una variabile è una cosa simbolica che viene eliminata a livello compilazione e trasformata in un indirizzo fisico.

Quello che però puoi fare sono due array di pari lunghezza ...

  1. il primo, di tipo char array, conterrà delle stringhe classiche del 'C', in cui metterai il 'nome simbolico della variabile' così come lo scrivi nel sorgente.
  2. il secondo, che riempirai all'avvio, dovrà contenere, nello stesso ordine i puntatori alle variabili.

Quando ricevi una richiesta, vai a cercare il nome simbolico nel primo array, una voltra trovato hai l'indice con cui andare a recuperare nel secondo array il pointer alla variabile e quindi recuperarne il valore.

Guglielmo

...magari sbaglio...non si potrebbe fare con le JSON (aJSON)!?

ORSO2001:
...magari sbaglio...non si potrebbe fare con le JSON (aJSON)!?

Ovvero ? Come risali dal nome simbolico che una variabile aveva nel sorgente al suo indirizzo fisico (in SRAM) che ha nel compilato ?

Guglielmo

di seguito un esempio della libreria aJSON che ho un po’ modificato…si parte con una “struttura” predefinata ( a noi interessa il valore di “sensor”)…se da seriale digito una prima volta “sensor” (con fine linea abilitato) mi ritorna “gps”…se digito una seconda volta mi torna “gps2” in quanto l’ho modificato al primo giro…

#include <ArduinoJson.h>
char tipo[7];
StaticJsonBuffer<200> jsonBuffer;
char json[] =
  "{\"sensor\":\"gps\",\"time\":1351824120,\"data\":[48.756080,2.302038]}";
JsonObject& root = jsonBuffer.parseObject(json);

int index;
boolean op;


void setup() {
  index = 0;
  op = false;
  Serial.begin(9600);
}

void loop() {
  if (Serial.available()) {
    char c = Serial.read();
    if (c != '\n') {
      tipo[index] = c;
      index++;
    }
    if (c == '\n') {
      op = true;
      index = 0;
    }
  }
  if (op) {
    char* scrivi = root[tipo];
    Serial.println(scrivi);
    op = false;
    root["sensor"]="gps2";
  }
}

E allora ?

... a lui serve, ricevuto "pippo" dalla seriale, andare a recuperare il valore della variabile che nel sorgente si chiamava "pippo" (e che si trova all'indirizzo di memoria 0xnnnn) e restituirlo, se invece riceve "pluto" deve andare a recuperare il valore della variabile che nel sorgente aveva chiamato "pluto" (e che si trova all'indirizzo di memoria 0xmmmm) e ritornare quello, e così via.

Come la fai questa cosa con un parser JSON ? ? ?

Guglielmo

magari ho capito male...ma se alcune variabili (quelle interessate al recupero informazioni) le gestisce come JSON...quindi invece di:

int data1 = 3;

int data2 = data1*2;

Serial.print(data2); // che da 6

potrebbe fare, considerando l'oggetto JSON come root,:

char json[] = "{\"data1\":[3]}";

int data2 = int(root["data1"])*2;

Serial.println(data2);  // da sempre 6

così, se vuole, può recuperare il valore di data1
e data1 è aggiornabile...a lui il controllo.
ripeto...magari sbaglio.

Cioè tu proponi di mettere tutte le variabili in una struttura JSON (char array) e di gestire tale struttura ...
... però così non può usare direttamente le variabili, ma deve ogni volta decodificarle e duplicarle in una vera variabile numerica di lavoro.

E' sicuramete un'opzione possibile, ma ... è anche una bella complicazione oltre ad un notevole spreco di spazio ...
... con i due array che gli ho suggerito all'inizio ha un accesso diretto alle 'vere' variabili in memoria :wink:

Naturlamnete ... al OP lo scegliere poi la strada che gli è più facile :slight_smile:

Guglielmo

è anche una bella complicazione

...dalla serie: la vita non è facile! :smiley:

...con i due array che gli ho suggerito all'inizio ha un accesso diretto alle 'vere' variabili in memoria

sicuramente...volevo dare un'alternativa.

ORSO2001:
sicuramente...volevo dare un'alternativa.

Certamente :slight_smile:
... come detto, al OP scegliere la strada che più gli sembra facile in base alla sua preparazione :wink:

Guglielmo

Grazie ad entrambi :slight_smile:
Mi piace più la soluzione di Guglielmo, la trovo meno complessa, ora proverò a metterla in pratica :wink:
In verità ci sarebbe un'altra piccola complicazione per questa soluzione, ovvero che le mie variabili da restituire non sono tutte dello stesso tipo ma int, string, boolean ma vedrò di uniformarle per poterle inserire nello stesso array

bye bye

E perché mai ? ? ? :o :o :o

Come array usi un void pointer e poi fai il 'dereferencing', con il giusto cast, quando lo assegni :wink:

Esempo:

void setup() {
   void * pippo[10];
   int a, a1;
   long b, b1;
   char c, c1;
   //
   a = 1; a1 = 0;
   b = 2; b1 = 0;
   c = 'a'; c1 = ' ';
   //
   pippo[0] = &a;
   pippo[1] = &b;
   pippo[2] = &c;
   //
   a1 = *((int*)pippo[0]);
   b1 = *((long*)pippo[1]);
   c1 = *((char*)pippo[2]);
   //
   Serial.begin(9600);
   Serial.print("a= ");
   Serial.print(a);
   Serial.print(" - a1= ");
   Serial.println(a1);
   Serial.print("b= ");
   Serial.print(b);
   Serial.print(" - b1= ");
   Serial.println(b1);
   Serial.print("c= ");
   Serial.print(c);
   Serial.print(" - c1= ");
   Serial.println(c1);
}

void loop() {

}

Guglielmo

A parte i suggerimenti avuti, che sono soluzioni interessanti e non basilari. Io avrei risolto con la soluzione più semplice ma anche più “naturale”, in base alla stringa ricevuta la valuto con una serie di if e else if, e in base al suo valore restituisco il contenuto di una variabile specifica.
Io penso che tu non abbia necessità effettiva di fare quello che vorresti :slight_smile:

E perché mai ? ? ? :o :o :o

Come array usi un void pointer e poi fai il 'dereferencing', con il giusto cast, quando lo assegni :wink:

Tanto sempre un byte per volta viene spedito, questa è la soluzione artigianale meno sofisticata di frequente uso.

Io come al solito la faccio sempre complicata, perché a me capitano le cose complicate.

La cosa fattibile è questa (in alternativa).

I dati sono collezionati all'interno di una struttura (struct) quindi la collezione può essere eterogenea. Se il ricevente non conosce la composizione (cioè il numero di membri e il tipo di questi) prima di comunicare, il ricevente deve chiedere un header, (il quale sarebbe la descrizione della struttura dati) il trasmittente risponde a questa richiesta spedendo l'header,
se nessun errore si è verificato i due si sono messi in accordo, e possono trasmettersi byte dopo byte con il sistema spiegato da Guglielmo. Io invece ho fatto diversamente, il mio header è composto dai indirizzi di memoria:chiave, il ricevente allora quando vuole sapere il valore di una variabile qualsiasi, dalla chiave, risale all'indirizzo, poi fa una richiesta di accesso in lettura e piu poi spedisce un intero senza segno, che tu casti a puntatore.

Chi ha fatto la richiesta deve conoscere che a quella specifica chiave corrisponde una variabile di tipo float, in questo caso per ricavare il dato dovrà inviare 4 indirizzi di memoria e dopo ognuno sarà inviato un byte.

Insomma non è così banale, ma è rapido, flessibile, dinamico e quasi quasi non ha alcun difetto.