Ping with arduino using micro ROS: possible?

Hi everyone,

I’m new in this field.

With my laptop and using ROS 2, I want to communicate with an Arduino DUE (with micro ROS running on it) connected to the companion computer.

After setting up micro ROS on my Arduino DUE and testing the serial communication on my laptop (following this tutorial), I confirmed that everything is working ok:

$ ros2 run micro_ros_agent micro_ros_agent serial --dev /dev/ttyACM0 -b 115200 -v6
[1678973917.856675] info     | TermiosAgentLinux.cpp | init                     | running...             | fd: 3
[1678973917.857069] info     | Root.cpp           | set_verbose_level        | logger setup           | verbose_level: 6
[1678973935.542156] info     | Root.cpp           | create_client            | create                 | client_key: 0x0793D525, session_id: 0x81
[1678973935.542255] info     | SessionManager.hpp | establish_session        | session established    | client_key: 0x0793D525, address: 0
[1678973935.542397] debug    | SerialAgentLinux.cpp | send_message             | [** <<SER>> **]        | client_key: 0x0793D525, len: 19, data: 
0000: 81 00 00 00 04 01 0B 00 00 00 58 52 43 45 01 00 01 0F 00

The next steps were:

  • connect the Arduino to the companion computer
  • create the serial port (baud rate 115200) and the UDP port (192.168.2.2:8888) using routing
  • communicate with the Arduino through the UDP using micro ROS on my topside laptop

But something is wrong:

$ ros2 run micro_ros_agent micro_ros_agent udp4 --ip 192.168.2.1 --port 8888
[1678974517.990334] info     | UDPv4AgentLinux.cpp | init                     | running...             | port: 8888
[1678974517.990704] info     | Root.cpp           | set_verbose_level        | logger setup           | verbose_level: 4
[1678974531.335043] error    | InputMessage.cpp   | log_error                | deserialization error  | buffer: 
0000: 7E 00 00 18 00 80 00 00 00
[1678974532.326210] error    | InputMessage.cpp   | log_error                | deserialization error  | buffer: 
0000: 7E 00

Any idea of what it might be?

Some extra info:

  • script on Arduino DUE: example publisher
  • ROS 2 version: galactic (inside a custom docker)
  • final target: read Ping from my laptop in the ROS 2 ecosystem

Eventually, does anyone know also how to read the Ping from ROS 1?

Can you share your code ?

Everything should work as expected since Ping should not interfere with ROS.

You can also check this forum post:

1 Like

Thanks for your quick reply, Patrick.

As previously mentioned, I am using the example publisher script:

#include <micro_ros_arduino.h>

#include <stdio.h>
#include <rcl/rcl.h>
#include <rcl/error_handling.h>
#include <rclc/rclc.h>
#include <rclc/executor.h>

#include <std_msgs/msg/int32.h>

rcl_publisher_t publisher;
std_msgs__msg__Int32 msg;
rclc_executor_t executor;
rclc_support_t support;
rcl_allocator_t allocator;
rcl_node_t node;
rcl_timer_t timer;

#define LED_PIN 13

#define RCCHECK(fn) { rcl_ret_t temp_rc = fn; if((temp_rc != RCL_RET_OK)){error_loop();}}
#define RCSOFTCHECK(fn) { rcl_ret_t temp_rc = fn; if((temp_rc != RCL_RET_OK)){}}


void error_loop(){
  while(1){
    digitalWrite(LED_PIN, !digitalRead(LED_PIN));
    delay(100);
  }
}

void timer_callback(rcl_timer_t * timer, int64_t last_call_time)
{  
  RCLC_UNUSED(last_call_time);
  if (timer != NULL) {
    RCSOFTCHECK(rcl_publish(&publisher, &msg, NULL));
    msg.data++;
  }
}

void setup() {
  set_microros_transports();
  
  pinMode(LED_PIN, OUTPUT);
  digitalWrite(LED_PIN, HIGH);  
  
  delay(2000);

  allocator = rcl_get_default_allocator();

  //create init_options
  RCCHECK(rclc_support_init(&support, 0, NULL, &allocator));

  // create node
  RCCHECK(rclc_node_init_default(&node, "micro_ros_arduino_node", "", &support));

  // create publisher
  RCCHECK(rclc_publisher_init_default(
    &publisher,
    &node,
    ROSIDL_GET_MSG_TYPE_SUPPORT(std_msgs, msg, Int32),
    "micro_ros_arduino_node_publisher"));

  // create timer,
  const unsigned int timer_timeout = 1000;
  RCCHECK(rclc_timer_init_default(
    &timer,
    &support,
    RCL_MS_TO_NS(timer_timeout),
    timer_callback));

  // create executor
  RCCHECK(rclc_executor_init(&executor, &support.context, 1, &allocator));
  RCCHECK(rclc_executor_add_timer(&executor, &timer));

  msg.data = 0;
}

void loop() {
  delay(100);
  RCSOFTCHECK(rclc_executor_spin_some(&executor, RCL_MS_TO_NS(100)));
}

I didn’t connect (yet) Ping. I am just publishing a topic with Arduino and checking if my topside laptop (running the micro ROS agent) can see it. I planned to connect Arduino with Ping as soon as I could communicate with Arduino.
Is there something wrong with this approach? Did I make some mistakes on the micro ROS side? Maybe both?