How to Connect Arduino to ROS

How do we connect ROS to an actual embedded system that operates in the real, physical world? I’ll show you how to do this now using Arduino

Arduino is a popular microcontroller for building electronics projects. A microcontroller is a bunch of circuits that do stuff, such as accepting data input, doing calculations, and producing output. With respect to robotics development, Arduino would be the “brain” of a robot.

Fortunately, ROS can integrate with Arduino. We will install some software that will enable your Arduino to be a bonafide ROS node that can do everything a normal node can do, such as publish and subscribe to ROS messages.

Here are the official steps for interfacing Arudino with ROS, but I’ll walk you through the process below.

Table of Contents

Directions

How to Install Arduino on Ubuntu Linux

First, let’s download the Arduino IDE (Linux 64 bit version) to our computer. I will follow these instructions for installing the Arduino IDE on Ubuntu. Go to this website, and download the software:

63-download-arduino-file

Save the file. It will be saved as tar.xz format to your Downloads folder.

Open a new terminal window.

Move to the Downloads folder (or wherever you saved the tar.xz file).

cd Downloads
64-change-to-downloads-directory

Run this command to extract the files (substitute FILENAME with the name of the file you just downloaded):

tar xvf <FILENAME>

In my case, I will run:

tar xvf arduino-1.8.10-linux64.tar.xz

You will see a bunch of file names print out to your screen.

