Ask Your Question

How can ROS communicate with my microcontroller?

asked 2011-05-30 16:06:43 -0500

Bart gravatar image

updated 2014-01-28 17:09:46 -0500

ngrennan gravatar image

Some recent questions have shown an interest in how ROS can be used to run a motor or read a sensor on a custom robot. Many hobby robots have one or more microcontrollers that interface with the robot hardware. These microcontrollers should be able to communicate using a serial connection to a robot mounted laptop running ROS.

The avr_bridge is a sophisticated approach, but it requires a larger AVR processor and C++ code development on the microcontroller which may not be available in some circumstances. Is there a simpler alternative?

edit retag flag offensive close merge delete


@Bart - Can you provide a bit more explanation on when avr_bridge isn't suitable, perhaps chips you've had an issue with? I've been using it with the Arduino Duemilanove (ATmega328) and have been quite happy with its functionality. Thanks!
baalexander gravatar image baalexander  ( 2011-05-31 03:00:32 -0500 )edit
I have an ATmega16 that is already 85% full with ISR's, servo control and sensor processing. Some AVR's use a variant of Basic for programming. Some people are loyal to PIC microprocessors. I would like to try avr_bridge on my ATmega128 for a future project.
Bart gravatar image Bart  ( 2011-05-31 17:06:41 -0500 )edit

4 Answers

Sort by » oldest newest most voted

answered 2011-05-30 16:08:29 -0500

Bart gravatar image

updated 2011-05-30 16:20:01 -0500

A simple approach is to write a ROS node that can read/write text messages exchanged with the microcontroller over a serial port and convert these serial messages to ROS style std_msgs/String messages. A separate ROS node can then be written to convert the simple text messages to specific ROS message formats (cmd_vel, odom, etc) based on whatever message protocol was defined for the exchange with the microcontroller.

Attached below is the source for code that I used for this purpose. There is nothing original in the code, but it may be helpful to someone new to ROS and Unix/Linux serial communication. Posting this type of a listing may be a bit unconventional for this site as short answers are generally preferred. Hopefully no one is offended. I would be interested in hearing if there are other successful approaches to the problem.

 * Copyright (c) 2010, Willow Garage, Inc.                                                                               
 * All rights reserved.                                                                                                  
 * Redistribution and use in source and binary forms, with or without                                                    
 * modification, are permitted provided that the following conditions are met:                                           
 *     * Redistributions of source code must retain the above copyright                                                  
 *       notice, this list of conditions and the following disclaimer.                                                   
 *     * Redistributions in binary form must reproduce the above copyright                                               
 *       notice, this list of conditions and the following disclaimer in the                                             
 *       documentation and/or other materials provided with the distribution.                                            
 *     * Neither the name of the Willow Garage, Inc. nor the names of its                                                
 *       contributors may be used to endorse or promote products derived from                                            
 *       this software without specific prior written permission.                                                        
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE                                             
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE                                              
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR                                                   
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF                                                  
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS                                              
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN                                               
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)                                               
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE                                            
 * POSSIBILITY OF SUCH DAMAGE.                                                                                           


// communicate via RS232 serial with a remote uController. 
// communicate with ROS using String type messages.
// subscribe to command messages from ROS
// publish command responses to ROS

// program parameters - ucontroller# (0,1), serial port, baud rate

//Thread main
//  Subscribe to ROS String messages and send as commands to uController
//Thread receive
//  Wait for responses from uController and publish as a ROS messages

#include "ros/ros.h"
#include "std_msgs/String.h"
#include <sstream>
#include <pthread.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/time.h>
#include <fcntl.h>
#include <termios.h>
#include <stdio.h>
#include <stdlib.h>

#define DEFAULT_BAUDRATE 19200
#define DEFAULT_SERIALPORT "/dev/ttyUSB0"

//Global data
FILE *fpSerial = NULL;   //serial port file pointer
ros::Publisher ucResponseMsg;
ros::Subscriber ucCommandMsg;
int ucIndex;          //ucontroller index number

//Initialize serial port, return file ...
edit flag offensive delete link more


Interesting, but a lot of my serial stuff is send a message and receive a response back. Instead of separate publish/subscribes have you tried a service? That seems like it would work nicely for this.

Kevin gravatar image Kevin  ( 2012-02-22 15:51:55 -0500 )edit

@Bart Do you have a python version for this solution?

Spyros gravatar image Spyros  ( 2018-10-22 08:41:50 -0500 )edit

answered 2012-02-22 13:04:32 -0500

kleekru gravatar image

This seems to be exactly what I need... I think... but may be a little over my head so I will likely have a few questions regarding how to set this up. I'm using an arm attached to a BS2. I have a Roomba platform (that will have the arm attached) being controlled via a laptop running Ubuntu/ROS with web based control via php pages. I would like to use ROS to control the arm as well but I'm unsure of some of the basics. I have the ARM working through the Basic Stamp and I'm able to control the arm via the laptop keyboard... should I keep the BS2 microcontroller and send serial commands using the code above (if so, I'll have other questions)... or, is it better (even feasible...) to bypass the microcontroller and send commands directly to the arm using ROS? I think this is possible, but I'm a novice and need help connecting the dots. Any advice is greatly appreciated!

edit flag offensive delete link more


Agree, Bart's answer is cool, but is over kill for a beginner. If you pull out the thread stuff, but keep the serial setup, you can make something like the tutorials that talks to a serial port in the while loop.

Kevin gravatar image Kevin  ( 2012-02-22 14:31:16 -0500 )edit

answered 2012-11-19 23:57:06 -0500

Hi Bart,

My suggestion would be to use the cereal_port pkg on the serial_communication stack, you can install it on Fuerte by apt-get.

sudo apt-get install ros-fuerte-seria-communication

Its a ROS C++ wrapper for serial port reading and writing with a bunch of helpful functions such as readLine, readBetween, etc!

Hope this helps,

Gonçalo Cabrita

edit flag offensive delete link more

answered 2012-02-23 03:57:53 -0500

kleekru gravatar image

updated 2012-02-23 04:02:10 -0500

Thanks Kevin. I was thinking this must be simpler than that looks. You mention above using a service. Do you have an example? Does anyone have an example of python code that connects to a serial port (a linked USB in my case) and sends integers to a Microcontroller (BS2 in my case). I'll plug away with the publish/subscribe tutorials but it doesn't have the serial port part. I'm using the BS2 to actuate an arm. Thanks! Kevin

edit flag offensive delete link more



Please use the comment tags when replying to messages. Also commenting on an accepted question will not get you much help usually. If it's been accepted and closed for months I suggest you ask a new question referencing this one.

tfoote gravatar image tfoote  ( 2012-02-23 05:31:38 -0500 )edit

I played around with Bart's code and did a service. It seems to work pretty good. I am re-writing one of my robots to take advantage of it and see how ti works. Good Luck!!!

Kevin gravatar image Kevin  ( 2012-02-26 15:00:16 -0500 )edit

Kevin, How to use your service? Thanks a lot!

sonictl gravatar image sonictl  ( 2016-02-01 00:58:27 -0500 )edit

Your Answer

Please start posting anonymously - your entry will be published after you log in or create a new account.

Add Answer

Question Tools



Asked: 2011-05-30 16:06:43 -0500

Seen: 135,966 times

Last updated: Jan 28 '14