Strings verwerken op Arduino. Gebaseerd op "Stringsreeksen verwerken op Arduino"

Tekstreeksen kan op twee manieren worden gedeclareerd: je kunt het gegevenstype String gebruiken, dat sinds versie 0019 in de kernel is opgenomen; of declareer de string als een op nul eindigende char-array. Op deze pagina wordt de tweede methode beschreven. Om meer te krijgen gedetailleerde informatie over String-object, het verstrekken van meer mogelijkheden ten koste van een groter geheugengebruik, zie pagina String - object.

Voorbeelden

Hieronder staan ​​voorbeelden van correcte stringdeclaraties.

Teken Str1; char Str2 = ("a", "r", "d", "u", "i", "n", "o"); char Str3 = ("a", "r", "d", "u", "i", "n", "o", "\0"); char Str4 = "arduino"; char Str5 = "arduino"; char Str6 = "arduino";

Toegestane bewerkingen bij het declareren van tekenreeksen

  • Declareer een karakterarray zonder deze te initialiseren (Str1)
  • Declareer een karakterarray met één redundant element, de compiler zal zelf het vereiste nulteken toevoegen (Str2)
  • Null-teken expliciet toevoegen (Str3)
  • Initialiseer de array met een tekenreeksconstante tussen aanhalingstekens; de compiler maakt een array van de vereiste grootte met een nulteken aan het einde (Str4)
  • Initialiseer een array met behulp van een stringconstante, waarbij u expliciet de grootte specificeert (Str5)
  • Initialiseer een extra grote array, zodat er ruimte overblijft voor meer lange rijen(Str6)

Nul eindigend karakter

Normaal gesproken worden alle tekenreeksen afgesloten met een nulteken (ASCII-code 0), waardoor functies (zoals Serial.print()) de lengte van de tekenreeks kunnen bepalen. Zonder dit symbool zouden ze opeenvolgend geheugenbytes blijven lezen die niet langer feitelijk deel zouden uitmaken van de string.

In essentie betekent dit dat de lengte van uw string 1 teken langer moet zijn dan de tekst die u erin wilt opslaan. Dit is de reden waarom Str2 en Str5 8 tekens lang moeten zijn, ook al neemt het woord "arduino" er maar 7 in beslag - de laatste positie wordt automatisch gevuld met een nulteken. De grootte van Str4 wordt automatisch 8 - één teken vereist voor de afsluitende nul. In de string Str3 hebben we zelf het nulteken gespecificeerd (aangeduid met "\0").

Houd er rekening mee dat het over het algemeen mogelijk is om een ​​string te declareren zonder een nulteken als afsluiting (bijvoorbeeld als u de lengte van Str2 instelt op 7 in plaats van op 8). Dit zal echter de meeste stringfuncties kapot maken, dus u moet dit niet opzettelijk doen. Deze fout kan de oorzaak zijn vreemd gedrag of het verschijnen van tekens van derden bij het werken met tekenreeksen.

Enkele of dubbele aanhalingstekens?

Strings worden altijd gedeclareerd in dubbele aanhalingstekens("Abc"), en symbolen worden altijd gedeclareerd in enkele aanhalingstekens("A").

Lange lijnen inpakken

Lange lijnen kunnen als volgt worden gewikkeld:

Char myString = "Dit is de eerste regel" " dit is de tweede regel" " enzovoort";

Stringarrays

Bij het werken met grote volumes tekst (bijvoorbeeld in projecten die met een LCD-scherm werken), is het vaak handig om arrays van tekenreeksen te gebruiken. Omdat strings zelf arrays zijn, is dit in feite een voorbeeld van een tweedimensionale array.

In het volgende programma staat er een asterisk achter de typeaanduiding gegevens teken"char*" geeft aan dat de variabele een array van "pointers" is. Alle arraynamen zijn feitelijk verwijzingen, dus het sterretje is nodig om een ​​array met arrays te maken. Pointers in C zijn een van de moeilijkste dingen voor beginners, maar in in dit geval diep begrip van aanwijzingen voor hun effectief gebruik helemaal niet vereist.

Voorbeeld

