Ryd eksisterende array, når du får ny seriel kommando

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, ikke variablen, du opretter bare en ny. Du skal rydde og nulstille 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

  • Der er også brug for en null-terminator til data: Tilføj data[count]='\0'; efter dataComplete = true;
  • Ja, at ‘ er sandt, men det større problem er, at der ikke er nogen måde for afsenderen at angive afslutningen på en datatransmission andet end at sætte en pause. Og da dette er serielt, vil der være en lang nok pause mellem hvert transmitteret tegn.
  • Tak til jer begge. Min kode var forkert, og jeg ændrede den til ” count = 0 ” fungerede. Jeg tilføjede også en afgrænser for at indikere slutningen af en inputkommando, og den fungerer som beregnet nu. Den eneste måde, der arbejdede på at tømme ” data ” array var dog at bruge en for-loop som angivet af @JRobert: denne måde nyere kommandoer fungerer, selvom de er kortere end ældre.

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

Skriv et svar

Din e-mailadresse vil ikke blive publiceret. Krævede felter er markeret med *