bclose

7 – Communication with the outside world

Objectives

 

 

    • Understand the communication via Serial port.
    • Using the Serial library.
    • Operations with integers.
    • String and char Data Types.
    • Working with Strings.
    • The while statement block.

 

Bill of materials

Arduino Uno  Arduino Uno or equivalent. We can use any other Arduino board in this chapter.
We will also need a PC computer with the Arduino IDE properly installed and set up.

SERIAL COMMUNICATION WITH THE OUTSIDE WORLD

 

Sooner or later, we will need to communicate our Arduino with a computer. There are several reasons for that: to send orders or to receive information or signals, for example.

Computers are provided with keyboards, screens and network adapters but Arduino has to use its USB port to establish a serial connection with our PC.

Serial communication is pretty straightforward, two wires are enough to send a difference of voltage between them (as well as to define a high voltage value (+5 V) and a low voltage value (0 V)) so we can transmit digital information.
There is only one thing left, the sender and the receiver must agree with:

 
  • A common code to encode the characters sent.
  • An speed agreement to set the data rate.
 

The common code used in Arduino is called ASCII code and it is standard on all PCs. The ASCII code is a way to encode alphanumeric characters by using numbers. Remember that we can only send ones and zeros.

For example the letter A is represented by the number 65, B by 66, C by 67 … and so on. Nearly all modern computers use this code (this includes Windows, Mac and Linux, that is why we can read emails sent from different platforms), but it is important to understand that this is only one among several possible character encodings (EBCDIC, for example).

 
  • Nowadays, in fact, we use an ASCII code extension (called Unicode) which allows the use of characters not included in the original table, or to represent characters like ñ or accents in Spanish, as well as different kind of alphabets like Chinese Kanji or Cyrillic. And this is why you can read Chinese or Russian letters on the websites of these countries..
 

The other thing we have to agree with is data rate. Since we only have two wires to transmit, we need to know when to read the line by setting an speed agreement. If the transmission speed is different from the reading speed, the final message will be unrecognizable.

Many of the errors in serial communication when programming with Arduino are usually due to a difference in speed between the transmitter and receiver.

This data rate is measured in bits per second or bauds. We will see that Arduino supports several serial communication data rates.

SETTING THE SERIAL COMMUNICATION

 

Arduino provides a built-in serial library called Serial that allows to send information to the computer. To use it we only have to include the following instruction in the setup() function:

Serial.begin(speed);
 
  • Note that the first letter in Serial is written in capital letters and that C++ is case sensitive.
 

The data rate ranges from 300 to 115.200 bits per second (baud). We usually set it at 9600 baud (by default), although there is no reason for it and this isn’t either a particularly high speed.

To send a message from our Arduino to the computer we can use the Serial.print() and Serial.println() functions. Let’s see an example:

     
     int LED = 10 ; 
     int button = 6 ;
     bool state = false ;
     void setup()
          {  
              Serial.begin(9600) ;                 // Initializes Serial Port at 9600 bits per second
          }
     void loop()
         { 
              int i = 54 ;                 
              Serial.println( i );
         }

In the previous code, the Serial.prinln() function sends the value i to the Arduino Serial port continuously. In order to read the value in the computer we need a Serial port monitor. The Arduino IDE provides a very simple one, useful enough though, that can be invoked by double-clicking on the Serial Monitor icon, shown in the following picture.

Serial monitor button

We also need to ensure that the speed of transmission is the same on both sides. Take a look at the bottom right of the serial monitor:

Serial Monitor baud rate dropdown

Normally the default speed of the serial port is set at 9600 bits per second or baud. If we deploy the combo box to the left of the arrow tip on the picture above, you will see the available baud rates in Arduino.

 
  • Strictly speaking, baud and bits per second are not exactly the same, except under certain specific conditions that in Arduino are met, so here we can use them interchangeably.
  • In the Arduino world seems to be agreement to use low baud rate, as low as 9600 baud rather than higher as 115200 baud, to avoid problems. This is something that for years was justified by transmission problems, but with today’s technology there is no reason for it. Moreover, as we need to use communications devices such as Ethernet or Bluetooth adapters to communicate, we will need to use higher baud rates.
 

Now that we know how to send information and data to a computer, let’s see how we can work with integers and show the result in the serial port monitor.

 
  • Addition:              +
  • Subtraction:           –
  • Multiplication:        *
  • Integer Division:      /           Quotient without decimals (since we work with integers)
  • Module:                %           Returns the remainder of a division between two integers.
 

In C++ we have to express the mathematical operations in a single line and use braces to ensure that they are executed the way we want.

Let’s see some examples:

OPERATION RESULT COMMENT
int i = 4 * 2 result =  8
int i = 4 * 2 / 3 result = 2 Decimals are left out since the result is an integer
int i = 14 % 3 result = 2 The remainder of 14 divided by 3
Int i = 2 + 8 / 2 result = 6 Performs division first.
Int i = (2+8) / 2 resultado = 5 The parenthesis force the addition be performed first

Given an expression, the precedence of operators states which operations are executed first and which later, according to their range. For those starting out in C++ it is not easy to know which operators have preference, so it is safer to use braces, just in case.

The use of braces forces the operations declared inside to be executed first and should be used when in doubt because, otherwise, detecting errors in the operations can become very difficult, especially when you start programming.

