Lesson 30. Text strings in Arduino. Converting data to strings and vice versa. String class.

Text strings

In the lesson, I will tell you about text strings in Arduino, about the String class, about converting various data types to text strings, and about the reverse operation-converting strings to numbers.

Previous lesson     List of lessons     Next lesson

I was going to develop a stepper motor driver with computer control, but I came across a topic that was necessary for development, which we have not yet studied. So for one lesson, I'll take a break from stepper motors and talk about text strings and operations with them.

 

Text strings in Arduino.

A text string is an array of characters that ends with a special character that indicates the end of the string. This attribute is necessary so that the functions of working with strings determine where the characters of the string end and do not read extra data that does not belong to it.

In Arduino, the end-of-line sign is the number 0, in the text form '\0'.
When declaring string variables, in some cases it is necessary to explicitly specify the end-of-line attribute, and in some cases it is formed by default.

Methods to declare and initialize text strings.

char myStr1 [10];

A fixed-size character array is declared. When filling it with characters, you need to take care of writing at the end of the string a byte with the value 0 – the end-of-line attribute.

char myStr2 [6] = {‘S’, ‘t’, ‘a’, ‘r’, ‘t’};

The array is declared and assigned a value to the elements. At the end of the line, the compiler will add the end-of-line attribute automatically.