If you type the dir command, you will see the new folder. Let’s move that folder to the home directory. You can cut and paste it into the home directory using the file manager (the file cabinet on the left of the screen. Go there, then go to the Downloads folder, cut the file and paste it into the Home directory.

65-downloads-dir
66-arduino-in-home-directory

Now open up a new terminal window and type:

cd arduino-1.8.10

Type dir to see what files are inside.

67-what-files-are-inside

To install the IDE, type:

sudo ./install.sh
68-install-ideJPG

Here is the output. You should see a “done” message. A desktop icon will also be present. You can activate it by clicking on it and allowing permissions at the prompt.

Now, get your Arduino and connect it to the USB port on your computer.

Start Arduino by going into a new terminal window and typing:

arduino

You might see an error message like this:

69-arduino-startupJPG

Failed to load module “canberra-gtk-module” … but already installed

To resolve that error, press CTRL+C and close the terminal window.

Open a new terminal window, and type:

sudo apt-get install libcanberra-gtk-module

Now open a new terminal window, and type:

arduino

Let’s see if everything works by trying to blink the light-emitting diode (LED) on your computer.

Go to File – > Examples -> 01.Basics, and choose Blink.

Try to upload that code to your Arduino by clicking the right arrow on the upper left of your screen.

70-right-arrow-to-uploadJPG

You should see an error about the “Serial port not selected”.

Close out of your Ubuntu Virtual Machine completely. Do not save the state.

Set Up the Serial Port for VirtualBox With Ubuntu

Assuming you are using Windows, go to your Device Manager. Search for that in your computer in the bottom left of your desktop.

Under Device Manager, you should see Ports (COM & LPT). Note that Arduino is port 3 (Make sure your Arduino board is connected to the USB port of your computer).

71-arduino-com-portJPG

Open your VirtualBox.

Click Settings and go down to Serial Ports.

72-settings-serial-portsJPG

Make sure your settings look exactly like this:

73-settings-after-serial-portJPG

Note that the little box next to “Enable Serial Port” is checked.

Side Note: Any time you unplug your Arduino….say perhaps after using it within Ubuntu Linux or if you shutdown your PC….be sure to disable the “Enable Serial Port” option before restarting Ubuntu Linux in your Virtual Box. Otherwise, your Ubuntu Linux session will NOT launch. I’ve made this mistake numerous times, and it is frustrating.

After you are done, click OK.

Restart the VirtualBox with Ubuntu.

Open a new terminal window and type:

ls -al /dev/ttyS0

Here is the output:

74-serial-port-outputJPG

Now we need to give the IDE permissions to access the device.

In a new terminal window, find out your username. Type:

whoami

Now type the following commands, replacing YOUR_USER_NAME with what you found above:

sudo usermod -a -G dialout YOUR_USER_NAME
sudo chmod 660 /dev/ttyS0
76-add-dialoutJPG

Reboot your machine:

sudo reboot

Open up a terminal window and launch Arduino by typing:

arduino

Go to Tools -> Port, and you should see /dev/ttyS0. This is your Arduino board that is connected to the USB port of your computer. Make sure /dev/ttyS0 is checked.

77-arduino-board-selectedJPG

Now open the Blink sketch again. Go to File – > Examples -> 01.Basics, and choose Blink.

Click the Upload button…the right arrow in the upper left of your screen.

The LED on your Arduino should be blinking! If it is not, go back to the beginning of this tutorial and follow the steps carefully.

To turn off the blinking light, open up a new sketch and upload it to your board. Go to File -> New.

Integrate Arduino With ROS

Now that we know Arduino is working, we need to integrate it with ROS. Here are the official instructions. I’ll walk you through the steps below.

Let’s install the necessary packages. 

Close Arduino. Then type the following commands in a new terminal window (these will take a while to download so be patient):

sudo apt-get install ros-melodic-rosserial-arduino
sudo apt-get install ros-melodic-rosserial

Open the IDE by typing arduino and go to File -> Preferences. Make a note of the Sketchbook location. Mine is:

/home/ros/Arduino

78-sketchbook-locationJPG

Open a new terminal window and go to the sketchbook location you noted above. I’ll type:

cd Arduino
79-libraries-folderJPG

Type the dir command to see the list of folders.

Go to the libraries directory.

cd libraries

Within that directory, run the following command to build the Arduino library that will be used by ROS (don’t leave out that period that comes at the end of the command):

rosrun rosserial_arduino make_libraries.py .

Type the dir command to see the list of folders. You should now see the ros_lib library.

80-ros-lib-libraryJPG

Make sure the Arduino IDE is closed. Now open it again.

You should see some sample code. Now, let’s take a look at the Blink example.

Go to File -> Examples -> ros_lib

81-ros-lib-on-examplesJPG

Return to Table of Contents

How to Blink an LED (Light-Emitting Diode) Using ROS and Arduino

The Blink example is analogous to a “Hello World” program. Blinking an LED is the most basic thing we can do to make sure the hardware is working properly and that it accepts the software we are developing on our laptop. The goal of the Blink example is to toggle an LED on and off. 

In this example, Arduino is going to be considered a Subscriber node. It will subscribe to a topic called toggle_led. Publishing a message to that topic causes the LED to turn on. Publishing a message to the topic again causes the LED to turn off. 

Go to File -> Examples -> ros_lib and open the Blink sketch.

Now we need to upload the code to Arduino. Make sure your Arduino is plugged into the USB port on your computer.

Upload the code to your Arduino using the right arrow button in the upper left of your screen. When you upload the code, your Arduino should flicker a little bit.

Open a new terminal window and type:

roscore

In a new terminal window, launch the ROS serial server. This command is explained here on the ROS website. It is necessary to complete the integration between ROS and Arduino:

rosrun rosserial_python serial_node.py /dev/ttyS0
83-rosrun-rosserial-pythonJPG

Now let’s turn on the LED by publishing a single empty message to the /toggle_led topic. Open a new terminal window and type:

rostopic pub toggle_led std_msgs/Empty --once
84-publish-message-led-onJPG

The LED on the Arduino should turn on. Note the yellow light is on (my Arduino is inside a protective case).

2019-10-21-193316

Now press the Up arrow in the terminal and press ENTER to run this code again. You should see the LED turn off. You might also see a tiny yellow light blinking as well. Just ignore that one…you’re interested in the big yellow light that you’re able to turn off and on by publishing single messages to the /toggle_led topic.

85-publish-message-led-offJPG
2019-10-21-193535

Return to Table of Contents

That’s it! You have now seen how you can integrate Arduino with ROS. To turn off your Arduino, all you need to do is disconnect it.

How to Control a Servo Motor Using Arduino

Motors are what enable robots to move and do things. Without motors, robots are just big pieces of metal and plastic that can’t move.

The simplest type of motor is the direct current (DC) motor. This type of motor spins around and around in one direction, rotating 360 degrees. It only stops rotating when it is disconnected from a power source. DC motors are common in wheeled robots.

Another type of motor is known as the servo motor (“servo”). Instead of rotating continuously for 360 degrees in one direction, servo motors move to specific angles, typically anything between 0 and 180 degrees. Servo motors are common in robotics. You will see them in all types of applications where a motor needs to move a part of the robot to a specific position. Examples include robot arms, hands, legs, and humanoid robots. NASA’s Robonaut 2, for example, has a total of 54 servo motors which are used to move the robot’s joints, head, and other body parts.

In this post, I will explain how servos work, and then we will get our hands dirty by powering up our Arduino and using it to control a servo.

How Servos Work

Servos work by receiving electrical signals. The length of this signal controls the angle the motor turns…the longer the signal, the greater the motor will turn. This process is known as pulse-width-modulation because the width (i.e. duration) of the electrical pulse modulates (modifies) the motor’s angle of rotation. Here is what that looks like:

controlling-a-servo-motor-2

Requirements

Here are the requirements:

  • Control a servo motor’s angle of rotation.

You Will Need

controlling-a-servo-motor-1

The following components are used in this project. You will need:

Directions

Control a Servo Using Arduino’s Power Supply

controlling-a-servo-motor-3

Here is the hardware we need to set up:

servo-motor-arduino

Connect the red wire of the servo to the 5V pin of the Arduino Uno.

Connect the black wire of the servo to the GND (ground) pin of the Arduino Uno.

Connect the yellow control wire of the servo to Digital Pin 9 of the Arduino Uno. This yellow wire is the one that will receive commands from the Arduino. Pin 9 is one of Arduino’s Pulse-Width Modulation pins.

Power up your Arduino by plugging in the USB cord to your computer.

Open the Arduino IDE, and in a new sketch, write the following code:

/* Sweep
 by BARRAGAN <http://barraganstudio.com>
 This example code is in the public domain.

 modified 8 Nov 2013
 by Scott Fitzgerald
 http://www.arduino.cc/en/Tutorial/Sweep
*/

#include <Servo.h>

Servo myservo;  // create servo object to control a servo
// twelve servo objects can be created on most boards

int pos = 0;    // variable to store the servo position

void setup() {
  myservo.attach(9);  // attaches the servo on pin 9 to the servo object
}

void loop() {
  for (pos = 0; pos <= 180; pos += 1) { // goes from 0 degrees to 180 degrees
    // in steps of 1 degree
    myservo.write(pos);              // tell servo to go to position in variable 'pos'
    delay(15);                       // waits 15ms for the servo to reach the position
  }
  for (pos = 180; pos >= 0; pos -= 1) { // goes from 180 degrees to 0 degrees
    myservo.write(pos);              // tell servo to go to position in variable 'pos'
    delay(15);                       // waits 15ms for the servo to reach the position
  }
}

Upload the code to your board. This code will make the shaft of the motor sweep back and forth 180 degrees.

Control a Servo Using Arduino and a Potentiometer

controlling-a-servo-motor-4

In some applications, we might want to control the angle a servo rotates without having to constantly modify the code. One way to do this is to use a potentiometer. Think of a potentiometer as a variable resistor. By turning the knob, you can control the voltage output of the potentiometer.

In this piece of the project, we will set up software that reads the voltage output of the potentiometer. It then converts that number it into an angle for the servo.

A potentiometer has 3 terminals:

  1. Two outer terminals are used for power: one outer pin connects to ground and the other connects to positive voltage. Potentiometers don’t have polarity, so it doesn’t matter which one is ground and which one is connected to positive voltage.
  2. A central control terminal is used for voltage output: turning the knob of the potentiometer increases or decreases the resistance, which lowers or increases the voltage output.

So let’s set all this up. Here is the schematic diagram:

servo-motor-arduino-potentiometer

With your Arduino unplugged, stick the 10k Ohm potentiometer into the solderless breadboard. Make sure each terminal is connected to separate row in the breadboard.

Connect one of the outer terminals to the blue (ground) rail of the breadboard.

Connect the other outer terminal to the red (positive) rail of the breadboard.

Connect the central pin of the potentiometer to Analog Input pin A0 of the Arduino.

Connect the black and red wires of the servo to the blue and red rail of the breadboard, respectively.

Connect the yellow control wire to pin 9 of the Arduino.

Connect a wire from the +5V pin of the Arduino to the positive red rail of the breadboard.

Connect a wire from Ground (GND) of the Arduino to the blue rail of the breadboard.

This completes the hardware setup.

Plug in the Arduino.

controlling-a-servo-motor-5

Open up the IDE. Inside a new sketch, write the following code:

/*
 Controlling a servo position using a potentiometer (variable resistor)
 by Michal Rinott <http://people.interaction-ivrea.it/m.rinott>

 modified on 8 Nov 2013
 by Scott Fitzgerald
 http://www.arduino.cc/en/Tutorial/Knob
*/

#include <Servo.h>

Servo myservo;  // create servo object to control a servo

int potpin = 0;  // analog pin used to connect the potentiometer
int val;    // variable to read the value from the analog pin

void setup() {
  myservo.attach(9);  // attaches the servo on pin 9 to the servo object
}

void loop() {
  val = analogRead(potpin);            // reads the value of the potentiometer (value between 0 and 1023)
  val = map(val, 0, 1023, 0, 180);     // scale it to use it with the servo (value between 0 and 180)
  myservo.write(val);                  // sets the servo position according to the scaled value
  delay(15);                           // waits for the servo to get there
}

Upload the code to your board.

Turn the knob on your potentiometer to move the servo.

Your Arduino microcontroller is reading the voltage that is coming in from the potentiometer on Analog Input pin 0. It is then converting this voltage into a value between 0 and 180. This degree value then gets sent down the yellow control wire to the servo, and the servo moves accordingly. Thus, the higher the voltage output by the potentiometer, the greater the servo’s angle of rotation.

Control a Servo Using an External Power Supply

controlling-a-servo-motor-6

We don’t always want to use the Arduino to power our servos. Sometimes we might want to use an external power supply. Here is a basic schematic (Note: Ignore the AAA on the batteries below. They are actually AA.):

servo-motor-arduino-external-power

The biggest change from the previous implementation is that now the servos are connected to the 4xAA battery holder instead of the Arduino’s power supply.

With your Arduino powered off, move the red and black wires of the servo to the other red and blue rails of your solderless breadboard.

Connect the red wire of the 4xAA battery holder to the red rail of the solderless breadboard (the one electrically connected to the servo).

Connect the black wire of the 4xAA battery holder to the blue rail of the breadboard.

Make sure your external power supply is connected to the same ground as the Arduino. Use a male-to-male jumper wire to connect both ground rails. This is called common ground.

Power up the Arduino, open the IDE, and find the same sketch as the previous section of this blog post.

Upload the sketch to your Arduino.

Turn the knob of the potentiometer, and watch the servo move.

How to Add Sound to a Wheeled Robot | Arduino

In this post, I’ll show you how to add sound to a wheeled robot.

Shout out to the late Gordon McComb for this project idea. He is the author of an excellent book that I recommend buying if you’re getting started with robotics: How to Make a Robot.

Requirements

Here are the requirements:

  • Build a wheeled robot that makes sound before it backs up.

You Will Need

The following components are used in this project. You will need:

Directions

Get the Piezo Transducer.

Stick the positive lead of the transducer into cell j26. Stick the other lead of the transducer into cell j29.

Connect digital pin 5 of the Arduino board to cell f26 of the breadboard.

Connect f29 to e29 with a male to male jumper wire, or just make sure that j29 is electrically connected to Ground.

sound-robot

Upload the following sketch to the Arduino breadboard to test the Piezo transducer.

#define SPKR 5

/**
 * Test the piezo transducer 
 * connected to pin 5
 * 
 * @author Addison Sears-Collins
 * @version 1.0 2019-05-15
 */
 
void setup() {
}

// Play sounds over and
// over again
void loop() {
   tone(SPKR, 247, 300); //247 Hz, 300ms
   delay(200);
   tone(SPKR, 131, 300);
   delay(200);
   tone(SPKR, 1175, 300);
   delay(200);
   tone(SPKR, 262, 300);
   delay(200);
   tone(SPKR, 1175, 300);
   delay(200);
   tone(SPKR, 131, 300);
   delay(200);
   tone(SPKR, 262, 300);
   delay(200);
   tone(SPKR, 1175, 300);
   delay(200);
   tone(SPKR, 247, 300); //247 Hz, 300ms
   delay(200);
}

Upload the following sketch to the Arduino breadboard in order to cause the robot to make sound just before it backs up.

#include <Servo.h> 

/**
 *  This robot will move around a room and when it 
 *  bumps into an object, it will turn around and 
 *  go in another direction. It will make a noise
 *  just before it backs up.
 * 
 * @author Addison Sears-Collins
 * @version 1.0 2019-05-12
 */

#define SPKR 5

// Create two servo objects, one for each wheel
Servo right_servo;
Servo left_servo;

// Volatile keyword is used because these variables
// can change at any time without any action having been
// taken by the compiled code. 

volatile int left_switch = LOW;   // Left switch flag
volatile int right_switch = LOW;  // Right switch flag
boolean already_started = false;  

/*   
 *  This setup code is run only once, when Arudino is 
 *  supplied with power.
 */
void setup() {
  // Set the pin modes for the switches
  pinMode(2, INPUT); // Right switch is input
  pinMode(3, INPUT); // Left switch is input
  pinMode(4, OUTPUT); // Pin 4 is ground
  
  // Turn on the internal pull up resistors for the switches
  // Keeps input from floating when the switches are not
  // pressed
  digitalWrite(2, HIGH);     // Right switch default to high
  digitalWrite(3, HIGH);     // Left switch default to high
  digitalWrite(4, LOW);      // Pin 4 default is ground

  right_servo.attach(9);      // Right servo is pin 9
  left_servo.attach(10);      // Left servo is pin 10
 
  // Declare the interrupts
  // attachInterrupt(digitalPinToInterrupt(pin), ISR, mode)
  // Interrupt when go from high to low
  attachInterrupt(digitalPinToInterrupt(2), hit_right, FALLING); 
  attachInterrupt(digitalPinToInterrupt(3), hit_left, FALLING);  
  
  already_started = true;  // Bot can now move
}

void loop() {
  if (left_switch == HIGH) {       // If the left switch is hit
    go_backwards();                // Go backwards for one second
    delay(1000); 
    go_right();                    // Turn to the right for one second
    delay(1000);
    go_forward();                  // Move forward
    left_switch = LOW;             // Reset the flag
  }
  
  if (right_switch == HIGH) {      // If the right switch is hit
    go_backwards();                // Go backwards for one second
    delay(1000); 
    go_left();                     // Turn left for one second
    delay(1000);
    go_forward();                  // Move forward
    right_switch = LOW;            // Reset the flag
  }
}
  
// Interrupt routine for left switch bumping into an object
void hit_left() {
  if (already_started)              // Valid if the program has begun
    left_switch = HIGH;             
}

// Interrupt routine for right switch bumping into an object
void hit_right() {
  if (already_started)              // Valid if the program has begun
    right_switch = HIGH;
}

/*   
 *  Forwards, backwards, right, left, stop.
 */
void go_forward() {
  right_servo.write(0);
  left_servo.write(180);
}
void go_backwards() {

  // Make a noise before you go backwards
  tone(SPKR, 247, 300); //247 Hz, 300ms
  delay(200);
  tone(SPKR, 131, 300);
  delay(200);
  tone(SPKR, 1175, 300);
  delay(200);
  right_servo.write(180);
  left_servo.write(0);
}
void go_right() {
  right_servo.write(180);
  left_servo.write(180);
}
void go_left() {
  right_servo.write(0);
  left_servo.write(0);
}
/*
void stop_all() {
  right_servo.write(90); // Tweak the 90
  left_servo.write(90);  // Tweak the 90
}
*/