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

Arduino Ethernet Driver | Custom hardware publishing on topic via ethernet

asked 2017-05-04 04:22:37 -0500

mcarr gravatar image

updated 2017-05-04 08:12:09 -0500

I have a custom sensor which I am using with an Arduino. My ultimate goal (TL:DR) is to publish these sensor values on a ROS topic via Ethernet.

I am using a Ethernet shield and have completed the Arduino Ethernet tutorial which walked through creating a server which 'publishes' the sensor data via HTTP. On my PC browser (on the same network) I can navigate to the server/ethernet shield IP address and view the sensor values. I am familiar with fundamental ROS concepts but just a beginner in Ethernet communication, TCP/IP, etc

So what I'm trying to do is write a driver which 'reads' these sensor values, formats them into a custom rosmsg and publishes this rosmsg on a topic.

I would appreciate some tips if anyone is familiar with interfacing between custom hardware and ROS via ethernet. How would one go about the above things I mentioned? I guess it's to set up a socket listening to the sensor but have no idea how to start on this. I realise that a many sensor drivers do a similar thing as I'm trying to do. I know some SICK sensors communicate via Ethernet so effectively I'm trying to reproduce the same funtionality with my custom hardware. I did look at some of these drivers however couldn't understand them very well. If anyone has any links to tutorials / guide of something similar that would be great.

Also if anyone has any wisdom to impart or tips to offer, that would be great!

Cheers

edit retag flag offensive close merge delete

2 Answers

Sort by » oldest newest most voted
3

answered 2017-05-09 02:20:36 -0500

mcarr gravatar image

updated 2017-05-09 02:21:34 -0500

Will answer this myself.

I used the Arduino example "WebServer" from the library Ethernet2 as my Server. I then needed a client socket to 'listen' to this data. I used this code from the website Binary Tides as a base for my client socket and this tutorial to understand how the code works.
The next part was to use a string stream to convert the data being received into int arrays (actually vectors) of my desired size. I then created a custom ROS msg by following this tutorial then formatted my data as desired and published it using a basic ros publisher node.

If anyone is trying to publish data from an arduino (e.g. custom sensor) on a ROS topic via ethernet (TCP/IP) feel free to ask for help

edit flag offensive delete link more

Comments

hey I am trying something same, so I need to subscribe some ros messages and control servo motors. the communication has to be over ethernet. Any suggestions?

Arnav08 gravatar image Arnav08  ( 2017-05-24 08:42:42 -0500 )edit

the arduino has to subscribe the ros messages

Arnav08 gravatar image Arnav08  ( 2017-05-24 08:43:13 -0500 )edit

If you follow the links in my answer, you should be able to at least create a ROS node which can communicate with Arduino via Ethernet. Then you need make it subscribe to your servo topic as well. The Arduino Example "WebServer" is already reading data, have a look at that.

mcarr gravatar image mcarr  ( 2017-05-26 02:28:05 -0500 )edit

HERE is my code. You will have to edit most of it to be used in your application

mcarr gravatar image mcarr  ( 2017-05-26 02:42:10 -0500 )edit

Hey Thank you, i ll take a look at your code and will make sense out of it. Thanks for the help . i really appreciate it . Will contact you if face problems

Arnav08 gravatar image Arnav08  ( 2017-05-29 16:14:57 -0500 )edit

Hi, I'm trying to do the opposite way com, I mean, I'm trying to send data to arduino trough the Ethernet shield for remote operation of some actuators.... Could you please give me some ideas for do this? Thank you

Noel Cortés gravatar image Noel Cortés  ( 2017-06-22 16:06:24 -0500 )edit

Hi Noel, what I've discussed will let you communicate both directions with your Arduino. You will need to write a subscriber for the topic and the code I linked above can be used to send that data to your Arduino. Then you can use that to control your actuators. Hope that helps, Max

mcarr gravatar image mcarr  ( 2017-07-03 02:24:28 -0500 )edit
1

answered 2018-10-17 19:31:45 -0500

updated 2018-10-17 20:03:33 -0500

Max Carr did a fantastic job, thanks man! Having said that, I had a hard time with (1) getting the Arduino code figured out, and (2) a C++ program to communicate with the Arduino. My contribution (if you can call it that) to this topic is to provide the following:

  • Arduino code that uses sockets (not HTML or HTTP) to communicate to a C++ program. Arduino program can receive different types of requests from C++, and dish out the requested data.
  • C++ easily sends messages to Arduino, and collects the response.

You still have to convert the C++ code to a ROS package, but that is where Max Carr's answer is not at all ambiguous, and there are a ton of resources to figure that out on the ROS website. I will touch on that at the end. However the bulk of thsi answer deals with Arduino to C++ communication via sockets.

The hardware is a PC and an Arduino Mega with an ethernet shield. I have a switch in between.

image description

Quick note on the Arduino side of things - I see Arduino as a cheap, and effective way to collect the status of sensors (both analog and digital), and control simple devices (lights, relays, etc...). Since you are running ROS, you have ample processing power in your PC, so I don't see you sending the Arduino tons of data to crunch. right? So, the code below receives a 3 character request, where the first two characters are capital letters, followed by a ~ as the end of transmission terminator. The Arduino code receives this message, and depending on the combination of letters (ex: AA~, or AB~, or ZZ~, etc....) the Arduino will take the appropriate action (send a pre-canned command to some device, turn on actuators, or in my case respond with the status of various sensors). In my case I am sending 8 variables back to the C++ program (6 int and 2 float). I am packaging each data type with letters. so the response looks like this:

A123B
C456D
E98F
H-23.4532I
....
~~~

With the 3 ~ characters serving as the end of transmission.

Arduino Code

#include <SPI.h>
#include <Ethernet.h>
#include <SimpleTimer.h> //see: https://playground.arduino.cc/Code/SimpleTimer
#include "arduino2.h" //see: https://www.codeproject.com/Articles/732646/Fast-digital-I-O-for-Arduino

// The Mac address is BADA5512456 (BAD A55 [ASS] followed by 123456).
byte mac[] = {0xBA, 0xDA, 0x55, 0x12, 0x34, 0x56};

//The IP address is obviously static, and there is no conflicts with any 
//other device on the robot. 
IPAddress ip(192, 168, 0, 21);

// Initialize the Ethernet server library and assign  
// and port you want to use (port 80 is default for HTTP):
EthernetServer server(23500);

//variables that allow me to figure out what the client is requesting
int iterator = 0;
//made bigher than 3 elements to accomodate bad requests that don't follow my AA~ protocol;
//where the client sends a letter, followed by a letter followed by a ~ character to 
//let the server know the ...
(more)
edit flag offensive delete link more

Question Tools

2 followers

Stats

Asked: 2017-05-04 04:22:37 -0500

Seen: 2,180 times

Last updated: Oct 17 '18