char myStr3 [6] = {‘S’, ‘t’, ‘a’, ‘r’, ‘t’, '/ 0 ’};

The same thing, but we declared the end of the string explicitly.

char myStr4 [] = “Start”;

The array is initialized with a string constant. The compiler will automatically set the size of the array and add a trailing character.

char myStr5 [6] = “Start”;

The same thing, only the size of the array is specified explicitly.

charmyStr 6 [20] = “Start”;

You can explicitly specify a larger array size, for example, if it will be used for strings of different lengths.

  • String constants are declared inside double quotes (”Start”).
  • Individual characters are specified inside single quotes ('S').

Long strings can be declared as follows:

char myStr7 [] = “Text string may be”
“declared”
" thus";

Nothing prevents specifying arrays of strings. Because strings themselves are arrays, string arrays will be two-dimensional arrays.

char * myStrArray = {“Message 1”, “Message 2”, “Message 3”, “Message 4”, “Message 5”, “Message 6”};

Arrays of strings are declared as arrays of pointers. This is because the strings can have different lengths, and you have to reserve a two-dimensional data array designed for the longest string. And pointers require the same number of memory cells.

Control characters.

Text strings can contain not only text characters, but also control characters. Control characters are not displayed on the screen in graphical form. They are used to control data transfer and display. There are several dozen such characters. I will note the most important ones.

Character code
HEX (DEC)
Name Designation Description
0 (0) End of line \0 End of line character
0D (13) Carriage return \r Moves the cursor to the left most position
0A (10) Line Feed \n Moves the cursor one line down

To display text in a new line, use the characters ' \r 'and'\n'.

A simple program that demonstrates how to use control characters to print from a new line.

// control characters
void setup() {
  Serial.begin(9600); // rate 9600
}

void loop() {
  Serial.println("\r\n Begin \r\n next string"
"\r\n 3 empty strings \r\n\r\n\r\n"); // display the message in several line
  delay(1000);
}

On the serial port monitor screen we will see:

Begin
next string
3 empty strings

Often the control characters '\ r' and '\ n' are used to terminate a command in character form, such as AT commands. We will use this control method in the next lesson for a stepper motor driver.

Converting various types of Arduino data to a text string.

  • The task of converting various data types to symbolic form and vice versa occurs:
    when outputting data to a display;
  • transferring data to other devices, such as a computer;
  • some electronic components require data exchange using AT commands in symbolic form, for example, GSM modems, WiFi modules, etc.

There are many ways to solve this problem. I will describe in detail several of them, in my opinion, the most successful.

Converting data to a string using the built-in functions of the I / O classes.

It is the most convenient, preferred way to convert data to characters. Many I / O libraries have functions for converting data to text format.
If you need to transfer data through the serial port, why not use the standard functions of the Serial class (lesson 12).

Conversion Function of the Sreial class Description
int to DEC text print(int d) Converts an int variable to a decimal string
int to DEC text print(int d, DEC) Converts an int variable to a decimal string
int to HEX text print(int d, HEX) Converts an int variable to a hexadecimal string
int to OCT text print(int d, OCT) Converts an int variable to an octal string
int to BIN text print(int d, BIN) Converts an int variable to an octal string
float totext print(float d) Converts a float variable to a string with two decimal places
float totext print(float d, N) Converts a float variable to a string with N decimal places

For example, converting an int number to a string would look like this.

int x= 24562;
Serial.print(x);

Converting a float variable to a string can be done like this.

float x= 12.657;
Serial.print(x);

The conversion will be performed when transferring data to another device. The functions of the Serial class are described in detail in Lesson 12.

To output data to the LCD display using the LiquidCristal library, you can use the print method with the same parameters (lesson 23).

Converting integer data to a string using the itoa, ltoa, ultoa functions.

The functions are simple, they allow you to convert numbers of integer formats to a text string.

itoa (int data, char * string, int radix); // int conversion
ltoa (long data, char * string, int radix); // long conversion
ultoa (unsigned long data, char * string, int radix); // unsigned long conversion

  • data - the variable being converted;
  • char * string - a pointer to the string (array name);
  • radix - notation system of result in the string:
    •  10 for DEC;
    •  8 for OCT;
    •  16 for HEX;
    •  2 for BIN.

For example, converting int variable x to the string myStr1 can be done like this.

itoa (x, myStr1, 10); // in decimal
itoa (x, myStr1, 8); // in octal
itoa (x, myStr1, 16); // in hexadecimal
itoa (x, myStr1, 2); // in binary

Here is a program to test these functions.

// testing the conversion of a number to a text string
int x=0; // variable that is displayed
char myStr[20]; // text array

void setup() {
  Serial.begin(9600); // rate 9600
}

void loop() {
  // preparing the string buffer
  for (int i=0; i<20; i++) {myStr[i]=' ';} // filling with spaces
  myStr[18]='\r'; // carriage return
  myStr[19]='\n'; // line feed

  // converting variable int x
  itoa(x, myStr, 10); // int -> DEC
  //itoa(x, myStr, 8); // int -> OCT
  //itoa(x, myStr, 16); // int -> HEX
  //itoa(x, myStr, 2); // int -> BIN

  // converting variable long x
  //ltoa(x, myStr, 10); // long -> DEC
  //ltoa(x, myStr, 8); // long -> OCT
  //ltoa(x, myStr, 16); // long -> HEX
  //ltoa(x, myStr, 2); // long -> BIN

  // converting variable unsigned long x
  //ultoa(x, myStr, 10); // long -> DEC
  //ultoa(x, myStr, 8); // long -> OCT
  //ultoa(x, myStr, 16); // long -> HEX
  //ultoa(x, myStr, 2); // long -> BIN

  Serial.write(myStr, 20);
  x++;
  delay(500);
}

In the cycle, every 0.5 seconds occurs:

  • The text string myStr is filled with spaces, the carriage return and line feed control characters are added at the end.
  • The variable x is converted by one of the functions. The result ends up in the buffer myStr.
  • Serial.write(myStr, 20) function sends 20 bytes of the myStr array as bytes over the serial port.
  • Adds 1 to the variable x.

To test the desired function, you need to release it from the comment attribute. I checked all of them.

Converting data to a string using the sprintf function.

This is the most convenient, versatile method. The disadvantage of this method is that the sprintf function just devours the resources of the microcontroller. It is better not to use it in time-critical and memory-critical applications.

sprintf is a formatted output function. It is widely used in applications on computers. It provides the widest possibilities for converting data to a text string. But on the Arduino system, sprintf does not support floating point format.

int sprintf( char *string, const char *format , argument1, argument2 ... )

The function returns the number of converted characters. In case of an error, it returns a number – 1.

  • argument - these are the variables to be converted;
  • format - control line: % [flag] [width] format_type.

Flag and width - optional fields.

Format type Output data type
c Character
s Character string
d, i Decimal integer
u Unsigned decimal integer
o Octal integer
x hexadecimal integer

Flags.

Sign Action
- Align the result to the left
+ Displays the sign of a number
Пробел Displays a space  before positive numbers
0 Fills the field with 0

Width - the minimum size of the field for displaying characters. If the length of the number is less, then spaces are added. If there is a 0 in front of the width, zeros are added.

The examples from the table should make everything clear.

int x= 125; int y= 34;

Function Will Output to myStr
sprintf(myStr2,"%d",x ); 125
sprintf(myStr2,"%5d",x );   125
sprintf(myStr2,"%05d",x ); 00125
sprintf(myStr2,"%+05d",x ); +00125
sprintf(myStr2,"Cycle %d is over",x ); Cycle   125 is over
sprintf(myStr2,"Cycle %d is over y= %d",x,y ); Cycle   125 is over y= 34
sprintf(myStr2,"%o",x ); 175
sprintf(myStr2,"%x",x ); 7d

You can download the following program and test how sprintf works in a real Arduino controller.

// testing the conversion of a number to a text string
// using sprintf
int x=0; // variable that is displayed
char myStr[20]; // text array

void setup() {
  Serial.begin(9600); // rate 9600
}
void loop() {
  // preparing the string buffer
  for (int i=0; i<20; i++) {myStr[i]=' ';} // filling with spaces
  myStr[18]='\r'; // carriage return
  myStr[19]='\n'; // line feed

  // converting variable int x
  sprintf(myStr,"%d",x ); // int -> DEC
  //sprintf(myStr,"%5d",x ); // int -> DEC
  //sprintf(myStr,"%05d",x ); // int -> DEC
  //sprintf(myStr,"%+05d",x ); // int -> DEC
  //sprintf(myStr,"Cycle %d is over",x ); // int -> DEC with text
  //sprintf(myStr,"%o",x ); // int -> OCT
  //sprintf(myStr,"%x",x ); // int -> HEX
  Serial.write(myStr, 20);
  x++;
  delay(500);
}

Converting float data into a text string.

The easiest way to convert float to text string is using the dtostrf function.

char * dtostrf (double data, signed char width, unsigned char prec, char * string)

  • data is the variable being converted;
  • width - number of significant digits;
  • prec - the number of decimal places;
  • char * string - pointer to string (array name).

float x = 12.728;
dtostrf(x, 2, 3, mystr3); / / output 2 digits before, 3 digits after the decimal point to the string mystr3

Here is a program to test this method.

// testing the conversion of a number to a text string
// using dtostrf
float x=0; // variable that is displayed
char myStr[20]; // text array

void setup() {
  Serial.begin(9600); // rate 9600
}

void loop() {
  // preparing the string buffer
  for (int i=0; i<20; i++) {myStr[i]=' ';} // filling with spaces
  myStr[18]='\r'; // carriage return
  myStr[19]='\n'; // line feed

  // converting variable float into a string
  dtostrf(x, 2, 3, myStr);

  Serial.write(myStr, 20);
  x+= 0.01;
  delay(500);
}

Converting a text string to various data types.

The next section deals with the reverse conversion - a text string to a number.

Converting a string to data using the atoi, atol, atof functions.

Nice, convenient method. The functions are simple and have the form:

int atoi (const char * string); // convert to int
long atol (const char * string); // convert to long
double atof (const char * string); // convert to float

The function argument is a pointer to a string with a decimal number. Return is the converted number value.

For example, converting the string myStr4 to a variable x of type int would look like this.

int x;
x = atoi (myStr4);

For floating point numbers.

float x;
x = atof (myStr4);

Here is a program for testing atoi and atol.

// testing the conversion of a text string to a number
// using atoi
char myStr[]= "123"; // text array

void setup() {
  Serial.begin(9600); // rate 9600
}

void loop() {
  Serial.println(atoi(myStr)); // converting string to int
  //Serial.println(atol(myStr)); // converting string to long
  delay(1000);
}

And with the help of this program, I checked the work of atof.

// testing the conversion of a text string to a number
// using atof
char myStr[]= "123.456"; // text array

void setup() {
  Serial.begin(9600); // rate 9600
}

void loop() {
  Serial.println(atof(myStr),3); // converting string to float
  delay(1000);
}

Converting a text string to number using the sscanf function.

This function is an inverse of sprintf with the same disadvantages and advantages. But it allows you to convert numbers in octal and hexadecimal formats. This function does not support the float type on Arduino.

int sscanf (char * string, const char * format, address1, address2 ...)

All arguments and formats are the same as for sprintf. Only variable addresses are specified (address1, address2 ...).

Converting the string myStr5 to a variable x of type int will look like this.

int x;
sscanf (myStr5, "% d", & x); // for decimal numbers
sscanf (myStr5, "% o", & x); // for octal numbers
sscanf (myStr5, "% x", & x); // for hexadecimal numbers

Here is a sketch of the function test for integer operations.

// testing the conversion of a text string to a number
// using sscanf
int x;
char myStr[]= "123"; // text array

void setup() {
  Serial.begin(9600); // rate 9600
}

void loop() {
  sscanf(myStr,"%d", &x);
  Serial.println(x); // converting string to int
  delay(1000);
}

String class in Arduino.

There is String class in Arduino. It provides more advanced options for working with text strings.

It is necessary to clearly distinguish:

  • char myStr [] = “Start”; - a character string, i.e. an array of type char with a terminating attribute at the end;
  • String MyStr = Start ”; - an instance of the String class.

It is customary for text string names to start as normal variables with a lowercase letter (myStr), and String instances with a capital letter (MyStr).
Instances of the String class take up more memory, are slower to process, but they do allow you to expand, concatenate, search, replace characters, and more. Whether you use text strings or the String class is up to you. For resource-optimized applications, it is better to use strings.

A few basic functions of the String class.

I will describe only the minimum functions required to work with the String class.

String ()

Constructor, creates an instance of the String class. An object of type String can be created from different data types:

String MyStr1 = "Start"; // initialize the string constant
String MyStr2 = String ('d'); // convert character to String object
String MyStr3 = String ("Start"); // convert string constant to String object
String MyStr4 = String (MyStr1 + "in 10 sec"); // concatenate two strings
String MyStr5 = String (67); // use an integer constant
String MyStr6 = String (analogRead (1), DEC); // use int with base 10
String MyStr7 = String (346, BIN); // use int with base 2
String MyStr8 = String (89, HEX); // use int with radix 16
String MyStr9 = String (millis (), DEC); // using long with radix 10

When creating an object from a number, the generated string will contain the ASCII (character) representation of the number. The default is decimal, but you can specify a different one. Those. the String function can convert integer data to a text string.

toCharArray (* buf, length)

Copies the text of an instance of the String class into the specified array.

MyStr.toCharArray (* buf, length)

  • buf - pointer to an array;
  • length - the number of characters.

MyStr.toCharArray (myStr, 10); // copy 10 characters to myStr array

int length ()

The function returns the length of the String in characters without taking into account the terminating sign of zero.

int len = MyStr.length (); // get the length of the string MyStr

long toInt ()

The function converts a String object to an integer.

int x = MyStr.toInt (); // convert string MyStr to int

Converting data to a String.

It's very simple for integer formats.

String MyStr;
int x;
MyStr = String (x, DEC); // for decimal numbers
MyStr = String (x, HEX); // for hexadecimal numbers
MyStr = String (x, BIN); // for binary numbers

Program for testing.

// check converting a number to String
int x=0; // variable that is displayed
String MyStr;

void setup() {
  Serial.begin(9600); // rate 9600
}

void loop() {
  MyStr= String(x, DEC); // int -> DEC
  //MyStr= String(x, HEX); // int -> HEX
  //MyStr= String(x, BIN); // int -> BIN

  Serial.println(MyStr);
  x++;
  delay(500);
}

For floating point, use the dtostrf () function. Using it, get an array string, and then enter it into a String object.

float x = 2.789;
StringMyStr;
char myStr8 [10];
dtostrf (x, 2, 3, myStr8); // output in the string myStr8 2 digits before, 3 digits after the decimal point
MyStr = myStr8;

Program for checking the float conversion.

// check converting a number to String
float x=0; // variable that is displayed
String MyStr;
char myStr[10];

void setup() {
  Serial.begin(9600); // rate 9600
}

void loop() {
  dtostrf(x, 2, 3, myStr); // output in the string myStr8 2 digits before, 3 digits after the decimal point
  MyStr = myStr;

  Serial.println(MyStr);
  x += 0.01;
  delay(500);
}

Converting String to various data types.

For integers, use the toInt () function.

String MyStr = "123";
int x = MyStr.toInt ();

Testing.

// testing String to number conversion
// using toInt
String MyStr = "123";

void setup() {
  Serial.begin(9600); // rate 9600
}

void loop() {
  Serial.println(MyStr.toInt()); // converting String to int
  delay(1000);
}

For floating point.

Let's get the data from the String object into an array and perform the conversion using the atof () function.

String MyStr = "34.123";
char myStr8 [10];
MyStr.toCharArray (myStr8, MyStr.length ()); // copy String to myStr8 array
float x = atof (myStr8); // convert to float

Program for checking.

// testing String to number conversion
// с помощью atof
String MyStr = "34.123";
char myStr[10];

void setup() {
  Serial.begin(9600); // rate 9600
}

void loop() {
  MyStr.toCharArray(myStr, MyStr.length());
  Serial.println(atof(myStr)); 
  delay(1000);
}

I have given quite a few different ways to convert data to strings and vice versa. Choose, invent your own.

In the next lesson, we'll get back to stepper motor control.

Previous lesson     List of lessons     Next lesson

Leave a Reply

Your email address will not be published. Required fields are marked *