Fjern eksisterende matriser når du får ny seriell kommando

Jeg begynner å bygge mitt første Arduino-prosjekt, men jeg får problemer med seriell kommunikasjon.

Jeg får seriedata fra konsollen og lagrer den i en char-array kalt «data».

Så når jeg sender en ny konsollmelding til Arduino, vil jeg at den skal fjerne eksisterende «data» -matrise og lagrer bare de nye dataene i den matrisen.

Jeg forstår ikke nøyaktig hva som er galt med koden min: Jeg tror de nestede Serial.available () -uttalelsene ikke fungerer men jeg har ingen ideer om hvordan jeg skal fikse koden.

Data er riktig lagret av Arduino, men de sammenkobler den nyere strengen 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 takk!

Svar

For å tømme en matrise vil du gjøre:

for( int i = 0; i < sizeof(data); ++i ) data[i] = (char)0; 

eller

memset(data, 0, sizeof(data)); 

, som gjør det samme ved hjelp av en biblioteksfunksjon.

Imidlertid fordi strenger av tegn (refererer ikke til «String» -objekter her) avsluttes med null byte, bare den første byten må nullstilles:

data[0] = (char)0; 

vil gjøre det .

Svar

Først og fremst er dette et utmerket eksempel på hvorfor mellomrom betyr noe. Koden din er veldig vanskelig å lese som den er, da den skumrer over den, virker den som den andre om utsagnet er utenfor 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 virker også som om det skrives ut» Kommando mottatt: «hver iterasjon, uansett om det er nye data eller ikke (selv om dette kan være den tiltenkte funksjonen).

Som nevnt, ikke ømmer du variabelen, du oppretter bare en ny. Du må fjerne og nullstille count for å fikse dette problemet. Bare tilbakestilling av antall teller vil ikke fungere hvis den andre kommandoen er kortere enn den før.

Hvorfor kompliserer du også koden med dataComplete -variabelen? Jeg forenklet 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 sannsynligvis ikke gjør det du har tenkt å gjøre:

Serial.println("There is data already, clearing..."); char data[30]; 

Utdataene dine sier at du tømmer data matrisen, men du «gjør ikke noe slikt. Du erklærer faktisk en ny lokal variabel kalt data, som er uavhengig av den globale data deg allerede har erklært øverst i programmet ditt. Lokale variabler eksisterer bare innenfor det omfanget de er deklarert i (i deres nærmeste vedlagte { }).

I stedet holder count variabelen oversikt over hvor mye data du har mottatt. Så kanskje gjør følgende:

Serial.println("There is data already, clearing..."); count = 0; 

Dette er ikke det eneste som kan føre til at programmet fungerer uventet, men det bør i det minste løse problemet som er angitt i spørsmålet ditt.

Kommentarer

  • Det kreves også en null terminator for data: Legg til data[count]='\0'; etter dataComplete = true;
  • Ja, at ‘ er sant, men det større problemet er at det ikke er noen måte for avsenderen å angi slutten på en dataoverføring annet enn å pause. Og siden dette er seriell, kommer det til å være en lang nok pause mellom hvert tegn som overføres.
  • Takk til dere begge. Koden min var feil og endret den til » count = 0 » fungerte. Jeg la også til en skilletegn for å indikere slutten på en inndatakommando, og den fungerer som ment nå. Den eneste måten å tømme » data » array var imidlertid å bruke en for loop som indikert av @JRobert: denne måten nyere kommandoer fungerer selv om de er kortere enn eldre.

Svar

Å snakke til punktet i spørsmålet , og hva forfatteren prøvde å oppnå.

Ingen av denne koden fungerer faktisk som en helhet. Dataene vil bli overskrevet og bare fortsette å løpe kontinuerlig … uansett, her er et fungerende eksempel på den opprinnelige koden.

Denne metoden foretrekker jeg å fjerne en matrise:

 for( int i = 0; i < sizeof(data); ++i ) data[i] = (char)0; 

Her er arbeidseksempel. (Sørg for å velge Vognretur på seriell skjerm)

 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 ble lest alle kommentarene til dette spørsmålet, men alle kodene var delte så ordrike. Etter det oppretter jeg en kode med enkle funksjoner og mindre linje. i dette tilfellet tror jeg denne koden vil fungere fint

hvis du setter baudrate under 115200, må du legge til forsinkelse () for å lagre meldingen 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[] = {}; gir deg en null-lengdematrise. Det er en dårlig ide å prøve å legge inn data.
  • Jeg er enig med @NickGammon.Vennligst rediger svaret ditt for å erstatte » Jeg tror … vil fungere bra » med et definitivt ja / nei, når du har testet kode.
  • @NickGammon takk for korreksjonen, jeg reviderte koden min

Legg igjen en kommentar

Din e-postadresse vil ikke bli publisert. Obligatoriske felt er merket med *