HowTo: Ardunio – Use 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 the Arduino or receive values from the Arduino.

How to do this and what options you have I describe in the following article.


Safety instructions

I know the following notes are always kind of annoying and seem unnecessary. Unfortunately, many people who knew "better" have lost eyes, fingers or other things due to carelessness or injured themselves. Data loss is almost negligible in comparison, but even these can be really annoying. Therefore, please take five minutes to read the safety instructions. Because even the coolest project is not worth injury or other trouble.
https://www.nerdiy.de/sicherheitshinweise/

Affiliate links/advertising links

The links to online shops listed here are so-called affiliate links. If you click on such an affiliate link and make a purchase via this link, Nerdiy.de will receive a commission from the relevant online shop or provider. The price does not change for you. If you make your purchases via these links, you support Nerdiy.de in being able to offer other useful projects in the future. 🙂 


Prepare serial interface

To use the serial port in your program you have to initialize it.
This is done by using the function in the “setup()” function

Serial.begin(115200);

calls. The number “115200” stands for the baud rate – i.e. the speed – at which the symbols (not bits or bytes) 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 unshielded and/or very long cables, this speed should not be set 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” – i.e. the other communication partner for serial communication. Only then will the characters be received and sent correctly. You will find out 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 like sensors and actuators.


Send data from the Arduino board to the connected computer

To send data from your Arduino board to the connected computer you have to call the following function.

This sends the text “Hello world!” including line breaks 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 output shown. After every “Hello World!” A change to the next line is automatically made.

In the following combination, the function sends the text “Hello world!” to the computer without line breaks.

Serial.print("Hello world!");

There is another example of this.

void setup() { Serial.begin(115200); } void loop() { Serial.print("Hello world!"); delay(1000); }
Now that after “Hello World!” If no line breaks are made, a long line is created with several “Hello World!” sections.

If you want to send variable values – in this case the value of the variable “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 line break.

Sending a line break means that in addition to the actual message content, a control character is also sent that signals the recipient to change 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 from the computer and makes it readable for you.
You can 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. The program is also a good alternative to the “Serial Monitor” of the Arduino IDE HTERM.

The line terminator and the baud rate can be set in the serial monitor window. By clicking on “Delete output” you can also delete the contents of the output window.

In the window of the serial monitor you can set the baud rate. Here you have to set the same value that you have set before in the program code.
If you have used the command

Serial.begin(115200);

so you have to set a baudrate of 115200 baud in the serial monitor.

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

Here you can set the character that is automatically appended and sent after each value is sent.

You can use this in your code for example to detect on the Arduino if the transmission of a command or value is completed.

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


Use serial plotter

The serial plotter is a tool with which you can display numerical values (e.g. measured values) directly on the computer as a time curve. To do this, you must 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);

The variable “VariableWithAMeasured Value” should of course contain your measured value as a number.
You then have to start the serial plotter on the computer. 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 out the code. It should run on any Arduino. Remember to set your “serial plotter” to 115200 baud.

