Tyhjennä nykyinen taulukko, kun haen uutta sarjakomentoa

Aloitan ensimmäisen Arduino-projektini rakentamista, mutta minulla on joitain ongelmia sarjaliikenteen kanssa.

Saan sarjatiedot konsolista ja tallennan ne ”data” -merkkiryhmään.

Kun sitten lähetän uuden konsoliviestin Arduinolle, haluan sen tyhjentävän olemassa oleva ”data” -taulukko ja tallenna vain uudet tiedot taulukkoon.

En ymmärrä tarkalleen, mikä koodissani vikaa: Uskon, että ne sisäkkäiset Serial.available () -lausekkeet eivät toimi mutta minulla ei ole ideoita koodin korjaamisesta.

Arduino tallentaa tiedot oikein, mutta se yhdistää uudemman merkkijonon vanhaan.

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

Kiitos etukäteen!

Vastaa

Voit tyhjentää taulukon seuraavasti:

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

tai

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

, joka tekee saman asian kirjastotoiminnon avulla.

Kuitenkin, koska merkkijonot merkkiä (ei viittaa tässä merkkijono-objekteihin) päättyy nollatavulla, vain ensimmäinen tavu on nollattava:

data[0] = (char)0; 

tekee sen .

Vastaus

Ensinnäkin tämä on erinomainen esimerkki miksi välilyönnillä on merkitystä. Koodiasi on todella vaikea lukea sellaisenaan, sillä sen ohittaminen näyttää toiselta, jos lause on ensimmäisen ulkopuolella.

Kiinteä koodi:

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

Näyttää myös siltä, että se tulostaa” Komento vastaanotettu: ”kaikki iteraatiot riippumatta siitä, onko uusia tietoja vai ei (vaikka tämä voisi olla tarkoitettu ominaisuus).

Kuten mainittiin, et tyhjennä muuttujaa, vaan luot vain uuden. Sinun on tyhjennettävä ja palautettava count ongelman korjaamiseksi. Pelkkä laskurin nollaaminen ei toimi, jos toinen komento on lyhyempi kuin yksi ennen.

Miksi monimutkaistat koodia muuttujalla dataComplete? Yksinkertaistin alla olevaa koodia:

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

Vastaa

Tämä ei todennäköisesti ”t” tee se, mitä aiot tehdä:

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

Lähdössä sanotaan, että tyhjennät data -taulukon, mutta ”en tee mitään sellaista. Itse asiassa ilmoitat uuden paikallisen muuttujan nimeltä data, joka on riippumaton globaalista data sinusta olet jo ilmoittanut ohjelman yläosassa. Paikalliset muuttujat ovat olemassa vain siinä laajuudessa, jossa ne on ilmoitettu (lähimmän ympäröivän { } sisällä).

Sen sijaan count -muuttuja seuraa vastaanotettujen tietojen määrää. Joten tee ehkä seuraava:

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

Tämä ei ole ainoa asia, joka saattaa aiheuttaa ohjelman odottamattoman toiminnan, mutta sen pitäisi ainakin korjata kysymyksesi.

Kommentit

  • Tietoihin tarvitaan myös tyhjä terminaattori: Lisää data[count]='\0'; dataComplete = true;
  • Kyllä, se ’ on totta, mutta suurempi ongelma on, että lähettäjällä ei ole mitään tapaa ilmaista tiedonsiirron loppu muu kuin tauko. Ja koska tämä on sarja, kaikkien lähetettyjen hahmojen väliin tulee tarpeeksi pitkä tauko.
  • Kiitos teille molemmille. Koodini oli väärä ja sen muuttaminen ” count = 0 ” toimi. Lisäsin myös erottimen osoittamaan syöttökomennon loppua ja se toimii nyt tarkoitetulla tavalla. Ainoa tapa, joka toimi ” data ” -taulukon tyhjentämisessä, oli for for -silmukan käyttäminen @JRobertin osoittamalla tavalla: näin uudempi komennot toimivat, vaikka ne olisivat lyhyempiä kuin vanhemmat.

Vastaa

Puhuaksesi kysymykseen asti ja mitä kirjoittaja yritti saavuttaa.

Mikään näistä koodeista ei todellakaan toimi kokonaisuutena. Tiedot pääsisivät kirjoitettujen yli ja jatkaisivat silmukointia jatkuvasti … tässä tapauksessa tässä on toimiva esimerkki alkuperäisestä koodista.

Tämä menetelmä haluan tyhjentää taulukon:

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

Tässä on toimiva esimerkki. (Muista valita sarjaliikennevälineen rivinvaihto)

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

Vastaa

Luin kaikki kommentit tästä kysymyksestä, mutta kaikki koodit jaettiin niin verbosing. Sen jälkeen luon koodin, jossa on yksinkertaiset toiminnot ja vähemmän riviä. tässä tapauksessa luulen, että tämä koodi toimii hyvin

jos asetat baudrate-arvon alle 115200, on lisättävä delay () viestin tallentamiseksi char-taulukkoon

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

Kommentit

  • char data[] = {}; antaa sinulle nollapituisen taulukon. Tietojen yrittäminen siihen on huono idea.
  • Olen samaa mieltä @NickGammonin kanssa.Muokkaa vastaustasi korvaamaan ” mielestäni … toimii hyvin ” lopullisella kyllä / ei, kun olet testannut koodi.
  • @NickGammon kiitos korjauksesta, olin tarkistamassa koodiani

Vastaa

Sähköpostiosoitettasi ei julkaista. Pakolliset kentät on merkitty *