Buona sera , avrei bisogno di aiuto per saper come condividere una variabile tipo String , generata in loop , in una routine tipo VOID() richiamata sempre dal LOOP() .
Tutti i tentativi mi portano ad un annullamento della variabile nel VOID() .
Ti segnalo che, nella sezione in lingua Inglese, si può scrivere SOLO in Inglese ... quindi, per favore, la prossima volta presta più attenzione in quale sezione metti i tuoi post; questa volta esso è stato spostato, da un moderatore della sezione di lingua Inglese, nella sezione di lingua Italiana ... la prossima volta potrebbe venire direttamente eliminato.
Grazie.
Se dichiari una variabile all'interno di una funzione essa diventa una variabile "locale" e quindi visibile solo all'interno della funzione. Se ti serve che una variabile sia accessibile il lettura/scrittura da più funzioni, allora il modo più semplice è utilizzare le variabili "globali", ovvero dichiarate esternamente alle funzioni (es. prima del setup()) che sono visibili ovunque.
Guglielmo
Premesso che nel C/C++ le routine non esistono, ma si parla sempre e soltanto di funzioni,
puoi passare il riferimento alla tua variabile String come argomento della funzione.
void loop() {
String myStrVar = "Sono un oggetto di tipo String";
miaFunzione(myStrVar);
}
// Al fine di evitare inutili duplicazioni in SRAM,
// passo l'argomento per riferimento (puntatore ad oggetto di classe String)
void miaFunzione( String& myStr) {
Serial.println(myStr);
}
Grazie , ma cosi la funzione void miaFunzione(string) gestisce una sola variabile mentre quelle generate in loop() sono di più. Come faccio a trasferirle ? Non posso dichiarare le variabili in modo globale perché queste vengono elaborate durante il loop() .
Beh, oltre al consiglio di Guglielmo (che penso sia "la" soluzione) ho la curiosità di capire perché tu debba usare variabili di tipo "String" (con la "S" maiuscola) che generalmente su Arduino (soprattutto per UNO) sono deprecate in quanto potenzialmente letali per il codice per via dell'allocazione di memoria non ottimizzata. In genere si preferisce usare le più semplici "stringhe C" ossia "array di char".
Facci quindi sapere se l'uso delle "String" sia in qualche modo per te necessario o meno, e magari posta anche un esempio del tuo codice così capiamo meglio l'ambito.
Ciao, facci vedere un esempio di codice.
Perché l'affermazione "non posso dichiarare le variabili globali..." suona proprio strano.
Ciao.
Non mi è chiaro il senso di questa cosa. Possono esistere decine di variabili globali, anche degli array e strutture, quindi che vengano "elaborate" durante il loop non è significativo.
Come scrivevo prima, posta il tuo codice così capiamo meglio.
A parte quanto già detto dagli altri sulle variabili globali che sottoscrivo, ad una funzione puoi passare quanto argomenti vuoi. Basta definirli.
Ad ogni modo mi sa che qui sono necessari i soliti link (che non ricordo mai dove sono.... ) sul come e dove iniziare con lo studio
Io potrei ipotizzare che si tratti di variabili "stringhe di C" create a run-time dalla loop perché a run- time è disponibile la loro lunghezza
Nel caso dichiarerei un puntatore globale e lo punterei alla variabile nella loop
per cortesia mi potresti fare un esempio ?
Meglio se ci fai tu un esempio del tuo codice, almeno possiamo darti consigli più precisi non ti pare?
Intendi da me?
int SECRETCHANNEL;
int CO2acqua;
String sc ;
String Caq ;
String f_coa;
String channel;
void setup() {
Serial.begin(9600);
Serial.println("");
Serial.println(" SELEZIONE AMBIENTE a-z");
Serial.println("------------------------------------------");
Serial.println("");
Serial.println("a");
}
void loop() {
int inByte = Serial.read();
switch (inByte) {
case 'a':
Serial.println("You selected a");
SECRETCHANNEL= 2210816;
CO2acqua=6;
sc = String (SECRETCHANNEL);
channel=("channel")+sc;
Caq = String (CO2acqua);
String f_coa=("field")+Caq;
break;
}
analisi_pippo ();
}
void analisi_pippo() {
Serial.print("field numero ");Serial.println(f_coa);
Serial.print("channel ");Serial.println(channel);
}
ecco il codice . avrei bisogno che le variabili string generate nel loop , "passino" nella funzione void pippo e vengano visualizzate .
vi ringrazio
Il primo errore è l'uso di oggetti String
Ma per il momento facciamo finta che vada bene, quando avrai problemi capirai da te perchè non dovevi usarli
Per quanto riguarda le variabili, facciamo scommessa che channel passa e f_coa no?
Se guardi alla diversa maniera di come le usi nella loop capisci
ciao,
dal programma si capisce che c'è un po' di confusione sul concetto di "visibilità" delle variabili...e delle grandezze che possono gestire.
int SECRETCHANNEL;
SECRETCHANNEL= 2210816;
gli int in arduino sono a 16 bit...quindi...valori da -32768 a 32767...valori maggiormenti negativi o positivi vanno in overflow...
A quanto giustamente ti ha segnalato @Salvorhardin (occhio che i consigli implicano anche che tu debba capirli, nel caso chiedi...) aggiungo anche un paio di cose.
Primo, indenta correttamente il codice. Questo non è un aspetto secondario perché rende il codice più leggibile a te stesso in primis, ma anche per noi. E questa cosa risulterà sempre più utile/necessaria al crescere della lunghezza del codice, fidati. Nell'IDE premi Ctrl-T e te lo fa lui. Inoltre evita di aggiungere inutili righe vuote soprattutto se multiple perché rendono il codice inutilmente lungo e quindi meno leggibile: per separare blocchi di codice (e farlo solo dove serve) ne basta uno solo.
Secondo, per leggere da seriale dovresti prima verificare se ci sono caratteri da leggere, quindi usando Serial.available. Ad esempio:
void loop() {
if (Serial.available())
{
int inByte = Serial.read();
switch (inByte) {
case 'a':
...
Terzo, nell'interazione seriale ricorda che il Serial Monitor per default invia i caratteri quando premi "Invio". Quindi ti conviene attendere che arrivi il carattere '\n' accumulando in una stringa i caratteri man mano ricevuti (ed ignorando l'eventuale carattere '\r').
Quarto, per convenzione si usano identificativi tutti in maiuscolo solamente per le costanti, e "SECRETCHANNEL" ad esempio non lo è (anzi, cerchi di assegnargli un valore che non può avere, ma lo vedremo in seguito).
Fai queste modifiche, oltre a cercare di capire i suggerimenti di Salvorhardin, ed in caso di difficoltà posta il "nuovo" codice (unitamente alla descrizione dell'eventuale mancato funzionamento...). E ti consiglio anche di studiare le "stringhe C" (o "char array") per sostituire le "String" che ti ha evidenziato.
f_coa è ridefinita come variabile locale nella funzione loop(), mentre un'altra funzione vede quella globale.
String f_coa;
void loop() {
// ...
String f_coa=("field")+Caq;
// ...
}
Ah, sì, addirittura tra le parentesi di uno switch (blocco di codice):
http://www.pluto.it/files/ildp/guide/abs/localvar.html
void loop() {
int inByte = Serial.read();
switch (inByte) {
case 'a':
Serial.println("You selected a");
SECRETCHANNEL = 2210816;
CO2acqua = 6;
sc = String (SECRETCHANNEL);
channel = ("channel") + sc;
Caq = String (CO2acqua);
String f_coa = ("field") + Caq;
break;
} // end switch
analisi_pippo ();
}
Il codice così formattato rende subito evidente che f_coa è dichiarata dentro il case e non si può fare. Se è proprio necessario dichiarare variabili dentro i case è necessario racchiudere il case dentro un blocco di codice. Per creare un blocco di codice si usano le graffe { // questo è un blocco di codice }. Le variabili dichiarate all'interno di un blocco di codice esistono solo dentro il blocco in cui sono state dichiarate, ad esempio anche se scrivessi:
switch (inByte) {
case 'a': { // apre blocco di codice
Serial.println("You selected a");
SECRETCHANNEL = 2210816;
CO2acqua = 6;
sc = String (SECRETCHANNEL);
channel = ("channel") + sc;
Caq = String (CO2acqua);
String f_coa = ("field") + Caq;
// analisi_pippo(f_coa); // [1] questo funziona (vedi post #4)
break;
} // chiude blocco di codice
} // end switch
analisi_pippo (); // qui **f_coa** non esiste
Sembra che l'intenzione sia di creare delle variabili temporanee come ad esempio f_coa. Le variabili temporanee però devono essere usate all'interno del blocco di codice in cui sono dichiarate, per cui la chiamata a analisi_pippo(String &myStr) dovrà essere fatta all'interno del blocco di codice, vedi [1].
Se queste variabili temporanee sono tante allora potrebbe essere conveniente dichiarare dei puntatori globali, ma questo lo vediamo dopo se necessario.
PS: applica anche tutti gli altri suggerimenti, tranne Serial.available() che in questo caso non è necessaria e non comporta alcun problema.
Inoltre come segnala @Datman ci sono due variabili con lo stesso nome, una globale e l'altra locale. A questo punto usa la variabile globale f_coa e non dichiararne un'altra con lo stesso nome ma locale, in questo modo non c'è la necessità di passare la variabile come argomento alla funzione analisi_pippo().
Ciao.
In questo caso si, ma dato che suggerivo di utilizzare un buffer per accumulare i comandi (separati da \r\n) si, che serve...