Jeg begynder at bygge mit første Arduino-projekt, men jeg løber ind i nogle problemer med seriel kommunikation.
Jeg får serielle data fra konsollen og gemmer dem i en char-array kaldet “data”.
Så når jeg sender en ny konsolbesked til Arduino, vil jeg have den til at rydde eksisterende “data” array og kun gemme de nye data i det array.
Jeg forstår ikke nøjagtigt, hvad der er galt med min kode: Jeg tror, at de indlejrede Serial.available () udsagn ikke fungerer men jeg har ingen ideer til, hvordan man løser koden.
Data gemmes korrekt af Arduino, men det sammenkæder den nyere streng til den gamle.
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); }
På forhånd tak!
Svar
For at rydde et array skal du gøre:
for( int i = 0; i < sizeof(data); ++i ) data[i] = (char)0;
eller
memset(data, 0, sizeof(data));
, hvilket gør det samme ved hjælp af en biblioteksfunktion.
Dog fordi strenge af tegn (der ikke henvises til “String” -objekter her) afsluttes med en nulbyte, kun den første byte skal nulstilles:
data[0] = (char)0;
vil gøre det .
Svar
Først og fremmest er dette et fremragende eksempel på, at hvidt mellemrum betyder noget. Din kode er virkelig svær at læse, som den er, da den skumrer over den, virker den som den anden, hvis udsagnet ligger uden for den første.
Fast kode:
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); }
Det ser også ud til, at den udskriver” Kommando modtaget: “hver iteration, uanset om der er nye data eller ej (selv om dette kunne være den tilsigtede funktion).
Som nævnt, count
for at løse dette problem. Bare nulstilling af antal tæller ikke, hvis den anden kommando er kortere end den før.
Hvorfor komplicerer du også koden med variablen dataComplete
? Jeg forenklede koden nedenfor:
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); }
Svar
Dette gør sandsynligvis ikke “t gør hvad du vil:
Serial.println("There is data already, clearing..."); char data[30];
Din output siger, at du rydder data
-arrayet, men du “gør ikke sådan noget. Faktisk erklærer du en ny lokal variabel kaldet data
, som er uafhængig af den globale data
dig allerede har erklæret øverst i dit program. Lokale variabler findes kun inden for det omfang, hvori de erklæres (inden for deres nærmeste vedhæftede { }
).
I stedet holder din count
variabel styr på, hvor mange data du har modtaget. Så gør måske følgende:
Serial.println("There is data already, clearing..."); count = 0;
Dette er ikke det eneste, der kan få dit program til at fungere uventet, men det skal i det mindste løse det problem, der er angivet i dit spørgsmål.
Kommentarer
Svar
At tale til punktet i spørgsmålet , og hvad forfatteren forsøgte at opnå.
Ingen af denne kode fungerer faktisk som en helhed. Dataene vil blive overskrevet og bare fortsætte med at løbe løbende … alligevel er her et fungerende eksempel på den originale kode.
Denne metode foretrækker jeg at rydde et array:
for( int i = 0; i < sizeof(data); ++i ) data[i] = (char)0;
Her er et arbejdseksempel. (Sørg for at vælge Carriage Return på den serielle skærm)
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; } } }
Svar
Jeg blev læst alle kommentarer til dette spørgsmål, men alle koder var delte så ordlyd. Derefter opretter jeg en kode med enkle funktioner og mindre linje. i dette tilfælde tror jeg, at denne kode fungerer fint
hvis du indstiller baudrate under 115200, skal du tilføje forsinkelse () for at gemme besked i char array
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); }
Kommentarer
-
char data[] = {};
giver dig et array med nul længde. Det er en dårlig idé at prøve at lægge data i det. - Jeg er enig med @NickGammon.Rediger dit svar for at erstatte ” Jeg tror … vil fungere fint ” med et definitivt ja / nej, når du først har testet kode.
- @NickGammon tak for rettelsen, jeg var ved at revidere min kode
data[count]='\0';
efterdataComplete = true;