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
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
data[count]='\0';
etterdataComplete = true;