The modulo operator is more useful than it seems at a first glance because it allows us to know whether a number is a multiple of another. Suppose we want to know whether a given number is even.
In this case we could write the following program:

     
     void setup()
          {
             Serial.begin(9600) ; // Initializes Serial Port at 9600 bits per second
          }
     void loop()
         { 
            int i = 27 ; // The number
            if ( i % 2 == 0)
                 Serial.println("It is an even number") ;
           else
                 Serial.println("It is an odd number ");
         }

Giving different values to i we can see how the modulo operator works. We will return to this when we see some examples of how to calculate prime numbers.

In this program we have used the Serial.println() function in a different way. Serial.print() sends the text written between quotation marks to the serial port, without adding a line break at the end. However, Serial.println() sends the text and besides adds a carriage return plus a form feed causing a line break.

     void setup()
          {
             Serial.begin(9600) ; // Initializes Serial Port at 9600 bits per second
          }
     void loop()
          { 
               Serial.print("Good ") ;
               Serial.print("morning ") ;
               Serial.println("to all.") ;
          }

C++ provides a new kind of Data Type called String that can contain alphanumeric characters. We can work with them as we do with any other C++ Data Type, just defining them.

      
      void loop()
           { 
               int result = 25 ;
               String s = The result is: ” ; // Note that S in String is written in capital letters.
               Serial.print( s) ;
               Serial.println( result); 
           }

We can simply define an String writing a text between double quotation marks and we can work with them in a similar way as we work with integers. Try it out!

    void loop()
    { 
        String a = "Hi" ;
        String b = "all." ;
        Serial.println( a + b);  
    }

We can also build a String on the fly like this:

    void loop()
    { 
        int result = 25 ;
        String s = "The result is: " ;
        Serial.println( s + String( result ));   
    }

The code above concatenates the string s with the integer result, previously casted to a String Data Type, and then sends it to the serial port . The + operator, when dealing with String Data Types, concatenates two strings together, one after each other.

RECEIVING MESSAGES THROUGH THE SERIAL PORT

.

So far we have only sent messages from the Arduino to the computer. But, how can we receive messages in our Arduino?
C++ provides a function called Serial.parseInt() that can be used to convert what is received through the serial port to an integer:

     
          void loop()
          { 
              if (Serial.available() > 0)
                  {
                      int x = Serial.parseInt();
                      Serial.println ( x) ;
                  }
          }

The previous code simply tries to convert the text typed through the serial monitor (once return is pressed) to an integer and stores the result in the integer variable x. If the text does not contain a number then the Serial.parseInt() function interprets it as a zero.

We have used another function included in the Serial library, the Serial.available() function that returns a boolean value. It is good practice, before reading the serial port, to check whether some data has been sent. If so, Serial.available() returns a logic true and a logic false otherwise.

When we want to read a String from the serial port the situation gets complicated. So we need to talk about the char Data Type first.

One of the biggest headaches when you start programming in C++ is to understand the difference, counterintuitive, between char and String. The char Data Type represents a single character and is defined by using single quotation marks, unlike String where you need to use double quotation marks:

char  c = ‘a’  ;
String s =”a”  ;

Although the expressions are very similar, they are quite different for C++.

To read a string from the serial port, we need to read one character at the time and after that concatenate them all in a single string. But first, check that the option Both NL & RC (New Line and Carriage Return) is selected in the serial monitor, to ensure that the end of line character is sent:

Serial Monitor

The following program reads a string from the serial port:

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

     void loop ()
          { 
              char c = ' ' ;
              String message ="" ;
              If (Serial.available()) // Check whether some data has been sent                     
                   {
                      while( c != '\n') // If any, we read it until the intro character is found
                          { 
                            message = message + c ; // We add what we have read to the message 
                            c = Serial.read(); // Reads 1 character
                            delay(25);
                          }
                      Serial.println(message); // We print the message in the serial console when we leave
                      message = "" ; // We clear the message to use it the next time
          }

Here we use another C++ instruction, the while statement block. It is quite similar to the if statement, but there is a main difference: the block of statements that follows executes again and again while the condition between braces is met, hence the name.

     
while ( condition)
{   
   ... 
}

In the previous sketch, the while statement tests the character we write via the Serial port and when we press enter, the condition c != ‘\n’, that is, c is not equal to enter, becomes false so the while loop ends.
Otherwise, we check whether there is anything available on the serial port and if so, we build the message string reading a character each time and adding it to the message variable to build a string that will be printed before exit.

 
  • The reason to use the instruction delay(25) is that, at such a slow speed, sending a 8 bit character via serial port takes much longer than it takes Arduino to execute the block of statements in the while loop and start again. So if the delay is removed (and we recommend you to test it) Arduino UNO or MEGA will read only a good character of the written word and as 10 trash characters.
  • If we raise the speed rate to 115200 bits per second, you won’t find this problem since by multiplying the speed rate for more than 10 Arduino no longer have time to come back for more characters before they arrive.
 

Summary

.

 
    • We have seen how to set a communication line with a computer to either send or receive messages containing text or integers.
    • We have introduced the String and char Data Types.
    • We have seen the basic rules to work with integers and strings.
    • We have introduced a new instruction: the while statement block.

 

 

 

No Comments

Give a Reply