Wis de bestaande array bij het ophalen van een nieuwe seriële opdracht

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

  • Er is ook een null-terminator nodig voor gegevens: voeg data[count]='\0'; toe na dataComplete = true;
  • Ja, dat ‘ is waar, maar het grotere probleem is dat er geen manier is voor de afzender om het einde van een gegevensoverdracht aangeven, behalve om te pauzeren. En aangezien dit serieel is, zal er een pauze zijn die lang genoeg is tussen elk verzonden karakter.
  • Dank aan jullie beiden. Mijn code was verkeerd en het wijzigen naar ” count = 0 ” werkte. Ik heb ook een scheidingsteken toegevoegd om het einde van een invoeropdracht aan te geven en het werkt nu zoals bedoeld. De enige manier die werkte om de ” data ” -array leeg te maken, was echter het gebruik van een for-lus zoals aangegeven door @JRobert: op deze manier nieuwer commandos werken zelfs als ze korter zijn dan oudere.

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

Geef een reactie

Het e-mailadres wordt niet gepubliceerd. Vereiste velden zijn gemarkeerd met *