/* _ _ _ _ _
                                 | | | | |(_) | |
  __ ____ ____ __ | | | ___ _ __ __| | _ _ _ __| | ___
    / / / / / / / / / | . ` | / _ | '__|/ _` || || | | | / _` | / _
    V V / V V / V /_ | | || __/| | (_| || |_| | _| (_| || __/
    \_/\_/ \_/\_/ \_/\_/(_)|_| \_| \___||_| \__,_||_| \__, |(_)\__,_| \___|
                                                               __/ |
                                                              |___/
     sinusTest by Fabian Steppat
     Info on https://www.nerdiy.de/ardunio-die-serielle-schnittstelle/

     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.

     This program is distributed in the hope 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 to 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 display the illustrated sine wave on the serial plotter.

Of course, the plotter works not only with sine values but also with all other numerical values.


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 it also works the other way around. This is especially useful or practical if you want to control the Arduino from the outside and do not want to connect input devices such as buttons and Co. to the Arduino (or can due to lack of GPIOs).

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

For communication over the serial interface the Arduino IDE provides some useful functions. (The documentation with more details can be found here: https://www.arduino.cc/reference/en/language/functions/communication/serial/)

So that the reception and the evaluation of Befeheln works, there are now three tasks to solve:
1. how does the Arduino recognize received characters?
2. how to assemble complete commands from the received characters?
3. how can these received commands be evaluated?

1. how the Arduino recognizes received characters

Now to react on incoming characters there is the function

Serial.available()

This checks whether new characters are contained in the Arduino's receive buffer. The receive buffer is a type of buffer in which received characters are stored until the Arduino's microcontroller has time to “take care” of the received characters.

In the case 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 perfect to check if characters have been received which have to be evaluated now. The command does not tell us how many characters were received. It only says that at least one character is in the receive buffer.

2. how to turn the received characters into complete commands

Good, 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 characters now?

Characters from the receive buffer can be deleted with the command

Serial.read()

read out. In doing so, the function outputs the first character contained in the receive buffer and automatically removes it from the receive buffer.
To read all characters and write them into a variable, we now read from the receive buffer until it is empty and remember each character read.
This can be implemented 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()==false).
Within the while loop, the characters contained in the receive buffer are read character by character (Serial.read()), assigned to the “current character” variable and appended to the “serial buffer” string.

This is where the line terminator mentioned in the “Serial Monitor” section comes into play. In this (and every other terminal program) you can set a character that is automatically appended and sent every time a character or character string is sent.

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

if (currentChar == 13)...

Don't let the 13 confuse you. The problem with line terminators is that they are not listed on a keyboard. So you cannot “type” them into the code as comparison characters.
To check the received character for the character terminator anyway, we use a trick here.

Thanks to the Ascii table we know that each character in the computer corresponds to a byte value (i.e. a numerical value between 0 and 255).
For example, if you store an “A” in the Arduino, it actually stores the numerical value “65”.
If you now wanted to check whether a received character corresponds to an “A”, you could either

if (currentcharacter == "A")

or else

if (currentcharacter == 65)

write. Both comparisons would lead to the same result.

We now make use of this trick. To check whether the currently received character is a line terminator such as the CR (=CarriageReturn), we do not check the character itself but the value of the character in the ascii table: i.e. 13.

So as soon as this character has been received we know that all previously sent characters are supposed to represent a command and must now be evaluated.

3. how these received commands can be evaluated

So we or the Arduino have now received a command. This is stored in the string variable “serial buffer” and is passed as a function parameter to the function “receive_character_evaluate()”.

This function could look like this, for example:

void received_character_evaluate(String serialBuffer)
{
   Serial.println("" + String(serialBuffer) + "" received."); //output the command just received.
   
   if (serialBuffer == "simplerCommandDerWasTut")
   {
      simpler_command_the_what_tut();
   } else if (serialBuffer.indexOf('=') != -1)
   {
      uint16_t receivedValue = serialBuffer.substring(serialBuffer.indexOf('=') + 1).toInt();
      String receivedParameter = serialBuffer.substring(0, serialBuffer.indexOf('='));
      
      if (receivedParameter == "commandSetOneValue")
      {
         if (receivedValue = 0)
         {
            command_the_one_value_sets(receivedvalue );
         } else
         {
            Serial.println(F("Value outside the allowed range of values."));
         }
      } else
      {
         Serial.print(F("The command ""));
         Serial.print(serialBuffer);
         Serial.print(F("" was not recognized."));
      }
   } else
   {
      Serial.print(F("The command ""));
      Serial.print(serialBuffer);
      Serial.print(F("" was not recognized."));
   }
}

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

You can then use a simple IF query to check which character string corresponds to the received command. Here, for example, it is checked whether the command corresponds to the string “simplerCommandDerWasTut”.
If this is the case, the function “simpler_command_that_does_();” 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 “brightnessSetUp=20” must also be able to be evaluated.
So the command name (in this case “brightnessSetOn”) and the value (in this case “20”) must be recognized.

This is done in the further part of the code shown above.
If none of the “absolute” commands match the received character string, it is checked whether there is an “=” character in the received character string.

For example, if you sent the command “setBrightness=100” to the Arduino, it will not be able to assign the entire string “setBrightness=100” to an “absolute” command.

In this case, the received string is examined for an equal sign and this is also found.

Then the received string is split into the part before and after the equal sign with the following commands.

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

Now the “100” is stored in the “receivedValue” variable and the “setBrightness” command is stored in the “receivedParameter” variable.

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

Just try it 🙂
You can find the whole code to try out here:

/* _ _ _ _ _
                                 | | | | |(_) | |
  __ ____ ____ __ | | | ___ _ __ __| | _ _ _ __| | ___
    / / / / / / / / / | . ` | / _ | '__|/ _` || || | | | / _` | / _
    V V / V V / V /_ | | || __/| | (_| || |_| | _| (_| || __/
    \_/\_/ \_/\_/ \_/\_/(_)|_| \_| \___||_| \__,_||_| \__, |(_)\__,_| \___|
                                                               __/ |
                                                              |___/
     serialTest by Fabian Steppat
     Info on https://www.nerdiy.de/ardunio-die-serielle-schnittstelle/

     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.

     This program is distributed in the hope 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 to 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 for you. If not or you have questions or suggestions please let me know in the comments. I will then add this to the article if necessary.
Ideas for new projects are always welcome. 🙂

PS 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 think it's cool that I share the information with you, I would be happy about a small donation to the coffee fund. 🙂

Buy Me a Coffee at ko-fi.com       

Kommentar hinterlassen

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

This site uses Akismet to reduce spam. Learn how your comment data is processed.