HowTo: Arduino - Possibilities of the serial port

Normally every Arduino board is programmed via the serial interface.
But not only the program code can be transferred to the Arduino. You can also send control commands to or receive values from the Arduino.

How to do that and what options you have in the following article.

Hints for our lovely english readers: Basically, many of the articles on Nerdiy.de are translations from the original german articles. Therefore, it may happen here and there that some illustrations are not available in english and that some translations are weird/strange/full of mistakes or generally totaly wrong. So if you find some obvious (or also not obvious) mistakes don't hesitate to leave us a hint about that in the comment section. 
Also please don't get confused, that instead of a "dot" often a "comma" is used as decimal separator. 🙂


Safety instructions

I know the following hints are always a bit annoying and seem unnecessary. But unfortunately, many people who knew it "better" from carelessness lost their eyes, fingers or other things or hurt themselves. In comparison, a loss of data is almost not worth mentioning, but even these can be really annoying. Therefore, please take five minutes to read the safety instructions. Even the coolest project is worth no injury or other annoyance. https://www.nerdiy.de/en/sicherheitshinweise/

Affiliate links / advertising links

The links to online stores listed here are so-called affiliate links. If you click on such an affiliate link and store via this link, Nerdiy.de receives a commission from the online store or provider concerned. The price doesn't change for you. If you do your purchases via these links, you will support Nerdiy.de in being able to offer further useful projects in the future. 🙂


Prepare serial interface

To use the serial interface in your program you have to initialize it.
This is done by setting the following function in the "setup()" function

Serial.begin(115200);

The number "115200" stands for the baud rate - ie the speed - with which the symbols are transmitted via the serial interface. You should make this speed dependent on the "quality" of the connection line.

For example, if you have a shielded and very short cable, the speed can be set very high.
For non-shielded and/or very long cables, this speed should not be so high.

Common baud rates are, for example, the following values:

50
110
150
300
1200
2400
4800
9600
19200
38400
57600
115200
230400
460800
500000

No matter what speed you set, this value must also be set in the "serial monitor" - the other communication partner of the serial communication. Only then will the characters be received and sent correctly. Learn more about this in the course of the text.

If you are unsure which baud rate to use, I recommend values between 9600 baud and 115200 baud. These and the values in between are also the common values for many finished products such as sensors and actuators.


Send data from the Arduino board to the connected computer

To be able to send data from your Arduino board to the connected computer you need to execute the following function.

This sends the text "Hallo welt!"(German for "Hello world!") including line break to the computer.

Serial.println("Hello world!");

As an example you can try the following code.

void setup() { Serial.begin(115200); } void loop() { Serial.println("Hello world!"); delay(1000); }
This will give you the illustrated output. After every "Hello world!" a linebreak to the next line is made automatically.

In the following combination, the function sends the text "Hello World!" without a line break to the computer.

Serial.print("Hello world!");

There is another example.

void setup() { Serial.begin(115200); } void loop() { Serial.print("Hello world!"); delay(1000); }
Now, after the "Hallo Welt!" no line break is made, a long line is created from several "Hello Welt!" sections.

If you want to send variable values – in this case the value of the variable “merry_variable”(German for “funny_variable”) – you can do this as follows:

uint8_t funny_variable=5; Serial.println(String(funny_variable));

As an example, the whole thing looks like this again.

void setup() { Serial.begin(115200); } void loop() { uint8_t funny_variable=5; Serial.println(String(funny_variable)); delay(1000); }
The value (5) of the variable is output including the line break.

Sending a line break means that, in addition to the actual message content, a control character is sent along that signals the recipient to switch to the next line.


Use serial monitor

The serial monitor is the counterpart to the Arduino board. It is the program which receives the data on the computer and makes it readable for you.
You will find it as part of the Arduino IDE under the menu item "Tools / Serial Monitor". Tools like this "serial monitor" are also called terminal programs. A good alternative to the "serial monitor" of the Arduino IDE is also the program HTERM.