char* myStrings=("Dit is string 1", "Dit is string 2", "Dit is string 3", "Dit is string 4", "Dit is string 5", "Dit is string 6"); void setup())( Serial.begin(9600); ) void loop())( for (int i = 0; i< 6; i++){ Serial.println(myStrings[i]); delay(500); } }

Wat was er nodig? Informatie weergeven en door de gebruiker ingevoerde strings verwerken. Bijvoorbeeld:

Ethernet-controller - oké
STATISCHE modus
>tijd
2015-11-16 22:35:27

Eigenlijk moet je de afvoeren vergelijken. Nee, eerst moet je de tekst in fragmenten opdelen met een scheidingsteken (bijvoorbeeld een spatie), maar dan nog steeds de regels vergelijken. Omdat de commando's "één, twee - waren en het was verkeerd berekend", heb ik de opsplitsing van de tekst in fragmenten verwijderd. Vanwege de bovenstaande fout kon de klasse String niet worden gebruikt. Hoe kan dit anders worden gedaan? Arduino gebruikt de AVR-libc-bibliotheek, dus het is logisch om hier eerst naar te kijken.
Wat hebben we?

  1. stdlib.h - functies voor wederzijdse conversie van getallen en tekenreeksen (in beide richtingen).
  2. string.h - functies voor het werken met tekenreeksen. Onze voornaamste interesse.
  3. stdio.h - standaard invoer/uitvoerfuncties.

De functionaliteit is hiertoe niet beperkt. Er wordt iets vermeld dat verband houdt met de taak.

Nr. 2 - gebruik functies memset om de buffer te vullen of leeg te maken, memcmp- ter vergelijking. strcmp Ik gebruik het niet omdat ik de lengte van het vergeleken fragment expliciet moet beperken. Nr. 3 - voor het lezen en uitvoeren van formaten: sprintf, sprint_P, sscanf, sscanf_P. Functies met achtervoegsel _P verschillen doordat de formatstring wordt overgenomen uit het PROGMEM-programmageheugen, ook wel macro genoemd F() in Arduino-bibliotheken.

Trouwens

Trouwens, als je de input-output-functies volledig implementeert apart karakter krijgc En putc, dan ontvang je standaard stromen invoer, uitvoer, fouten en voor het werken met bestanden, als je die hebt. U kunt vaak rondkomen door macro's te overschrijven putchar() En haalchar(), werken met standaard invoer en conclusie.

Mijn stringvergelijking ziet er als volgt uit:

