Törölje a meglévő tömböt, amikor új soros parancsot kap

Elkezdem építeni az első Arduino projektemet, de néhány probléma merül fel a soros kommunikációval.

Soros adatokat kapok a konzolról, és egy “data” nevű char tömbben tárolom.

Ezután, amikor új konzolos üzenetet küldök az Arduino-nak, azt akarom, hogy törölje a a meglévő “data” tömb és csak az új adatokat tárolja abban a tömbben.

Nem értem pontosan, mi a baj a kódommal: úgy gondolom, hogy a beágyazott Serial.available () utasítások nem működnek de nincs ötletem a kód javításáról.

Az Arduino megfelelően tárolja az adatokat, de összefűzi az újabb sztringet a régivel.

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

Előre is köszönöm!

Válasz

Egy tömb törléséhez tegye a következőket:

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

vagy

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

, amely ugyanazt csinálja egy könyvtár függvény használatával.

Azonban azért, mert húrok karaktert (itt nem hivatkozva a “String” objektumokra) nulla bájttal zárja le, csak az első bájtot kell nullázni:

data[0] = (char)0; 

megteszi .

Válasz

Először is ez egy kiváló példa, miért fontos a szóköz. A kódod nagyon nehéz elolvasni, ahogy van, a rajta való áthúzás másodiknak tűnik, ha az utasítás kívül esik az elsőn.

Javított kód:

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

Emellett úgy tűnik, hogy a” Parancs kapott: “minden iterációt kiírja, függetlenül attól, hogy vannak-e új adatok vagy sem (bár ez lehet a tervezett funkció).

Mint említettük, nem “törölheti a változót, csak létrehoz egy újat. A probléma megoldásához törölnie kell a és reset count elemeket. Ha a második parancs rövidebb, mint a parancs, akkor a számláló visszaállítása nem fog működni. előtt.

Ezenkívül miért bonyolítja a kódot a dataComplete változóval? Az alábbi kódot egyszerűsítettem:

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

Válasz

Ez valószínűleg nem “t” tedd azt, amit szeretnél:

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

A kimeneted szerint tisztítod a data tömböt, de “nem csinál ilyet. Valójában egy iv új = data nevű helyi változót deklarál, amely független a globális data től már deklarálta a program tetején. A helyi változók csak abban a körben léteznek, amelyben deklarálták (a legközelebbi bezáró { } belül).

Ehelyett a count változó nyomon követi, hogy mennyi adatot kapott. Tehát tegye a következőket:

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

Nem csak ez okozhatja a program váratlan működését, de legalább meg kell oldania a a kérdésed.

Megjegyzések

  • Az adatokhoz null-terminátor is szükséges: data[count]='\0'; hozzáadása dataComplete = true;
  • Igen, ez ‘ igaz, de a nagyobb probléma az, hogy a feladónak nincs módja jelezze az adatátvitel végét, a szüneteltetés kivételével. És mivel ez soros, elég hosszú szünet következik minden továbbított karakter között.
  • Mindkettőtöknek köszönöm. A kódom hibás volt, és megváltoztattam ” count = 0 ” -re. Hozzáadtam egy elválasztót is, hogy jelezzem a bemeneti parancs végét, és a rendeltetésszerűen működik. Az egyetlen mód, amely a ” adatok ” tömb kiürítéséhez működött, a @JRobert által jelzett for ciklust használta: így újabb a parancsok akkor is működnek, ha rövidebbek, mint az idősebbek.

Válasz

A kérdés lényegéhez szólni , és amit a szerző megpróbált megvalósítani.

A kódok egyike sem működik egészében. Az adatok túllépnének az írtakon, és folyamatosan folytatnák a hurkolást … amúgy itt van egy működő példa az eredeti kódra.

Ez a módszer inkább egy tömböt töröl:

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

Íme egy működő példa. (Ügyeljen arra, hogy a soros monitoron válassza a Carriage Return lehetőséget)

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

Válasz

Olvastam az összes megjegyzést erről a kérdésről, de az összes kód megosztott volt. Ezt követően létrehozok egy egyszerű függvényekkel rendelkező kódot, kevesebb sorral. ebben az esetben azt hiszem, hogy ez a kód jól fog működni

ha az átviteli sebességet 115200 alatt állítja be, akkor hozzá kell adnia a delay () értéket az üzenet char tömbbe mentéséhez

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

Megjegyzések

  • char data[] = {}; nulla hosszúságú tömböt kap. Rossz ötlet megpróbálni adatokat betenni.
  • Egyetértek a @NickGammon véleményével.Kérjük, szerkessze a válaszát, hogy ” helyettesítse. Azt hiszem, … jól fog működni kódot.
  • @NickGammon köszönöm a javítást, átdolgoztam a kódomat

Vélemény, hozzászólás?

Az email címet nem tesszük közzé. A kötelező mezőket * karakterrel jelöltük