The line monitor and baud rate can be set in the Serial Monitor window. By clicking on "Delete output", the content of the output window can also be deleted.

The baud rate can be set in the window of the serial monitor. Here, the same value must be set that you have previously set in the program code.
Do you have the command

Serial.begin(115200);

used in your arduino code so you have to set in the serial monitor the same baud rate of 115200 baud.

In addition to the baud rate, the line terminator can also be set. You only need this setting if you want to send data from the computer to the Arduino.

Namely, the character can be set here, which is automatically appended and sent after each sending of a value.

For example, you can use this in your code very well to see on the Arduino whether the transfer of a command or value is completed.

This is explained in detail in the section "Sending commands and parameters to the Arduino".


Use serial plotter

The serial plotter is a tool that allows you to display numerical values (such as readings) directly on the computer as a timeline. For this you have to program the Arduino so that it sends the numerical values to the computer.
This can be done, for example, with the command:

Serial.println(VariableWithAReading);

Of course, the variable "VariableMitEinemMesswert"(German for "VariableIncludingAMeasuredValue") should contain your metric as a number.
On the computer you have to start the serial plotter. You can find this under "Tools / Serial Plotter".

A simple example that outputs a sine curve on the serial plotter is the following. Just try the code. It should let work on every Arduino. Remember to set your "Serial Plotter" to 115200 baud.

/* _ _ _ _ _ | | | | |(_) | | __ ____ ____ __ | | | ___ _ __ __| | _ _ _ __| | ___ / / / / / / / / / | . ` | /_ | '__|/ _` || || | | | / _` | / _ VV / VV / VV /_ | | || __/| | | (_| || || |_| | _| (_| || __/ _/_/ _/_/ _/_/(_)|_| _| ___||_| __,_|| _| __, |(_)__,_| ___| __/ | |___/ sinusTest by Fabian Steppat Infos on https://www.nerdiy.de/ardunio-the-serial-interface/ This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version that it will be useful, but WITHOUT ANY WARRANTY;without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.See the GNU General Public License for more details.You should have received a copy of the GNU General Public License along with this program.If not, see . You will find additional information about this project at the following address:
     
HowTo: Ardunio – Use the serial port
This codesnippet prints a sine wave via serial console or serial plotter */ //variables and constants float degreeAngle = 0; float sinusValue = 0; const float pi = 3.1415; float radianAngle = 0; const uint8_t sinusFactor = 50; void setup() { Serial.begin(115200); } void loop() { radiantAngle = degreeAngle * pi / 180; //making deg in radians sinusValue = sin(radiantAngle); //calculate sine from radiant angle degreeAngle += 1.0; //increase the angle delay(5); //make output a bit slower if (degreeAngle > 360) //if degree boundary is reached reset it to zero { degreeAngle = 0; } Serial.println(sinusFactor * sinusValue); //output to serial monitor/plotter }
The above example should show the mapped sinusoid on the serial plotter.

The plotter works not only with sine but also with all other numbers.


Send commands and parameters to the Arduino

So now you know how to send various status messages or values ​​from the Arduino to the computer.
But this works the other way around too. This is especially useful or practical, if you control the Arduino from the outside and do not want to connect input devices such as buttons and Co. to the Arduino (or for lack of GPIOs).

For example, you can adjust the brightness or color of an LED or even a motor speed of a connected motor via the serial interface.

