Sto iniziando a costruire il mio primo progetto Arduino ma riscontro alcuni problemi con la comunicazione seriale.
Ricevo dati seriali dalla console e li memorizzo in un array di caratteri chiamato “dati”.
Quindi, quando invio un nuovo messaggio di console ad Arduino, desidero che cancelli il esistente “data” array e memorizza solo i nuovi dati in quellarray.
Non capisco esattamente cosa cè di sbagliato nel mio codice: credo che quelle istruzioni Serial.available () nidificate non funzionino ma non ho idee su come correggere il codice.
I dati vengono memorizzati correttamente da Arduino ma concatena la stringa più recente a quella vecchia.
int count = 0; char data[30]; boolean dataComplete = false; void setup() { Serial.begin(9600); } void loop() { if (Serial.available() > 0){ if (dataComplete == true){ Serial.println("There is data already, clearing..."); char data[30]; dataComplete = false; } if (dataComplete == false){ Serial.println("New command, collecting..."); while (Serial.available()>0){ char character = Serial.read(); data[count] = character; count++; } dataComplete = true; } } Serial.print("Command received: "); Serial.println(data); delay(1000); }
Grazie in anticipo!
Risposta
Per cancellare un array dovresti:
for( int i = 0; i < sizeof(data); ++i ) data[i] = (char)0;
o
memset(data, 0, sizeof(data));
, che fa la stessa cosa utilizzando una funzione di libreria.
Tuttavia, poiché le stringhe di caratteri (che non si riferiscono a oggetti “String” qui) sono terminati da zero byte, solo il primo byte deve essere azzerato:
data[0] = (char)0;
lo farà .
Risposta
Prima di tutto, questo è un eccellente esempio del motivo per cui gli spazi sono importanti. Il tuo codice è davvero difficile da leggere così comè, mentre lo scorri, sembra che la seconda istruzione if sia esterna alla prima.
Codice fisso:
int count = 0; char data[30]; boolean dataComplete = false; void setup() { Serial.begin(9600); } void loop() { if (Serial.available() > 0){ if (dataComplete == true){ Serial.println("There is data already, clearing..."); char data[30]; dataComplete = false; } if (dataComplete == false){ Serial.println("New command, collecting..."); while (Serial.available()>0){ char character = Serial.read(); data[count] = character; count++; } dataComplete = true; } } Serial.print("Command received: "); Serial.println(data); delay(1000); }
Inoltre, sembra che stampi” Comando ricevuto: “ogni iterazione, indipendentemente dal fatto che ci siano nuovi dati o meno (anche se questa potrebbe essere la caratteristica prevista).
Come accennato, non azzera la variabile, ma ne crei solo una nuova. Dovrai cancellare e reimpostare count
per risolvere questo problema. Tuttavia, il solo ripristino del conteggio non funzionerà se il secondo comando è più breve di quello prima.
Inoltre, perché complichi il codice con la variabile dataComplete
? Ho semplificato il codice seguente:
int count = 0; char data[30]; boolean dataComplete = false; void setup() { Serial.begin(9600); } void loop() { if (Serial.available()){ Serial.println("New command, collecting..."); count = 0; data[] = ""; while (Serial.available()){ char character = Serial.read(); data[count] = character; count++; } } Serial.print("Command received: "); Serial.println(data); delay(1000); }
Risposta
Probabilmente non “t fai quello che intendi fare:
Serial.println("There is data already, clearing..."); char data[30];
Il tuo output dice che stai cancellando larray data
, ma tu “Non stai facendo niente del genere. In effetti, stai dichiarando una nuova variabile locale chiamata data
, che è indipendente dalla data
hai già dichiarato allinizio del tuo programma. Le variabili locali esistono solo nellambito in cui sono dichiarate (allinterno del loro { }
che lo racchiude più vicino).
Invece, la tua variabile count
tiene traccia della quantità di dati che hai ricevuto. Quindi forse fai quanto segue:
Serial.println("There is data already, clearing..."); count = 0;
Questa non è lunica cosa che potrebbe far funzionare il tuo programma in modo imprevisto, ma dovrebbe almeno risolvere il problema indicato in la tua domanda.
Commenti
Rispondi
Per parlare fino al punto della domanda e ciò che lautore stava tentando di realizzare.
Nessuno di questo codice funziona effettivamente nel suo insieme. I dati verrebbero sovrascritti e continuerebbero a scorrere continuamente … comunque ecco un esempio funzionante del codice originale.
Questo metodo preferisco cancellare un array:
for( int i = 0; i < sizeof(data); ++i ) data[i] = (char)0;
Ecco un esempio funzionante. (Assicurati di selezionare Ritorno a capo sul monitor seriale)
char message[32]; uint8_t incomingByte = 0; uint8_t BufferPos = 0; int clearbyte = 0; void setup() { Serial.begin(9600); Serial.println("\n String conversion testing"); } void loop() { if (BufferPos >= 32) { Serial.print("Buffer Full\n"); BufferPos = 00; incomingByte = 0; } if (Serial.available()) { incomingByte = Serial.read(); message[BufferPos++]= incomingByte; switch(incomingByte) { case "\n": case " ": break; case "\r": Serial.println(message); for( int i = 0; i < sizeof(message); ++i ) message[i] = (char)0; BufferPos= 0; incomingByte= 0; } } }
Risposta
Ho letto tutti i commenti su questa domanda, ma tutti i codici erano condivisi in modo così prolisso. Dopodiché, creo un codice con funzioni semplici e meno righe. in questo caso, penso che questo codice funzionerà bene
se imposti il baudrate sotto 115200, devi aggiungere delay () per salvare il messaggio nellarray di caratteri
void loop() { char data[255]; uint8_t k = 0; while (Serial.available()) { data[k] = Serial.read(); k++; } for (int i = 0; i < k; i++) { Serial.print(data[i]); data [i] = "\0"; } //delay(50); }
Commenti
-
char data[] = {};
ti fornirà un array di lunghezza zero. Cercare di inserirvi dei dati è una cattiva idea. - Sono daccordo con @NickGammon.Modifica la tua risposta per sostituire ” Penso che … funzionerà bene ” con un sì / no definitivo, dopo aver testato il codice.
- @NickGammon grazie per la correzione, stavo revisionando il mio codice
data[count]='\0';
dopodataComplete = true;