Încep să construiesc primul meu proiect Arduino, dar întâmpin unele probleme cu comunicarea serială.
Obțin date seriale de pe consolă și le stochez într-o matrice de caractere numită „date”.
Apoi, când trimit un nou mesaj de consolă către Arduino, vreau să șterge matricea „de date” existentă și stochează doar noile date în matricea respectivă.
Nu înțeleg exact ce e în neregulă cu codul meu: cred că acele declarații imbricate Serial.available () nu funcționează dar nu am idei despre cum să repar codul.
Datele sunt stocate corect de Arduino, dar concatenează șirul mai nou cu cel vechi.
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); }
Vă mulțumim anticipat!
Răspundeți
Pentru a șterge o matrice, veți face:
for( int i = 0; i < sizeof(data); ++i ) data[i] = (char)0;
sau
memset(data, 0, sizeof(data));
, care face același lucru folosind o funcție de bibliotecă.
Cu toate acestea, pentru că șirurile de caractere (care nu se referă la obiectele „Șir” aici) sunt terminate cu un octet zero, doar primul octet trebuie zero:
data[0] = (char)0;
o va face .
Răspuns
În primul rând, acesta este un exemplu excelent de ce contează spațiul alb. Codul dvs. este într-adevăr greu de citit așa cum este, întrucât, deasupra acestuia, pare ca al doilea, dacă instrucțiunea se află în afara primei.
Cod fix:
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); }
De asemenea, se pare că se imprimă” Comandă primită: „fiecare iterație, indiferent dacă există sau nu date noi (deși, aceasta ar putea fi caracteristica intenționată).
Așa cum am menționat, nu ștergeți variabila, doar creați una nouă. Va trebui să ștergeți și resetați count
pentru a remedia această problemă. Cu toate acestea, doar resetarea numărului nu va funcționa dacă a doua comandă este mai scurtă decât cea înainte.
De asemenea, de ce complicați codul cu variabila dataComplete
? Am simplificat codul de mai jos:
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); }
Răspuns
Probabil că nu faceți ceea ce intenționați să faceți:
Serial.println("There is data already, clearing..."); char data[30];
Rezultatul dvs. spune că ștergeți matricea data
, dar dvs. Nu faci așa ceva. De fapt, declarați o nouă variabilă locală numită data
, care este independentă de data
global deja ați declarat în partea de sus a programului dvs. Variabilele locale există numai în domeniul în care sunt declarate (în cea mai apropiată incintă { }
).
În schimb, variabila dvs. count
ține evidența numărului de date pe care le-ați primit. Așadar, faceți următoarele:
Serial.println("There is data already, clearing..."); count = 0;
Acesta nu este singurul lucru care ar putea determina programul dvs. să funcționeze în mod neașteptat, dar ar trebui cel puțin să rezolve problema enunțată în întrebarea dvs.
Comentarii
Răspuns
Pentru a vorbi la punctul întrebării și ceea ce autorul a încercat să realizeze.
Niciunul dintre aceste coduri nu funcționează de fapt ca întreg. Datele vor fi scrise și ar continua să se bucle continuu … oricum iată un exemplu de lucru al codului original.
Această metodă prefer să șterg un tablou:
for( int i = 0; i < sizeof(data); ++i ) data[i] = (char)0;
Iată un exemplu de lucru. (Asigurați-vă că selectați Carriage Return pe monitorul serial)
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; } } }
Răspuns
Am fost citite toate comentariile la această întrebare, dar toate codurile au fost partajate atât de verbal. După aceea, creez un cod cu funcții simple și mai puține linii. în acest caz, cred că acest cod va funcționa bine
dacă setați baudrate sub 115200, trebuie să fie add delay () pentru salvarea mesajului în matricea de caractere
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); }
Comentarii
-
char data[] = {};
vă va oferi o matrice de lungime zero. Încercarea de a introduce date este o idee proastă. - Sunt de acord cu @NickGammon.Vă rugăm să modificați răspunsul pentru a înlocui ” Cred că … va funcționa bine ” cu un da / nu definitiv, după ce ați testat cod.
- @ NickGammon mulțumesc pentru corectare, am fost revizuit codul meu
data[count]='\0';
dupădataComplete = true;