CHAPTER 10 ■
SERIAL AND I2C
177
Code Character Code Character Code Character Code Character Code Character 43 +
62 81 Q
100 d
119 w
44 , 63 ?
82 R 101
e 120
x 45 -
64 83 S
102 f
121 y
46 . 65 A
84 T 103
g 122
z 47
66 B 85 U
104 h
123 {
48 0 67 C
86 V 105
i 124
| 49 1
68 D 87 W
106 j
125 }
50 2 69 E
88 X 107
k 126
~ The ASCII codes also contain something called escape codes. These characters have been around
for a while and control things like character returns, tabs, and line feeds or newlines. Later in our example code, we use the sequence
n, which is one of the control characters, a non-printable
character that controls the behavior of a device, to signal when a line has been entered. Table 10-2 provides some of the common escape codes.
Table 10-2. Escape Codes
ASCII Sequence Description
8 \b
Backspace 9
\t Tab
10 \n
Newline or line feed 13 \r
Carriage return
Finally, how fast we send our packets of information is called the data rate or sometimes the baud rate. This is a measure of how many pulses are being sent or received in one second, also known as bits
per second bps. A sort of de facto standard baud rate for the Arduino is 9600 bps although the microcontroller is capable of communications at a range of speeds up to 115,200 bps, as needed by
whatever specific devices that the Arduino is connected to. Both the sending and receiving device need to be set to the same data rate to ensure that both devices are speaking at the same speed.
With the boring basics for using serial communications out of the way, let’s turn our attention to the next project and some of the Serial functions available to us.
CHAPTER 10 ■
SERIAL AND I2C
178
Project 9: Serial to Servo
Sending information to the Arduino board to control how it functions is as useful and almost as easy as sending information from the Arduino board. For this project, we will look at the Servo project from the
last chapter so that we can use the Serial functions to send data to the Arduino board to control the servo’s position. For our sketch to work properly, we need to change the communication mode from No
line ending to Newline in the drop-down menu at the bottom of the Serial Monitor.
Hooking It Up
Because the circuit should be familiar, we won’t dwell on it too much. Figures 10-1 and 10-2 show the standard servo schematic and illustration that we used before with nothing else needed. The following
source code, however, will give us something new and fun to talk about.
GND PIN 10
+5 VDC SIGNAL
SERVO +5 VDC
GND
Figure 10-1. Serial Servo schematic
PIN 10 SERVO
+5VDC GND
Figure 10-2. Serial Servo illustration
CHAPTER 10 ■
SERIAL AND I2C
179
Uploading the Source Code
Where before we have used the Serial functions to send data from the Arduino board to our Serial Monitor, for the purpose of monitoring analog values, the sketch in Listing 10-1 will instead allow us to
send data to the Arduino board that has been entered in the Serial Monitor. On the surface, all we need to do is type in an angle for our servo from 0 to 180, corresponding to the angle that we want to position
a servo, and hit enter. When the Arduino receives this information, it will process it and move the servo to the proper angle.
We see that because serial communications happens in one-byte chunks and because of the habit of serial to send information in characters rather than numerical values more on that shortly, we need to
do a little work to get the characters that are received converted to proper numbers that can be used to position a servo. So let’s upload the following code and have a look at how all this works.
Listing 10-1. Serial Servo Source Code
include Servo.h Servo servo;
void setup { Serial.begin9600;
servo.attach 10; }
void loop { int angle = 0;
if Serial.available { byte incomingByte = Serial.read;
while incomingByte = \n { if incomingByte = 0 incomingByte = 9
angle = angle 10 + incomingByte - 0; incomingByte = Serial.read;
} if angle = 0 angle = 180 {
servo.writeangle; Serial.printlnangle;
} else Serial.printlnChoose an angle between 0 and 180.; }
}
Source Code Summary
Just like our example from the last chapter, at the beginning of our sketch we include and create a new instance for the Servo library. While it acts like any other library, we do not need to create an instance of
Serial because it is already included as a part of our sketch as standard. In our
setup function, we have
the necessary statements to establish the speed of our serial communications and attach our servo to a pin number. Our
loop function begins by starting our servo angle off at 0º and then checks to see if
CHAPTER 10 ■
SERIAL AND I2C
180
data is available in our serial buffer. If so, it reads the first byte and, so long as the newline escape code has not been sent, will check to see if that value of the byte represents a digit from 0 to 9. This sketch uses
the Newline option in the Serial Monitor, so that each time we hit the Enter key, the Serial Monitor sends the escape code
n for a new line. We can test for this in our if statement like any other value to know
when all of the digits for our angle have been entered. At this point, the code will put together our angle integer digit-by-digit or byte-by-byte using a little
math to convert the ASCII character into its numerical value, and then increases the angle value by a power of ten for each byte received. Once it receives the newline character or
n from the Serial
Monitor, it will move on to check the angle value that was received to make sure it falls within the capabilities of the servo. If so, it moves the servo to that angle and sends that angle value to the Serial
Monitor. If not, it will send a message letting us know to try again. Now let’s look at how this is done.
Serial Library
The Serial library is a little different from the other libraries that are a part of the standard Arduino distribution. First, the library is automatically included in our sketches along with the normal Arduino
library without us needing to do anything. Second, an instance of the Serial library is already created for us in the background that, on the Arduino Uno, is called
Serial, and on the Arduino Mega might be Serial1, Serial2, or Serial3. So when we use one of the upcoming functions, it will be preceded by the
instance name
Serial and a period to separate the library name from the procedural or function name.
As an aside, you might have noticed by now that many of the different libraries have similar procedures, including
begin, print, write, and others, so it is important that we get the instance of the library
correct or who knows what will happen Enough posturing, let’s move onward with our first Serial function.
begin
With the Serial library already included for us and an instance called
Serial already created, the first
thing we need to do to work with the Serial functions is to establish a data transfer speed. To do that we use the
begin function. Serial.begindatarate
Again, our instance name on the Arduino Uno is Serial, so we will stick with that for our instance
name. The
datarate parameter is the speed measured in bits per second that, for communicating with
our computer, should be one of the following speeds: 300, 1200, 2400, 4800, 9600, 14400, 19200, 28800, 38400, 57600, or 115200. Generally, you’ll find that 9600 is a fairly common speed and is more than fast
enough to do what we want to do. In our project sketch, this function took the following form:
Serial.begin9600;
This sets up our communication to occur at a speed of 9600 bps. You might have a reason to set a more esoteric speed if your device calls for it, but whatever speed is set, both devices need to be set for
the same speed. To do this in the built-in Serial Monitor, there is a drop-down menu in the bottom-right corner of the window where these speeds can be selected.
CHAPTER 10 ■
SERIAL AND I2C
181
available
Since we have already looked at sending data to our computer a few chapters ago, we will first talk about reading data and get back to sending it later in this chapter. Before we can read data from the serial line,
we need to know if data is available or not. That’s where the appropriately named
available function
comes in.
Serial.available
This function has no parameters but will instead return the number of available bytes waiting in the serial buffer. Remember, the hardware serial port on the Arduino microcontroller has a buffer that can
store up to 128 bytes of information so that it doesn’t get lost. If no data is waiting for us, it will return 0 and we can use this in an
if statement like we did in our project code, as follows: if Serial.available {
If no data is available in the buffer, then this function will return 0 and evaluate as false. On the
other hand, if any data is available, the function will return a value other than 0 that will evaluate as
true
and we can proceed to read from the buffer. In our example, it didn’t matter how much data is in the buffer, only that there was data to be read.
read
Now that we know there is data waiting for us in our buffer, we can use the read function to do
something with it. While the syntax is simple enough, there are some unusual characteristics that we will need to work through before moving on.
Serial.read
This function simply returns the first byte of information available in the serial buffer. Because the way our serial communications are structured, each character that we send to the Arduino through the
Serial Monitor will be converted to that character’s ASCII character value. See, I warned you this would come up again. For example, if we were to send the Arduino the number
1, instead of receiving the