Cancella larray esistente quando si riceve un nuovo comando seriale

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

  • Inoltre è necessario un terminatore nullo per i dati: aggiungi data[count]='\0'; dopo dataComplete = true;
  • Sì, ‘ è vero, ma il problema più grande è che il mittente non ha modo di indicare la fine di una trasmissione dati diversa dalla pausa. E poiché questo è seriale, ci sarà una pausa abbastanza lunga tra ogni personaggio trasmesso.
  • Grazie a entrambi. Il mio codice era sbagliato e la modifica in ” count = 0 ” ha funzionato. Ho anche aggiunto un delimitatore per indicare la fine di un comando di input e ora funziona come previsto. Tuttavia, lunico modo che ha funzionato per svuotare larray ” data ” era utilizzare un ciclo for come indicato da @JRobert: in questo modo più recente i comandi funzionano anche se sono più brevi di quelli più vecchi.

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

Lascia un commento

Il tuo indirizzo email non sarà pubblicato. I campi obbligatori sono contrassegnati *