Arbeta med arduino textsträngar. Slår in långa rader. Funktioner och metoder för klassen String


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

Tyvärr fungerar inte denna teknik i C. I det här fallet meddelandet kan visas med flera utskrifter, som visas nedan:

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

Detta tillvägagångssätt eliminerar behovet av bakom-kulisserna datakopiering under strängsammansättning (kombination) som sker i andra moderna språk.

Ett liknande tillvägagångssätt med flera utdatainstruktioner kan användas när du arbetar med en bildskärm serieport och Serial.print instruktioner. I liknande fall Den sista raden på raden är vanligtvis kommandot println, som lägger till ett nyradstecken i slutet.

Formatera strängar med använder sprintf

Standardbibliotek strängfunktioner för C (inte att förväxla med Arduino String Object-biblioteket som diskuteras i nästa avsnitt) innehåller en mycket praktisk sprintf-funktion som formaterar teckenuppsättningar. Den infogar värdena för variablerna i mallsträngen, som visas i följande exempel:

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

Teckenmatrisen line1 är en strängbuffert som innehåller formaterad text. Som anges i exemplet har den en kapacitet på 17 tecken, inklusive ett extra nolltecken i slutet. Jag valde namnet line1 för att jag ska visa dig hur du kan forma innehållet. översta raden för en flytande kristallskärm med två rader med 16 tecken vardera.

Den första parametern till kommandot sprintf är en uppsättning tecken som resultatet ska skrivas in i. Nästa argument är en formatsträng som innehåller mixen oformatterad text, som Temp:, och formateringskommandon, som %d. I det här fallet betyder %d "signerat decimalt heltal". De återstående parametrarna kommer att ersättas i formatsträngen i den ordning som de visas i stället för formateringskommandona.

För att visa tiden på den andra raden på LCD-skärmen kan den bildas från individuella timmar, minuter och sekunder, som visas nedan:

sprintf(rad2, "Tid: %2d:%02d:%02d", h, m, s);

Om du försöker mata ut strängen line2 till serieportmonitorn eller till LCD-skärmen, kommer du att se texten

Kommandot sprintf ersatte inte bara siffror i rätt ställen, men även lagt till en inledande nolla före siffran 5. I exemplet, mellan tecknen: det finns formateringskommandon för de tre tidskomponenterna. Klockan motsvarar kommandot %2d, som skriver ut ett tvåsiffrigt decimaltal. Formatkommandona för minuter och sekunder är något annorlunda (%02d). Dessa kommandon matar också ut tvåsiffrigt decimaltal, men lägg till en inledande nolla om det behövs.

Tänk dock på att det här tricket är för värderingar typ int. Tyvärr implementerade Arduino-utvecklarna inte in standardbibliotek C stöd för andra typer som flöte.

Bestämma längden på en sträng

Eftersom strängar som lagras i teckenmatriser ofta är kortare än själva matriserna, tillhandahåller biblioteket en praktisk funktion som kallas strlen. Denna funktion räknar antalet tecken i arrayen som föregår nolltecknet som markerar slutet på strängen.

Funktionen tar en array av tecken i sin enda parameter och returnerar storleken på strängen (exklusive nolltecknet) som är lagrad i den, t.ex. kommandot

kommer att returnera nummer 3.

Arduino String Object Library

I Arduino IDE, sedan version 019, som släpptes för några år sedan, ingår String-biblioteket, vilket är mer förståeligt och vänligt för utvecklare som använder Java, Ruby, Python och andra språk där strängsammansättning är tillåten enkel operatör+. Detta bibliotek erbjuder också många hjälpfunktioner för att arbeta med strängar.

Säkert, givet bibliotek lägger till några kilobyte kod till skissen. Dessutom använder den en dynamisk minnesallokeringsmekanism med alla tillhörande problem såsom minnesutmattning. Så tänk noga innan du bestämmer dig för att använda den. Många Arduino-användare föredrar att använda vanliga teckenuppsättningar.

Det här biblioteket är otroligt lätt att använda, och om du någonsin har arbetat med strängar i Java kommer Arduino String Object Library att få dig att känna dig som hemma.

Skapa strängar

Du kan skapa en sträng från en rad element av typ röding, såväl som från ett int- eller flytvärde, som visas i följande exempel:

String message = "Temp: ";

String temp = String(123);

Strängsammansättning

