Ik begin met het bouwen van mijn eerste Arduino-project, maar ik “kom wat problemen tegen met seriële communicatie.
Ik krijg seriële data van de console en sla deze op in een char-array genaamd “data”.
Wanneer ik dan een nieuw consolebericht naar de Arduino stuur, wil ik dat het de bestaande “data” -array en sla alleen de nieuwe data in die array op.
Ik begrijp niet precies wat er mis is met mijn code: ik geloof dat die geneste Serial.available () statements niet werken maar ik heb geen idee hoe ik de code moet repareren.
Gegevens worden correct opgeslagen door de Arduino, maar het voegt de nieuwere string samen met de oude.
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); }
Bij voorbaat dank!
Answer
Om een array te wissen, doet u het volgende:
for( int i = 0; i < sizeof(data); ++i ) data[i] = (char)0;
of
memset(data, 0, sizeof(data));
, wat hetzelfde doet met een bibliotheekfunctie.
Echter, omdat strings van tekens (niet verwijzend naar “String” -objecten hier) worden beëindigd door een nul-byte, alleen de eerste byte hoeft op nul te worden gezet:
data[0] = (char)0;
zal het doen .
Antwoord
Allereerst is dit een uitstekend voorbeeld waarom witruimte belangrijk is. Je code is echt moeilijk te lezen zoals hij is, als je eroverheen bladert, lijkt het de tweede als de instructie buiten de eerste valt.
Vaste code:
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); }
Het lijkt er ook op dat het elke iteratie” Opdracht ontvangen: “afdrukt, ongeacht of er nieuwe gegevens zijn of niet (hoewel dit de bedoelde functie zou kunnen zijn).
Zoals gezegd, wist je de variabele niet, je maakt gewoon een nieuwe aan. U moet wissen en resetten count
om dit probleem op te lossen. Het resetten van de telling werkt echter niet als de tweede opdracht korter is dan de vorige. ervoor.
En waarom maak je de code ingewikkeld met de dataComplete
variabele? Ik heb de onderstaande code vereenvoudigd:
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); }
Antwoord
Dit is waarschijnlijk niet doe wat je van plan bent te doen:
Serial.println("There is data already, clearing..."); char data[30];
Je output zegt dat je de data
array wist, maar jij “doet zoiets niet. In feite declareert u een nieuwe lokale variabele met de naam data
, die onafhankelijk is van de globale data
die u hebben al verklaard bovenaan uw programma. Lokale variabelen bestaan alleen binnen het bereik waarin ze zijn gedeclareerd (binnen hun dichtstbijzijnde omsluitende { }
).
In plaats daarvan houdt uw count
variabele bij hoeveel gegevens u heeft ontvangen. Dus doe misschien het volgende:
Serial.println("There is data already, clearing..."); count = 0;
Dit is niet het enige dat ervoor kan zorgen dat uw programma onverwacht werkt, maar het zou op zijn minst het probleem moeten oplossen dat wordt vermeld in uw vraag.
Opmerkingen
Answer
Om tot het punt van de vraag te spreken , en wat de auteur probeerde te bereiken.
Geen van deze code werkt echt als geheel. De gegevens zouden overschreven worden en gewoon doorlopend blijven herhalen … hier is in ieder geval een werkend voorbeeld van de originele code.
Deze methode maak ik liever leeg:
for( int i = 0; i < sizeof(data); ++i ) data[i] = (char)0;
Hier is een werkvoorbeeld. (Zorg ervoor dat u Carriage Return selecteert op de seriële monitor)
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; } } }
Answer
Ik heb alle reacties op deze vraag gelezen, maar alle codes waren zo uitgebreid gedeeld. Daarna maak ik een code met eenvoudige functies en minder regel. in dit geval denk ik dat deze code goed zal werken
als je baudrate instelt onder 115200, moet add delay () zijn om bericht op te slaan in 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); }
Reacties
-
char data[] = {};
geeft je een array met de lengte nul. Het is een slecht idee om er gegevens in te stoppen. - Ik ben het eens met @NickGammon.Bewerk uw antwoord om ” Ik denk dat … prima zal werken ” door een definitief ja / nee, zodra u de code.
- @NickGammon bedankt voor de correctie, ik was mijn code aan het herzien
data[count]='\0';
toe nadataComplete = true;