Rensa befintlig array när du får nytt seriekommando

Jag börjar bygga mitt första Arduino-projekt men jag stöter på problem med seriell kommunikation.

Jag får seriell data från konsolen och lagrar den i en char-array som heter ”data”.

Sedan, när jag skickar ett nytt konsolmeddelande till Arduino, vill jag att det ska rensa befintlig ”data” array och lagrar bara de nya data i den arrayen.

Jag förstår inte exakt vad som är fel med min kod: Jag tror att de kapslade Serial.available () uttalandena inte fungerar men jag har inga idéer för hur jag ska fixa koden.

Data lagras korrekt av Arduino men det sammanfogar den nyare strängen till den gamla.

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); } 

Tack på förhand!

Svar

För att rensa en matris skulle du göra:

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

eller

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

, vilket gör samma sak med hjälp av en biblioteksfunktion.

Men eftersom strängar av tecken (som inte hänvisar till ”String” -objekt här) avslutas med en nollbyte, bara den första byten behöver nollställas:

data[0] = (char)0; 

gör det .

Svar

Först och främst är detta ett utmärkt exempel på varför det stora utrymmet är viktigt. Din kod är väldigt svår att läsa som den är, eftersom den skummar över den verkar som den andra om uttalandet ligger utanför det första.

Fast kod:

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 verkar också som om det skrivs ut” Kommando mottaget: ”varje iteration, oavsett om det finns nya data eller inte (även om detta kan vara den avsedda funktionen).

Som nämnts, ömmer du inte variabeln, du skapar bara en ny. Du måste rensa och återställa count för att åtgärda problemet. Men bara att återställa antalet kommer inte att fungera om det andra kommandot är kortare än det innan.

Varför komplicerar du också koden med variabeln dataComplete? Jag förenklade koden nedan:

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

Detta gör förmodligen inte ”t gör vad du tänker göra:

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

Din utdata säger att du rensar data -arrayen, men du ”gör inget sådant. Du förklarar faktiskt en ny lokal variabel som heter data, som är oberoende av den globala data du redan har deklarerat högst upp i ditt program. Lokala variabler finns bara inom det omfång inom vilket de deklareras (i deras närmaste omslutande { }).

I stället håller din count variabel reda på hur mycket data du har fått. Så gör kanske följande:

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

Detta är inte det enda som kan få ditt program att fungera oväntat, men det borde åtminstone åtgärda problemet som anges i din fråga.

Kommentarer

  • Dessutom krävs en nullterminator för data: Lägg till data[count]='\0'; efter dataComplete = true;
  • Ja, att ’ är sant, men det större problemet är att det inte finns något sätt för avsändaren att ange slutet på en dataöverföring annat än att pausa. Och eftersom detta är seriellt kommer det att finnas en tillräckligt lång paus mellan varje tecken som sänds.
  • Tack till er båda. Min kod var fel och ändrade den till ” count = 0 ” fungerade. Jag lade också till en avgränsare för att ange slutet på ett inmatningskommando och det fungerar som avsett nu. Det enda sättet som fungerade för att tömma ” data ” -matrisen var att använda en for-loop enligt @JRobert: detta sätt nyare kommandon fungerar även om de är kortare än äldre.

Svar

Att tala till punkten i frågan , och vad författaren försökte åstadkomma.

Ingen av denna kod fungerar faktiskt som en helhet. Uppgifterna skulle bli överskrivna och bara fortsätta att kretsa kontinuerligt … hur som helst här är ett fungerande exempel på den ursprungliga koden.

Denna metod föredrar jag att rensa en array:

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

Här är ett fungerande exempel. (Se till att du väljer Vagnretur på seriell bildskä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

Jag fick läsa alla kommentarer på den här frågan, men alla koder var så delaktiga. Efter det skapar jag en kod med enkla funktioner och mindre linje. i det här fallet tror jag att den här koden fungerar bra

om du ställer in baudrate under 115200, måste du lägga till fördröjning () för att spara meddelande 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[] = {}; ger dig en matris med noll längd. Att försöka lägga in data i det är en dålig idé.
  • Jag håller med @NickGammon.Redigera ditt svar för att ersätta ” Jag tror … kommer att fungera bra ” med ett definitivt ja / nej, när du har testat kod.
  • @NickGammon tack för rättelsen, jag reviderade min kod

Lämna ett svar

Din e-postadress kommer inte publiceras. Obligatoriska fält är märkta *