Strängar av typen Sträng kan kombineras med varandra och med data av andra typer med hjälp av operatorn +. Försök att lägga till följande kod till den tomma skissens inställningsfunktion:

Serial.begin(9600);

String message = "Temp: ";

String temp = String(123);

Serial.println(meddelande + temp + "C");

Observera att det sista värdet som läggs till i strängen faktiskt är en uppsättning tecken. Om det första elementet i sekvensen av värden mellan +-operatorerna är en sträng, kommer de återstående elementen automatiskt att konverteras till strängar innan de sammanfogas.

Andra strängfunktioner

I tabell. 6.1 listar några fler bekväma funktioner från String-biblioteket. Full lista tillgängliga funktioner kan hittas på http://arduino.cc/en/Reference/StringObject.

Tabell 6.1. Några användbara funktioner i String-biblioteket

Fungera

Exempel

Beskrivning

char ch = String("abc")

Variabeln ch får värdet "a"

Strings = "abc";

Tar bort blanksteg från båda sidor av abc-teckengruppen. Variabeln s får värdet "abc"

String s = "123";

int x = s.toInt();

Konverterar strängrepresentationen av ett tal till ett int eller långt värde

String s = "abcdefg";

String s2 = s.substring(1, 3);

Returnerar ett fragment av den ursprungliga strängen. Variabeln s2 kommer att få värdet "bc". Parametrarna skickas: indexet för det första tecknet i fragmentet och indexet för det efterföljande tecknet sista karaktären fragment

String s = "abcdefg";

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

Ersätter alla förekomster av "de" i strängen med "DE". Variabel s2 kommer att ställas in på "abcDEfg"

Använder EEPROM

Innehållet i alla variabler som används i Arduino skiss, försvinner när strömmen stängs av eller en återställning utförs. För att lagra värdena måste de skrivas byte för byte till EEPROM-minnet. I Arduino Uno det finns 1 KB EEPROM-minne.

NOTERA

Detta gäller inte för Arduino-bräda Förfaller utan EEPROM. I denna modell bör data sparas på ett microSD-kort.

För att läsa och skriva data till EEPROM, måste du använda biblioteket som ingår i Arduino IDE. Följande exempel visar hur man skriver en enda byte till EEPROM, i det här fallet utförs operationen i inställningsfunktionen:

#omfatta

byte valueToSave = 123

EEPROM.write(0, valueToSave);

Det första argumentet till skrivfunktionen är EEPROM-adressen där databyten ska skrivas, och det andra argumentet är värdet för att skriva till den adressen.

Textsträngar kan deklareras på två sätt: du kan använda datatypen String, som ingår i kärnan sedan version 0019; eller deklarera strängen som en array av tecken med ett nolltecken i slutet. Den här sidan beskriver den andra metoden. För mer detaljerad information För String-objektet, som ger fler funktioner till priset av mer minne, se String - Object-sidan.

Exempel

Följande är exempel på korrekta strängdeklarationer.

Char Strl; 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";

char Str1 [15];

char Str2 [8] = ( "a", "r", "d", "u", "i", "n", "o");

char Str3 [8] = ( "a", "r", "d", "u", "i", "n", "o", "\0" );

char Str4 = "arduino" ;

char Str5 [ 8 ] = "arduino" ;

char Str6 [ 15 ] = "arduino" ;

Tillåtna operationer vid deklarering av strängar

  • Deklarera en uppsättning tecken utan att initialisera den (Str1)
  • Deklarera en array av tecken med ett redundant element, kompilatorn själv kommer att lägga till det nödvändiga nolltecknet (Str2)
  • Lägg till nolltecken uttryckligen (Str3)
  • Initiera en array med en strängkonstant omgiven av citattecken; kompilatorn kommer att skapa en array önskad storlek avslutas med ett nolltecken (Str4)
  • Initiera en array med en strängkonstant, explicit specificera dess storlek (Str5)
  • Initiera en överdimensionerad array och lämna utrymme för längre strängar (Str6)

Null avslutande tecken

Vanligtvis är alla strängar nollterminerade (ASCII-kod 0), vilket gör att funktioner (som Serial.print()) kan bestämma längden på en sträng. Utan detta tecken skulle de fortsätta att sekventiellt läsa byte av minne som inte längre faktiskt skulle vara en del av strängen.

