Overview of the Serial Communication Protocol
Setting Up the Arduino
Notice that the Arduino code (Listing 1) does not have much logic. The only thing it does is respond to incoming messages. In this case, whatever program is controlling the device makes all the decisions, so the logic lives elsewhere. The Arduino just follows the instructions it receives over the serial port and reports changes to the attached inputs.
Listing 1
Arduino Code
01 #include <Servo.h> 02 03 Servo servo; 04 int oldSwitch = 0; 05 int oldButton = 0; 06 07 void setup() 08 { 09 pinMode(2, INPUT_PULLUP ); 10 pinMode(3, INPUT_PULLUP ); 11 pinMode(13, OUTPUT); 12 Serial.begin ( 9600 ); 13 Serial.setTimeout ( 5000 ); 14 15 servo.attach ( 11 ); 16 } 17 18 void loop() 19 { 20 char incoming=0; 21 int readState=0; 22 23 if ( Serial.available() ) 24 { 25 incoming = Serial.read(); 26 if ( incoming == 'L' ) digitalWrite ( 13 , HIGH ); 27 else if ( incoming == 'l' ) digitalWrite ( 13 , LOW ); 28 else 29 { 30 int i=0; 31 String fullNumber = String ( incoming ); 32 String number; 33 34 number = Serial.readStringUntil ( '.' ); 35 fullNumber.concat ( number ); 36 i = fullNumber.toInt(); 37 38 if ( i >= 0 && i <= 180 ) servo.write ( i ); 39 } 40 } 41 42 readState = digitalRead ( 2 ); 43 if ( readState != oldButton ) 44 { 45 oldButton = readState; 46 Serial.print ( "Button:" ); 47 Serial.println ( readState ); 48 } 49 50 readState = digitalRead ( 3 ); 51 if ( readState != oldSwitch ) 52 { 53 oldSwitch = readState; 54 Serial.print ( "Switch:" ); 55 Serial.println ( readState ); 56 } 57 }
Lines 1-5 bring in the appropriate library and initialize global variables: servo
from the Servo.h
library represents a servo motor, and the integers oldSwitch
and oldButton
store previous states of the button and switch.
The Arduino calls the setup
function (lines 7-16) once when the program is first run. As the name implies, it sets up any Arduino features that will be used and initializes any hardware that needs to be set up before the main loop runs. In this case, it sets up input and output pins and the serial port.
Lines 9-11 tell the Arduino whether the specified pin is used as an input or an output. The first argument is the pin number, and the second argument is the mode. The INPUT_PULLUP
mode not only sets the pin to an input but also enables the Arduino's pull-up resistor.
Buttons and switches are passive components (not electrically active on their own) so the pull-up resistor provides the electrical equivalent of a default value. The pull-up resistor is relatively weak, so when the button or switch is connected to ground, the pin will see that instead, which guarantees a clean 0 or 1 each time the button or switch changes.
The Arduino Uno has one serial port located on pins 0 and 1. You'll notice, though, that nothing is connected to those pins. It also has a USB-to-serial converter as part of its onboard hardware, but everything happens behind the scenes, so you don't have to worry about it. I'll be using serial from the attached computer over the USB port.
The Serial.begin
function tells the Arduino to turn on the serial port (as opposed to being a general-purpose I/O), and 9600
is the baud rate. Serial.timeout
tells the Arduino that any code waiting for input from the serial port should stop waiting after 5,000msec, which prevents the program from stalling if a proper signal isn't received. Eventually, it will time out and move on with the program.
Servo Setup
The servo
variable created in line 3 hasn't been connected to anything yet, so the servo.attach
line tells the Arduino which pin the servo is on (11 in this case).
The special Arduino loop()
function starts in line 18 and does exactly what its name implies: It runs continuously until power is removed from the Arduino.
After initializing two local variables, incoming
and readState
, a checking routine looks for any characters that are available from the serial port. Serial.available
returns the number of characters waiting in the buffer. If it is not zero, the processing inside the if
statement proceeds.
The Serial.read
gets the first character from the serial port and saves it in the incoming
variable. If the incoming character is an uppercase L, a call to digitalWrite
turns the LED on; otherwise, the program checks for a lowercase l, which turns off the LED.
By line 28, if nothing has happened, the Arduino has probably received a number, which is processed in lines 29-39. After initializing the local variable i
to 0, lines 31 and 32 set up strings for the incoming data from the serial port. The fullNumber
variable is given an initial value of the string version of incoming
– the first character received (i.e., the first digit).
The variable number
is initialized to a blank string. Line 34 requests characters from the serial port until it receives a period. The received characters go into number
, which is concatenated to fullNumber
in the next line. Now fullNumber
really does have the full number received from the port. Line 36 uses toInt
to turn the string into an integer and stores it in i
.
Finally, if i
is greater than 0 and less than 180 (the valid range for a servo), servo.write
asks the servo to move to the angle specified in i
.
Buttons and Switches
Variable readState
stores the state of Arduino pin 2, which determines whether the button is pressed or not. Note that a value of 0 is pressed and 1 is not pressed, which might seem backward.
If readState
is different from oldButton
, the button has changed state. In that case, line 45 updates oldButton
, line 46 sends the string Button:
out the serial port, and line 47 sends the new state of the button; Serial.println
then tells the Arduino to add a newline after printing the readState
variable.
Checking the switch works exactly the same as checking the button, except on pin 3 (line 50) and by checking and updating oldSwitch
(lines 51 and 53) instead of oldButton
and printing Switch:
instead of Button:
(line 54).
Buy Linux Magazine
Direct Download
Read full article as PDF:
Subscribe to our Linux Newsletters
Find Linux and Open Source Jobs
Subscribe to our ADMIN Newsletters
Find SysAdmin Jobs
News
-
OpenMandriva Lx 23.03 Rolling Release is Now Available
OpenMandriva "ROME" is the latest point update for the rolling release Linux distribution and offers the latest updates for a number of important applications and tools.
-
CarbonOS: A New Linux Distro with a Focus on User Experience
CarbonOS is a brand new, built-from-scratch Linux distribution that uses the Gnome desktop and has a special feature that makes it appealing to all types of users.
-
Kubuntu Focus Announces XE Gen 2 Linux Laptop
Another Kubuntu-based laptop has arrived to be your next ultra-portable powerhouse with a Linux heart.
-
MNT Seeks Financial Backing for New Seven-Inch Linux Laptop
MNT Pocket Reform is a tiny laptop that is modular, upgradable, recyclable, reusable, and ships with Debian Linux.
-
Ubuntu Flatpak Remix Adds Flatpak Support Preinstalled
If you're looking for a version of Ubuntu that includes Flatpak support out of the box, there's one clear option.
-
Gnome 44 Release Candidate Now Available
The Gnome 44 release candidate has officially arrived and adds a few changes into the mix.
-
Flathub Vying to Become the Standard Linux App Store
If the Flathub team has any say in the matter, their product will become the default tool for installing Linux apps in 2023.
-
Debian 12 to Ship with KDE Plasma 5.27
The Debian development team has shifted to the latest version of KDE for their testing branch.
-
Planet Computers Launches ARM-based Linux Desktop PCs
The firm that originally released a line of mobile keyboards has taken a different direction and has developed a new line of out-of-the-box mini Linux desktop computers.
-
Ubuntu No Longer Shipping with Flatpak
In a move that probably won’t come as a shock to many, Ubuntu and all of its official spins will no longer ship with Flatpak installed.