If (memcmp(str, "statlist",8)==0) ( // jouw code hier )

Misschien is het de moeite waard om te vermelden dat het begin van de lijnen wordt vergeleken. Om naar fragmenten te zoeken kunt u gebruik maken van memmem.

snaren voor C

snaren voor C str, zij zijn teken *- dit is een link naar het begin van de reeks verkoold, waarvan het laatste van belang is 0x00. Dit betekent dat ze ergens geplaatst moeten worden. Bijvoorbeeld in een array. Of gebruik malloc, calloc, vrij. Wat je ervan weerhoudt fouten te maken, betekent het verschuiven van de verantwoordelijkheid naar de programmeur voor hun plaatsing en lengtecontrole.

Dat wil zeggen, het zoeken naar een opdracht kan er als volgt uitzien:

If (memcmp(str ,"statclear", 9)==0) ( memset(journal, 0, sizeof(jrn_rec_t)*JRN_REC_NUM); Serial.println(F("ok")); )else if (memcmp(str ,"statlist" ,8)==0) ( funcStatlist(); )else if (memcmp(str , "cfgshow", 7)==0) ( funcCfgShow(); )else if (memcmp(str , "timeset" , 7)==0) ( funcTimeSet(str); // datum en tijd instellen JJJJ-MM-DD uu:mm:ss )else if (memcmp(str ,"cfgset", 6)==0) ( funcCfgSet( str); //funcPingdel(str); )else if (memcmp(str ,"time", 4)==0) ( funcTime(); // print datum en tijd van RTC )else if (memcmp(str ," help", 4)==0) ( // print korte help Serial.println(F(" helprn statlist statclearrn time timesetrn cfgshow cfgset")); )else( Serial.print(F("unknow cmd> ")); Serieel.println(str); )

Niet voor de hand liggend moment

Commando's, of regels, met een langere lengte moeten in het bovenstaande fragment eerst komen. Denk er eens over na, waarom?

Ik “verzamel” de regels op de volgende manier: ik lees bytes van de poort totdat de toegestane regellengte wordt overschreden of totdat een van de regelinvoertekens r of n wordt aangetroffen.

Lees regel

Het zou beter zijn om het af te ronden... Voor nu is het zoals het is. Wordt voortdurend gebeld in de hoofdring. Als er geen werk is, ga dan zo snel mogelijk naar buiten en breng het terug vals. Als u een nieuwe regel hebt getypt - WAAR. bool readln(HardwareSerial &uart, char *outbuf) // return true wanneer CR, LF of beide wordt gevonden en als de groottelimiet ( static char mybuf = ( 0 ); static char idx = 0; while (uart.available()) ( if (uart.peek()!= "r" && uart.peek()!= "n") ( mybuf[ idx++ ] = uart.read(); ) else (// if CR uart.read(); if ( uart.peek()=="n" || uart.peek()=="r") uart.read(); if (idx == 0) ( return 0; ) mybuf[ idx++ ] = ""; / / add 0 memcpy(outbuf, mybuf, idx); // kopieer idx = 0; return 1; ) if (idx >=(SBUF_SZ-1)) ( // controleer de lengte van de interne buffer mybuf[ SBUF_SZ-1 ] = " "; // voeg 0 toe memcpy(outbuf, mybuf, 32); // kopieer idx = 0; return 1; ) ) return 0; )

Formaat invoer/uitvoer is ook erg handig. Het parseren van een string met de ingevoerde datum en tijd ziet er bijvoorbeeld als volgt uit:

Sscanf_P(str, (const char *)F("%*s %d-%d-%d %d:%d:%d"), &y, &m, &d, &hh, &mm, &ss)

Een string verkrijgen om het IP-adres uit te voeren:

Sprintf_P(buff, (const char *)F("Uw IP: %d.%d.%d.%d"), ip, ip, ip, ip);

Dat is alles. Ik hoop iemand dit materiaal zal u helpen Arduino ‘weg te werken’ of uw programma’s eenvoudigweg beter en in minder tijd te schrijven. Maar meer typische situatie- beperkingen omzeilen Bedrading.


String tekst = "Temp: " + tempC + " C";

Helaas werkt deze techniek niet in C. In dit geval kan het bericht worden afgedrukt met behulp van verschillende afdrukinstructies, zoals hieronder weergegeven:

lcd.print("Temp: "); lcd.print(tempC); lcd.print("C");

Deze aanpak elimineert de noodzaak van het kopiëren van gegevens achter de schermen tijdens het aaneenschakelen van tekenreeksen, zoals gebeurt in andere moderne talen.

Een soortgelijke aanpak waarbij meerdere uitvoerinstructies worden gebruikt, kan worden gebruikt bij het werken met een monitor seriële poort en Serial.print-instructies. In dergelijke gevallen is het laatste commando op de regel meestal het println-commando, dat een newline-teken aan het einde toevoegt.

Tekenreeksen opmaken met sprintf

De standaard C-bibliotheek met stringfuncties (niet te verwarren met de Arduino String Object-bibliotheek, besproken in de volgende sectie) bevat een zeer handige sprintf-functie die karakterarrays opmaakt. Het voegt variabele waarden in een sjabloontekenreeks in, zoals weergegeven in het volgende voorbeeld:

sprint(regel1, "Temp: %d C", tempC);

De karakterarray line1 is een tekenreeksbuffer die opgemaakte tekst bevat. Zoals vermeld in het voorbeeld heeft het een capaciteit van 17 tekens, inclusief het extra afsluitende null-teken. Ik heb voor de naam line1 gekozen omdat ik ga laten zien hoe je de inhoud vormgeeft bovenste regel voor een liquid crystal display met twee regels van elk 16 tekens.

De eerste parameter geeft het sprintf-commando een reeks tekens door waarin het resultaat moet worden geschreven. Het volgende argument is een formatstring die het mengsel bevat platte tekst, zoals Temp:, en opmaakopdrachten, zoals %d. In dit geval betekent %d 'decimaal geheel getal met teken'. De resterende parameters worden in de opmaaktekenreeks ingevoegd in de volgorde waarin ze verschijnen in plaats van de opmaakopdrachten.

Om de tijd op de tweede regel van het LCD-display weer te geven, kan deze worden gevormd uit de individuele waarden van uren, minuten en seconden, zoals hieronder weergegeven:

sprintf(regel2, "Tijd: %2d:%02d:%02d", u, m, s);

Als u regel2 probeert uit te voeren naar een seriële monitor of LCD-scherm, ziet u de tekst

Het sprintf-commando heeft niet alleen de cijfers aangesloten de juiste plaatsen, maar heeft ook een voorloopnul toegevoegd vóór het getal 5. In het voorbeeld staan ​​tussen de tekens: er zijn opdrachten voor het opmaken van de drie tijdscomponenten. De klok komt overeen met de opdracht %2d, die een decimaal getal van twee cijfers afdrukt. De opmaakopdrachten voor minuten en seconden zijn iets anders (%02d). Deze opdrachten leveren ook twee cijfers op decimale getallen, maar voeg indien nodig een voorloopnul toe.

Houd er echter rekening mee dat deze techniek voor waarden is typ int. Helaas hebben de Arduino-ontwikkelaars het niet geïmplementeerd standaard bibliotheek C-ondersteuning voor andere typen zoals float.

Snaarlengte bepalen

Omdat tekenreeksen die in karakterarrays zijn opgeslagen vaak korter zijn dan de arrays zelf, biedt de bibliotheek een handige functie genaamd strlen. Deze functie telt het aantal tekens in een array voorafgaand aan het nulteken dat het einde van de tekenreeks markeert.

De functie neemt een array met tekens als enige parameter en retourneert de grootte van de tekenreeks (exclusief het lege teken) die daarin is opgeslagen, bijvoorbeeld de opdracht

zal het nummer 3 teruggeven.

Arduino String-objectbibliotheek

IN Arduino-IDE, te beginnen met versie 019, die enkele jaren geleden is uitgebracht, is de String-bibliotheek inbegrepen, die begrijpelijker en vriendelijker is voor ontwikkelaars die Java, Ruby, Python en andere talen gebruiken die string-aaneenschakeling toestaan eenvoudige bediening+. Deze bibliotheek biedt ook veel hulpfuncties voor het werken met snaren.

Zeker, deze bibliotheek voegt enkele kilobytes aan code toe aan de schets. Bovendien maakt het gebruik van een mechanisme dynamische distributie geheugen met alle problemen van dien, zoals geheugenuitputting. Denk daarom goed na voordat u besluit het te gebruiken. Veel Arduino-gebruikers geven er de voorkeur aan om reguliere karakterarrays te gebruiken.

Deze bibliotheek is verbazingwekkend eenvoudig te gebruiken, en als je ooit met strings in Java hebt gewerkt, zul je je meteen thuis voelen met de Arduino String Object-bibliotheek.

Tekenreeksen maken

Je kunt een string maken van een array van elementen typ char, of van een waarde van het type int of float, zoals weergegeven in het volgende voorbeeld:

String bericht = "Temp: ";

Stringtemperatuur = String(123);

Tekenreeksaaneenschakeling

Strings kunnen met elkaar en met andere soorten gegevens worden gecombineerd met behulp van de + operator. Probeer de volgende code toe te voegen aan de setup-functie van een lege schets:

Serieel.begin(9600);

String bericht = "Temp: ";

Stringtemperatuur = String(123);

Serial.println(bericht + temperatuur + "C");

Houd er rekening mee dat laatste waarde, die aan de string wordt toegevoegd, is eigenlijk een array van tekens. Als het eerste element in de reeks waarden tussen de + operatoren een string is, worden de overige elementen automatisch geconverteerd naar strings voordat ze worden samengevoegd.

Ander string-functies

In tafel 6.1 somt er nog een paar op handige functies uit de String-bibliotheek. Volle lijst beschikbare functies is te vinden op http://arduino.cc/en/Reference/StringObject.

Tabel 6.1. Sommige handige functies in de String-bibliotheek

Functie

Voorbeeld

Beschrijving

char ch = String("abc")

De variabele ch krijgt de waarde "a"

Tekenreeks s = "abc";

Verwijdert spaties aan beide zijden van de abc-tekengroep. De variabele s krijgt de waarde "abc"

Tekenreeks s = "123";

int x = s.toInt();

Converteert de tekenreeksweergave van een getal naar een int- of long-waarde

Tekenreeks s = "abcdefg";

Tekenreeks s2 = s.subtekenreeks(1, 3);

Retourneert een fragment van de originele tekenreeks. De variabele s2 krijgt de waarde "bc". De parameters passeren: de index van het eerste teken van het fragment en de index van het volgende teken laatste teken fragment

Tekenreeks s = "abcdefg";

s.replace("de", "DE");

Vervangt alle exemplaren van "de" in een string door "DE". Variabele s2 krijgt de waarde "abcDEfg"

EEPROM gebruiken

Inhoud van alle variabelen die worden gebruikt in Arduino-schets, gaat verloren wanneer de stroom wordt uitgeschakeld of een reset wordt uitgevoerd. Om de waarden op te slaan, moeten ze byte voor byte in het EEPROM-geheugen worden geschreven. IN Arduino Uno Er is 1 KB EEPROM-geheugen aanwezig.

OPMERKING

Dit geldt niet voor het bestuur Arduino verschuldigd, die geen EEPROM heeft. In dit model moeten gegevens worden opgeslagen op een microSD-kaart.

Om gegevens naar de EEPROM te lezen en te schrijven, moet u de bibliotheek gebruiken die bij de Arduino IDE is geleverd. Het volgende voorbeeld laat zien hoe u een enkele byte naar EEPROM schrijft; in dit geval wordt de bewerking uitgevoerd in instelfuncties:

#erbij betrekken

bytewaardeToSave = 123

EEPROM.write(0, waardeToSave);

Het eerste argument voor de schrijffunctie is het adres in de EEPROM waar de databyte moet worden geschreven, en het tweede is de waarde die naar dat adres moet worden geschreven.

18 november 2015 om 14:39 uur

Gebaseerd op "Stringsreeksen verwerken op Arduino"

  • Ontwikkeling voor Arduino

Wat was er nodig? Informatie weergeven en door de gebruiker ingevoerde strings verwerken. Bijvoorbeeld:

Ethernet-controller - oké
STATISCHE modus
>tijd
2015-11-16 22:35:27

Eigenlijk moet je de afvoeren vergelijken. Nee, eerst moet je de tekst in fragmenten opdelen met een scheidingsteken (bijvoorbeeld een spatie), maar dan nog steeds de regels vergelijken. Omdat de commando's "één, twee - waren en het was verkeerd berekend", heb ik de opsplitsing van de tekst in fragmenten verwijderd. Vanwege de bovenstaande fout kon de klasse String niet worden gebruikt. Hoe kan dit anders worden gedaan? Arduino gebruikt de AVR-libc-bibliotheek, dus het is logisch om hier eerst naar te kijken.
Wat hebben we?
  1. stdlib.h - functies voor wederzijdse conversie van getallen en tekenreeksen (in beide richtingen).
  2. string.h - functies voor het werken met tekenreeksen. Onze voornaamste interesse.
  3. stdio.h - standaard invoer/uitvoerfuncties.
De functionaliteit is hiertoe niet beperkt. Er wordt iets vermeld dat verband houdt met de taak.

Nr. 2 - gebruik functies memset om de buffer te vullen of leeg te maken, memcmp- ter vergelijking. strcmp Ik gebruik het niet omdat ik de lengte van het vergeleken fragment expliciet moet beperken. Nr. 3 - voor het lezen en uitvoeren van formaten: sprintf, sprint_P, sscanf, sscanf_P. Functies met achtervoegsel _P verschillen doordat de formatstring wordt overgenomen uit het PROGMEM-programmageheugen, ook wel macro genoemd F() in Arduino-bibliotheken.

Trouwens

Trouwens, als je de invoer-uitvoerfuncties van een enkel teken volledig implementeert krijgc En putc, dan krijgt u standaard invoer-, uitvoer-, fout- en bestandsstreams, als u die heeft. U kunt vaak rondkomen door macro's te overschrijven putchar() En haalchar(), werkend met standaard invoer en uitvoer.


Mijn stringvergelijking ziet er als volgt uit:

If (memcmp(str, "statlist",8)==0) ( // jouw code hier )
Misschien is het de moeite waard om te vermelden dat het begin van de lijnen wordt vergeleken. Om naar fragmenten te zoeken kunt u gebruik maken van memmem.

snaren voor C

snaren voor C str, zij zijn teken *- dit is een link naar het begin van de reeks verkoold, waarvan het laatste van belang is 0x00. Dit betekent dat ze ergens geplaatst moeten worden. Bijvoorbeeld in een array. Of gebruik malloc, calloc, vrij. Wat je ervan weerhoudt fouten te maken, betekent het verschuiven van de verantwoordelijkheid naar de programmeur voor hun plaatsing en lengtecontrole.


Dat wil zeggen, het zoeken naar een opdracht kan er als volgt uitzien:

If (memcmp(str ,"statclear", 9)==0) ( memset(journal, 0, sizeof(jrn_rec_t)*JRN_REC_NUM); Serial.println(F("ok")); )else if (memcmp(str ,"statlist" ,8)==0) ( funcStatlist(); )else if (memcmp(str , "cfgshow", 7)==0) ( funcCfgShow(); )else if (memcmp(str , "timeset" , 7)==0) ( funcTimeSet(str); // datum en tijd instellen JJJJ-MM-DD uu:mm:ss )else if (memcmp(str ,"cfgset", 6)==0) ( funcCfgSet( str); //funcPingdel(str); )else if (memcmp(str ,"time", 4)==0) ( funcTime(); // print datum en tijd van RTC )else if (memcmp(str ," help", 4)==0) ( // print korte help Serial.println(F(" help\r\n statlist statclear\r\n tijd tijdset\r\n cfgshow cfgset")); )else( Serial. print(F("onbekend cmd> ")); Serial.println(str); )

Niet voor de hand liggend moment

Commando's, of regels, met een langere lengte moeten in het bovenstaande fragment eerst komen. Denk er eens over na, waarom?


Ik “verzamel” de regels op de volgende manier: ik lees bytes van de poort totdat de toegestane regellengte wordt overschreden of totdat een van de regelinvoertekens \r of \n wordt aangetroffen.

Lees regel

Het zou beter zijn om het af te ronden... Voor nu is het zoals het is. Wordt voortdurend gebeld in de hoofdring. Als er geen werk is, ga dan zo snel mogelijk naar buiten en breng het terug vals. Als u een nieuwe regel hebt getypt - WAAR.

Bool readln(HardwareSerial &uart, char *outbuf) // retourneert waar wanneer CR, LF of beide wordt gevonden en als de groottelimiet ( static char mybuf = ( 0 ); static char idx = 0; while (uart.available()) ( if (uart.peek()!= "\r" && uart.peek()!= "\n") ( mybuf[ idx++ ] = uart.read(); ) else (// if CR uart.read(); if (uart.peek()=="\n" || uart.peek()=="\r") uart.read(); if (idx == 0) ( return 0; ) mijnbuf[ idx++ ] = "\0"; // voeg 0 memcpy(outbuf, mybuf, idx); // kopieer idx = 0; return 1; ) if (idx >=(SBUF_SZ-1)) ( // controleer de lengte van de interne buffer mybuf[ SBUF_SZ-1 ] = "\0"; // voeg 0 memcpy(outbuf, mybuf, 32); // kopieer idx = 0; return 1; ) ) return 0; )


Formaat invoer/uitvoer is ook erg handig. Het parseren van een tekenreeks met de ingevoerde datum en tijd ziet er bijvoorbeeld als volgt uit: sscanf_P(str, (const char *)F("%*s %d-%d-%d %d:%d:%d"), &y, &m, &d, &hh, &mm, &ss)
Een string verkrijgen om het IP-adres uit te voeren:

Sprintf_P(buff, (const char *)F("Uw IP: %d.%d.%d.%d"), ip, ip, ip, ip);
U kunt bijvoorbeeld meer lezen over de formatstring:

Ik kwam bij programmeren in het algemeen terecht, en Arduino-programmering in het bijzonder, compleet nul, ongeveer twee maanden geleden. Nu, in de loop van mijn huidige activiteiten, voelde ik de behoefte om de stringverwerking op Arduino onder de knie te krijgen. Een gewone trip naar Google voor informatie beviel me niet met een artikel waarin alles eenvoudig en duidelijk is geschreven voor dummies. En daarom ben ik hier om te praten over hoe het parseren van strings vanaf een seriële poort werd geïmplementeerd en welke valkuilen we onderweg tegenkwamen. Voor geïnteresseerden verwijzen wij naar cat.

Dus. Hier benaderend algoritme die ik volgde:

  1. We gaan naar arduino.ru en zoeken in de typekolom naar alles wat met symbolen te maken heeft.
  2. Wij beslissen welke vorm van vertegenwoordiging we zullen gebruiken (ik heb besloten klasse String, omdat een onaangename ervaring gehad met een mash-array).
  3. We proberen verwoed onze eigen functie te schrijven met voorkeur en professionele rasters
  4. Op zoek naar een klas.
  5. Wij zijn op zoek naar de nodige operators.
  6. Laten we schrijven!
En het algoritme van het hoofdgedeelte van het programma is eenvoudig:
  1. We kijken cyclisch of er nog iets in de buffer zit com-poort leesbare byte, indien aanwezig, lezen.
  2. Als de ontvangen byte een regeleindeteken is ("\n"), dan noemen we de zelfgeschreven parseerfunctie, zo niet, dan voegen we de ontvangen byte toe aan de gemaakte byte type variabele Snaar.
  3. Parseer ten slotte de tekenreeks.

    Sterker nog, omdat praktisch gebruik Het parseren van strings werkt bij mij dus niet deze functie is alleen demonstratief van aard, waarbij de resulterende string wordt vergeleken met een constante string die al in het geheugen is geschreven. Dus met behulp van de equals-operator vergelijken we de ontvangen string met de geschreven string, en als de operator true retourneert, verlaten we de handler-functie; zo niet, dan vergelijken we deze met de volgende. Als de tekenreeksen gelijkwaardig zijn, verlaten we opnieuw de handlerfunctie en retourneren we het resultaat. Welnu, als deze voorwaarde niet werkt, verlaten we de functie nog steeds en zeggen we dat de regel niet waar is.

  4. Afhankelijk van het geaccepteerde resultaat met schakelaar gebruiken geval selecteert u degene die u nodig heeft.
  5. We resetten de ontvangen string zodat we deze opnieuw kunnen verzamelen.

En tot slot, hier is de code:

#define led 13 String input_string = ""; const String Led_off = "schakel led uit"; const String Led_on = "schakel led aan"; bool led_running; void setup() ( Serial.begin(9600); ) void loop() ( while (Serial.available() > 0) ( char c = Serial.read(); if (c == "\n") ( Serial .print("Input_string is: "); Serial.println(input_string); switch (parse(input_string, Led_off, Led_on)) ( case 10: led_running=false; Serial.println("Uitschakelen is voltooid"); break; case 11: led_running=true; Serial.println("Inschakelen is voltooid"); break; case 0: Serial.println("ongeldige string"); break; ) input_string = ""; digitalWrite(led, led_running); ) else ( input_string += c; ) ) byte parse(String input_string, const String Led_off, const String Led_on) ( if (input_string.equals(Led_off) == true) ( ​​retourneert 10; ) else if (input_string.equals( Led_on ) == waar) ( retourneert 11; ) anders retourneert 0; )


Dus ik begrijp niet wat er aan de hand is? Waarom brandt de LED niet? Oh ja, hoe ben ik dit vergeten, in de void setup moet je toevoegen:

PinMode(led, UITGANG);

P.S.: Het is belangrijk om de com-poortmonitor in de Arduino IDE in te stellen op “ Nieuwe lijn", omdat in elk ander geval wordt de verzonden string niet gevolgd door het eindteken "\n".

P.P.S.: Ik ga niet deelnemen aan de holivar over het feit dat Arduino niet nodig is; ik heb niets verkeerd gedaan tijdens het bestuderen van de basisprincipes van programmeren en algoritmisering.

P.P.P.S.: Als het artikel adequaat wordt ontvangen, zal ik het volgende schrijven over wat ik heb gedaan met het verbeteren van de functionaliteit van de parseerfunctie. Welnu, bij God! .