I huvudsak betyder detta att din sträng måste vara 1 tecken längre än texten du vill att den ska innehålla. Det är därför Str2 och Str5 måste vara 8 tecken långa, även om ordet "arduino" bara tar upp 7 - den sista positionen fylls automatiskt med ett nolltecken. Storleken på Str4 kommer automatiskt att ändras till 8 - ett tecken krävs för den avslutande nollan. I strängen Str3 specificerade vi själva ett nolltecken (betecknat med '\0').

Observera att det i allmänhet är möjligt att deklarera en sträng utan ett avslutande nolltecken (till exempel genom att ställa in längden på Str2 till 7 istället för 8). Detta kommer dock att bryta de flesta strängfunktioner, så du bör inte göra det avsiktligt. Detta fel kan vara orsaken konstigt beteende eller utseendet på främmande tecken när du arbetar med strängar.

Enkla eller dubbla citattecken?

Strängar deklareras alltid i dubbla citattecken("Abc"), och tecken deklareras alltid inom enkla citattecken ('A').

Slår in långa rader

Långa rader kan slås in så här:

char myString = "Detta är den första raden" "detta är den andra raden" " etcetera";

char myString = "Detta är den första raden"

"det här är den andra raden"

" etc" ;

Uppsättningar av strängar

När man arbetar med stora volymer text (till exempel i projekt som fungerar med en LCD-skärm) är det ofta bekvämt att använda strängar. Eftersom strängar själva är arrayer är detta faktiskt ett exempel på en tvådimensionell array.

I följande program indikerar en asterisk efter att ha angett datatypen char "char*" att variabeln är en array av "pekare". Alla arraynamn är faktiskt pekare, så asterisken behövs för att skapa en array av arrayer. Pekare i C är en av de svåraste sakerna för nybörjare, men i det här fallet, en djup förståelse av pekare för dem effektiv användning krävs inte alls.

Exempel

char* myStrings=("Detta är sträng 1", "Detta är sträng 2", "Detta är sträng 3", "Detta är sträng 4", "Detta är sträng 5","Detta är sträng 6"); void setup()( Serial.begin(9600); ) void loop()( för (int i = 0; i< 6; i++){ Serial.println(myStrings[i]); delay(500); } }