For communication via the serial interface, the Arduino IDE provides some useful functions. (You can find the documentation with more details here: https://www.arduino.cc/reference/en/language/functions/communication/serial/)

There are now three tasks to be solved for receiving and evaluating commands:
1. How does the Arduino recognize received characters?
2. How are complete commands composed from the received characters?
3. How can these received commands be evaluated?

1. How does the Arduino recognize received characters

In order to respond to incoming characters, there is the function

Serial.available()

This checks if new characters are contained in the receive buffer of the Arduino. The receive buffer is a kind of buffer in which received characters are stored until the microcontroller of the Arduino has time to "take care" of the them.

In the event that new characters have been received but not yet read from the receive buffer, the function "Serial.available ()" returns "true" otherwise "false".

This function is therefore perfect for checking if characters were currently being received, which now have to be evaluated. The command does not tell us how many characters were received. He just says that there is at least one character in the receive buffer.

2. How do the received characters become complete commands?

Well, now we have recognized thanks to the previous function that at least one character is available in the receive buffer. But how do we get the received ones?

Characters from the receive buffer can be read with the command

Serial.read()

The function outputs the first character contained in the receive buffer and removes it automatically from the receive buffer.
In order to read out all characters and to write them into a variable, we now read from the receive buffer until it is empty and remember each read character.
This can be done with a loop, for example like this:

void check_serial_receive() { String serialbuffer; while (Serial.available()) { char currentChar = (char)Serial.read(); if (currentChar == 13) //check if the read character is the line terminator { evaluate_received_characters(serialbuffer); } else { serialbuffer += currentcharacter; } } }

As you can see, the code consists of a while loop that runs until the receive buffer is empty (then Serial.available () returns false).
Meanwhile, within the while loop, the characters contained on the receive buffer are read out character by character (Serial.read()), assigned to the variable "currentCharacter" and appended to the string "serialrBuffer" (German for "serialBuffer").

This is where the line terminator mentioned in the "Serial Monitor" section comes into play. In this (and any other terminal program) you can set a character, which is automatically attached and sent after each character or string.

This line terminator can now be used to detect whether the previously read string is completed and thus can be evaluated.
This means that every character received must be checked to see if it is the line terminator. In the code shown above, this is done by

if (currentChar == 13)...

Do not get confused by the 13. The problem with line terminators is that they are not listed on a keyboard. So you can not type them into the code as comparison characters.
In order to check the character received for the character closing character we use a trick here.

Thanks to the ASCII table, we know that every character in the computer corresponds to a byte value (that is, a numeric value between 0 and 255).
For example, if you store an "A" in Arduino, it will actually store the number "65".
If one wanted to check now whether a received sign corresponds to an "A" one could either check

if (currentcharacter == "A")

or

if (currentcharacter == 65)

Both comparisons would lead to the same result.

We are now taking advantage of this trick. To check whether the currently received character is a line terminator, such as the CR (= CarriageReturn), we check not for the character itself but for the value of the character in the Ascii table: So 13.

As soon as this character has been received, we know that all previously sent characters should represent a command and must now be evaluated.

3. How can these received commands be evaluated

We or the Arduino has now received a command. This is stored in the string variable "serial buffer" and is passed as a function parameter to the function "Evulate_received_characters").

For example, this feature might look like this:

void evaluate_received_characters(string serialbuffer) { Serial.println(""" + String(serialbuffer) + "" received."); //Output of the command just received if (serial buffer == "simpleCommandTheWhatDoes") { simpler_command_the_what_does(); } else if (serialBuffer.indexOf('=') != -1) { uint16_t receivedValue = serialBuffer.substring(serialBuffer.indexOf('=') + 1).toInt(); String of received parameters = serialbuffer.substring(0, serialbuffer.indexOf('=')); if (receivedParameter == "commandOfSetsAValue") { if (receivedValue = 0) { command_that_sets_a_value(receivedValue ); } else { Serial.println(F("Value outside the allowed value range.")); } } else { Serial.print(F("The command "")); Serial.print(serial buffer); Serial.print(F("" was not recognized.")); } } else { Serial.print(F("The command "")); Serial.print(serial buffer); Serial.print(F("" was not recognized.")); } }

After receiving a command, it will be printed again, which is very convenient for debugging purposes. So you can check which string has finally arrived in the Arduino.

Then it can be checked with a simple If query which string corresponds to the received command. Here, for example, it is checked whether the command of the character string corresponds to "simpleCommandThatDoesSomething"(German for "simpleCommandThatDoesSomething").
If this is the case, the function "simple_command_that_does_what();" will be executed.

Using these "absolute" commands, you could now issue simple commands. For example, to turn a light on or off.

In order to be able to transfer values, commands of the form "brightness_set = 20" must also be evaluated.
So the command name (in this case "brightnessOnOn") and the value (in this case "20") must be recognized.

This is done in the rest of the code shown above.
If none of the "absolute" commands match the received string, it will be checked if there is an "=" character in the received string.

For example, if you have sent the command "setBrightness=100" to the Arduino, it will not be able to match the entire string "setBrightness=100" to any "absolute" command.

In this case, the string received is therefore examined for an equal sign.

The received string is then decomposed with the following commands into the part before and after the equal sign.

uint16_t receivedValue = serialbuffer.substring(serialbuffer.indexOf('=') + 1).toInt(); String of received parameters = serialbuffer.substring(0, serialbuffer.indexOf('='));

Now in the variable "ReceivedValue"(German for "receivedValue") the "100" and in the variable "ReceivedParameter"(German for "receivedParameter") the instruction "setBrightness" is stored.

Once extracted from the string received, the two values can then be further processed and responded to.

just try it 🙂
You can find all the code to try again here:

/* _ _ _ _ _ | | | | |(_) | | __ ____ ____ __ | | | ___ _ __ __| | _ _ _ __| | ___ / / / / / / / / / | . ` | /_ | '__|/ _` || || | | | / _` | / _ VV / VV / VV /_ | | || __/| | | (_| || || |_| | _| (_| || __/ _/_/ _/_/ _/_/(_)|_| _| ___||_| __,_|| _| __, |(_)__,_| ___| __/ | |___/ serialTest by Fabian Steppat Infos on https://www.nerdiy.de/ardunio-the-serial-interface/ This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version that it will be useful, but WITHOUT ANY WARRANTY;without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.See the GNU General Public License for more details.You should have received a copy of the GNU General Public License along with this program.If not, see . You will find additional information about this project at the following address:
     
HowTo: Ardunio – Use the serial port
This codesnippet is a basic concept of a serial communication to control an arduino via serial commands */ { Serial.begin(115200); } void loop() { check_serial_receive(); } void check_serial_receive() { String serialbuffer; while (Serial.available()) { char currentChar = (char)Serial.read(); if (currentChar == 13) { evaluate_received_characters(serialbuffer); } else { serialbuffer += currentcharacter; } } } void evaluate_received_characters(string serialbuffer) { Serial.println(""" + String(serialbuffer) + ""received."); if (serial buffer == "simpleCommandTheWhatDoes") { simpler_command_that_does_the_what(); } else if (serialBuffer.indexOf('=') != -1) { uint16_t receivedValue = serialBuffer.substring(serialBuffer.indexOf('=') + 1).toInt(); String of received parameters = serialbuffer.substring(0, serialbuffer.indexOf('=')); if (receivedParameter == "commandThatSetsAValue") { if (receivedValue <= 23 &amp; & receivedValue >= 0) { command_that_sets_a_value(receivedValue ); } else { Serial.println(F("Value outside the allowed value range.")); } } else { Serial.print(F("The command "")); Serial.print(serial buffer); Serial.print(F("" was not recognized.")); } } else { Serial.print(F("The command "")); Serial.print(serial buffer); Serial.print(F("" was not recognized.")); } }

Have fun with the project

I hope everything worked as described. If not or you have any other questions or suggestions, please let me know in the comments. Also, ideas for new projects are always welcome. 🙂

P.S. Many of these projects - especially the hardware projects - cost a lot of time and money. Of course I do this because I enjoy it, but if you appreciate that I share this information with you, I would be happy about a small donation to the coffee box. 🙂

Buy Me a Coffee at ko-fi.com   

Kommentar hinterlassen

Your email address will not be published. Erforderliche Felder sind mit * markiert