ROS Resources: Documentation | Support | Discussion Forum | Index | Service Status | ros @ Robotics Stack Exchange
Ask Your Question

Using interrupts with rosserial_arduino to count wheel encoder pulses

asked 2017-01-07 07:52:59 -0500

epsilonjon gravatar image

updated 2017-01-09 15:05:32 -0500


I am trying to accurately measure my wheel velocities by counting the pulses coming from my encoders. My idea was to run an Arduino dedicated to only this task, which counts the pulses in the loop() function then uses a timer (from the Timer1 library) to trigger an interrupt service routine at a specified frequency (I was using 50Hz). Inside this ISR I work out the wheel velocity from the number of pulses counted over the 50Hz period, then publish this out over ROS.

Unfortunately when I try to connect to the node using rosserial_python, I get an error saying that it was expecting a certain number of bits but has received less than that, and the connection fails. Apologies, I don't have the Arduino with me right now so can't paste the full error, but will add it tomorrow if it will help diagnose the problem.

My guess is that whilst the Arduino is communicating back over serial, the ISR gets triggered, which interrupts the process, and ROS doesn't like it. Is this the case, or is something else going on? Can interrupts be used on an Arduino with ROS, or is this a no-go? If not, can anyone recommend a different way to count wheel encoder pulses over a well-defined time period?


Edit: the exact error I'm getting is

[WARN] [WallTime: 14839761.73.327399] Serial Port read returned short (expecting 81 bytes, received 24 instead).
[WARN] [WallTime: 14839761.73.328598] Serial Port read failure:
[INFO] [WallTime: 14839761.73.330119] Packet Failed : Failed to read msg data
[INFO] [WallTime: 14839761.73.331164] msg len is 8

My baud rate is left at the default 57600 and the data I'm sending is a custom msg containing two float32s.

edit retag flag offensive close merge delete


I implemented something like that and never had problems with a serial connection. Does it work if you just use the serial connection and a simple python script to read the data and convert it into a ROS-message?

NEngelhard gravatar image NEngelhard  ( 2017-01-07 09:30:51 -0500 )edit

What are the contents of the messages you are publishing/subscribing too, and their frequencies? Also, do you have the baud rate set to something other than the default? It is possible to overload the arduino connection with messages.

Steven_Daniluk gravatar image Steven_Daniluk  ( 2017-01-08 12:02:54 -0500 )edit

Steve_Daniluk, NEngelhard - please see edited question.

epsilonjon gravatar image epsilonjon  ( 2017-01-09 13:12:14 -0500 )edit

You know this already, but you shouldn't send to serial in ISR. You likely were reentering the ISR while still in it. If you have a serial port buffer, there will be cases where you could write to a buffer from ISR, but message should be smaller than buffer and buffer known to be empty before.

billy gravatar image billy  ( 2017-01-09 14:23:15 -0500 )edit

Of course - how stupid of me!

epsilonjon gravatar image epsilonjon  ( 2017-01-09 15:05:22 -0500 )edit

1 Answer

Sort by ยป oldest newest most voted

answered 2017-01-09 13:12:28 -0500

epsilonjon gravatar image

updated 2017-01-09 13:14:14 -0500

The error goes away if I don't do the publishing from inside the ISR, but instead from inside loop(). I then just create an "allow_publish" variable which gets set to true in the ISR, and use this to control when to publish in loop(). Not sure if this is the best way to approach it, but I'm getting a publish rate of 49.97 Hz using rostopic hz so it seems to be working okay.

edit flag offensive delete link more

Question Tools

1 follower


Asked: 2017-01-07 07:52:59 -0500

Seen: 956 times

Last updated: Jan 09 '17