char * myStrings = ( "Detta är sträng 1", "Detta är sträng 2", "Detta är sträng 3" ,

Jag kom till programmering i allmänhet, och Arduino programmering särskilt, fullständig noll, för ungefär två månader sedan. Nu, under min nuvarande aktivitet, kände jag ett behov av att bemästra bearbetningen av strängar på arduino. Den vanliga resan till Google för information behagade inte artikeln, där allt är enkelt och tydligt skrivet för dummies. Och det är därför jag är här för att prata om hur strängparsning från serieporten implementerades och vilka som möttes längs vägen undervattensstenar. Intresserad vänligen under kat.

Så. Här är ett exempel på en algoritm jag följde:

  1. Vi går till arduino.ru och letar i typkolumnen efter allt som har med symboler att göra.
  2. Vi bestämmer vilken form av representation vi ska använda (jag bestämde mig för String-klassen eftersom jag hade en dålig erfarenhet av array-röran).
  3. Vi försöker frenetiskt skriva vår egen funktion med preferens och professionella rutnät
  4. Letar efter en klass.
  5. Vi söker nödvändiga operatörer.
  6. Vi skriver!
Och algoritmen för programmets huvuddel är enkel:
  1. Kontrollera cykliskt om det finns i bufferten com-port läsbara bytes, om några, läsbara.
  2. Om den mottagna byten är ett radbrytningstecken ("\n"), anropar vi den självskrivna analysfunktionen, om inte, lägg till den mottagna byten till den skapade. typ variabel Sträng.
  3. Analysera slutligen strängen.

    Faktum är att praktisk användning Strängtolkning är avstängd för mig, alltså given funktionär endast demonstrativt genom att jämföra den mottagna strängen med en konstant sträng som redan finns lagrad i minnet. Så med hjälp av equals-operatorn jämför vi den mottagna strängen med den skrivna, och om operatorn returnerar sant avslutar vi hanterarfunktionen, om inte jämför vi den med nästa. Om strängarna är likvärdiga, avsluta återigen hanterarfunktionen och returnera resultatet. Tja, om detta villkor inte fungerar, kommer vi fortfarande att avsluta funktionen och säga att strängen inte är sann.

  4. Beroende på accepterat resultat med switch fallet välj den du behöver.
  5. Vi återställer den mottagna strängen, så att vi senare kan börja samla in den igen.

Och slutligen, här är koden:

#define led 13 String input_string = ""; const String Led_off = "stäng av lysdioden"; const String Led_on = "släck lysdioden"; 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 är: "); Serial.println(input_string); switch (parse(input_string, Led_off, Led_on)) (fall 10: led_running=false; Serial.println("Stängningen är klar"); break; fall 11: led_running=true; Serial.println("Slättningen är klar"); break; fall 0: Serial.println("ogiltig sträng"); 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) (return 10; ) else if (input_string.equals (Led_on ) == sant) (retur 11; ) annars returnerar 0; )


Så jag förstår inte vad som händer? Varför lyser inte lysdioden? Åh ja, hur glömde jag detta, du måste lägga till i ogiltig installation:

PinMode(led, OUTPUT);

P.S.: Det är viktigt att ställa in com-portmonitorn i Arduino IDE till " Ny linje", eftersom i någon annan kommer den skickade strängen inte att följas av dess terminator "\n".

P.P.S.: Jag tänker inte delta i holivaren om det faktum att arduino är onödigt, jag gjorde inget fel när jag studerade grunderna i programmering och algoritmisering.

P.P.P.S.: Om artikeln accepteras på ett tillfredsställande sätt, kommer jag att skriva nästa om vad som hände mig med förbättringen av funktionaliteten för analysfunktionen. Nåväl, med Gud! .

Jag kom till programmering i allmänhet, och Arduino-programmering i synnerhet, från grunden för ungefär två månader sedan. Nu, under min nuvarande aktivitet, kände jag ett behov av att bemästra bearbetningen av strängar på arduino. Den vanliga resan till Google för information behagade inte artikeln, där allt är enkelt och tydligt skrivet för dummies. Och det är därför jag är här för att prata om hur strängparsning från serieporten implementerades och vilka fallgropar man stötte på längs vägen. Intresserad vänligen under kat.

Så. Här är ett exempel på en algoritm jag följde:

  1. Vi går till arduino.ru och letar i typkolumnen efter allt som har med symboler att göra.
  2. Vi bestämmer vilken form av representation vi ska använda (jag bestämde mig för String-klassen eftersom jag hade en dålig erfarenhet av array-röran).
  3. Vi försöker frenetiskt skriva vår egen funktion med preferens och professionella rutnät
  4. Letar efter en klass.
  5. Vi söker nödvändiga operatörer.
  6. Vi skriver!

Och algoritmen för programmets huvuddel är enkel:

  1. Vi kontrollerar cykliskt om det finns bytes tillgängliga för läsning i com-portbufferten, i så fall läser vi det.
  2. Om den mottagna byten är ett radbrytningstecken ("n") anropar vi den självskrivna analysfunktionen, om inte, lägger vi till den mottagna byten till den skapade variabeln av typen String.
  3. Analysera slutligen strängen.

    Faktum är att Eftersom den praktiska användningen av strängparsning inte fungerar för mig, är denna funktion endast demonstrativ till sin natur, och jämför den mottagna strängen med en konstant sträng som redan finns lagrad i minnet. Så med hjälp av equals-operatorn jämför vi den mottagna strängen med den skrivna, och om operatorn returnerar sant avslutar vi hanterarfunktionen, om inte jämför vi den med nästa. Om strängarna är likvärdiga, avsluta återigen hanterarfunktionen och returnera resultatet. Tja, om detta villkor inte fungerar, kommer vi fortfarande att avsluta funktionen och säga att strängen inte är sann.

  4. Beroende på accepterat resultat växla fall välj den du behöver.
  5. Vi återställer den mottagna strängen, så att vi senare kan börja samla in den igen.

Och slutligen, här är koden:

#define led 13 String input_string = ""; const String Led_off = "stäng av lysdioden"; const String Led_on = "släck lysdioden"; 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 är: "); Serial.println(input_string); switch (parse(input_string, Led_off, Led_on)) (fall 10: led_running=false; Serial.println("Avstängning är klar"); break; case 11: led_running=true; Serial.println("Sättningen är klar"); break; fall 0: Serial.println("ogiltig sträng"); 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) (return 10; ) else if (input_string.equals( Led_on) == sant) (retur 11; ) annars returnerar 0; )

Så jag förstår inte vad som händer? Varför lyser inte lysdioden? Åh ja, hur glömde jag detta, du måste lägga till i ogiltig installation:

PinMode(led, OUTPUT);

P.S.: Det är viktigt att ställa in com-portmonitorn i Arduino IDE till New Line-läge, eftersom i någon annan kommer den skickade strängen inte att följas av dess terminator "n".

P.P.S.: Jag tänker inte delta i holivaren om det faktum att arduino är onödigt, jag gjorde inget fel när jag studerade grunderna i programmering och algoritmisering.

P.P.P.S.: Om artikeln accepteras på ett tillfredsställande sätt, kommer jag att skriva nästa om vad som hände mig med förbättringen av funktionaliteten för analysfunktionen. Nåväl, med Gud! .

Textsträngar kan deklareras på två sätt: du kan använda datatypen String, som ingår i kärnan sedan version 0019; eller deklarera strängen som en array av tecken med ett nolltecken i slutet. Den här sidan beskriver den andra metoden. För mer information om String-objektet, som ger fler funktioner till priset av mer minne, se String - Object-sidan.

Exempel

Följande är exempel på korrekta strängdeklarationer.

Char Strl; char Str2 = ("a", "r", "d", "u", "i", "n", "o"); char Str3 = ("a", "r", "d", "u", "i", "n", "o", " char 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"; "); char Str4 = "arduino"; char Str5 = "arduino"; char Str6 = "arduino";

Tillåtna operationer vid deklarering av strängar

  • Deklarera en uppsättning tecken utan att initialisera den (Str1)
  • Deklarera en array av tecken med ett redundant element, kompilatorn själv kommer att lägga till det nödvändiga nolltecknet (Str2)
  • Lägg till nolltecken uttryckligen (Str3)
  • Initiera en array med en strängkonstant omgiven av citattecken; kompilatorn kommer att skapa en array med önskad storlek med ett nolltecken i slutet (Str4)
  • Initiera en array med en strängkonstant, explicit specificera dess storlek (Str5)
  • Initiera en överdimensionerad array och lämna utrymme för längre strängar (Str6)

Null avslutande tecken

Vanligtvis är alla strängar nollterminerade (ASCII-kod 0), vilket tillåter funktioner (som Serial.print()) bestäm längden på strängen. Utan detta tecken skulle de fortsätta att sekventiellt läsa byte av minne som inte längre faktiskt skulle vara en del av strängen.

I huvudsak betyder detta att din sträng måste vara 1 tecken längre än texten du vill att den ska innehålla. Det är därför Str2 och Str5 måste vara 8 tecken långa, även om ordet "arduino" bara tar upp 7 - den sista positionen fylls automatiskt med ett nolltecken. Storleken på Str4 blir automatiskt 8 - ett tecken krävs för att avsluta null. I strängen Str3 specificerade vi själva ett nolltecken (betecknat med "\0").

Observera att det i allmänhet är möjligt att deklarera en sträng utan ett avslutande nolltecken (till exempel genom att ställa in längden på Str2 till 7 istället för 8). Detta kommer dock att bryta de flesta strängfunktioner, så du bör inte göra det avsiktligt. Ett sådant fel kan orsaka konstigt beteende eller uppkomsten av tecken från tredje part när du arbetar med strängar.

Enkla eller dubbla citattecken?

Strängar deklareras alltid med dubbla citattecken ("Abc"), och tecken deklareras alltid med enkla citattecken ("A").

Slår in långa rader

Långa rader kan slås in så här:

Char myString = "Detta är den första raden" "det här är den andra raden" " etcetera";

Uppsättningar av strängar

När du arbetar med stora mängder text (till exempel i projekt som fungerar med en LCD-skärm) är det ofta bekvämt att använda arrayer av strängar. Eftersom strängar själva är arrayer är detta faktiskt ett exempel på en tvådimensionell array.

I följande program indikerar asterisken efter datatypen char "char*" att variabeln är en array av "pekare". Alla arraynamn är faktiskt pekare, så asterisken behövs för att skapa en array av arrayer. Pekare i C är en av de svårare sakerna för nybörjare, men i det här fallet krävs inte alls en djup förståelse för pekare för att använda dem effektivt.

Exempel

char* myStrings=("Detta är sträng 1", "Detta är sträng 2", "Detta är sträng 3", "Detta är sträng 4", "Detta är sträng 5","Detta är sträng 6"); void setup()( Serial.begin(9600); ) void loop()( för (int i = 0; i< 6; i++){ Serial.println(myStrings[i]); delay(500); } }