ROS Serial Several Sensor Msg as String

Hello,

I am a Robotics Engineering student from Germany and I am trying to create a project for my Uni.

I have a robot which has several Sensors that is received by Arduino and I am trying to publish the Sensor Data as a one line to ROS with ROS Serial
I have thought about using String messages and collect all Sensor data into a String.

    #include <SPI.h>
    #define CAN_2515
    const int SPI_CS_PIN = 9;
    const int CAN_INT_PIN = 2;
    #include "mcp2515_can.h"
    mcp2515_can CAN(SPI_CS_PIN); // Set CS pin
    //============================================================
    //ROS
    #include <ros.h>
    #include <std_msgs/String.h>
    ros::NodeHandle  nh;
    std_msgs::String str_msg;
    ros::Publisher pub_IRCanbus("IRCanbus", &str_msg);
    char frameid[] = "/IRdata";
    //============================================================
    const int LED = 8;
    int IR1;
    int IR2;
    int IR3;
    int IR4;
    int IR5;
    int IR6;
    //============================================================
    //============================================================
    void setup() {
    //============================================================
      nh.initNode();
      nh.advertise(pub_IRCanbus);
    //============================================================
        SERIAL_PORT_MONITOR.begin(115200);
        pinMode(LED, OUTPUT);
        while (CAN_OK != CAN.begin(CAN_250KBPS)) {             // init can bus : baudrate = XX
            SERIAL_PORT_MONITOR.println("CAN init fail, retry...");
            delay(100);
        }
        SERIAL_PORT_MONITOR.println("CAN init ok!");
    //============================================================
    }
    //============================================================
    //============================================================
    void loop() {
        unsigned char len = 0;
        unsigned char buf[8];
    
        if (CAN_MSGAVAIL == CAN.checkReceive()) {         // check if data coming
            CAN.readMsgBuf(&len, buf);    // read data,  len: data length, buf: data buf
    
            unsigned long canId = CAN.getCanId();
       
            for (int i = 0; i < len; i++) { // print the data  
                    if (canId==30) {
                    IR1=buf[6];
                    }                     
                    if (canId==31) {
                    IR2=buf[6];
                    }                    
                      if (canId==33) {
                    IR3=buf[6];
                    }                
                    if (canId==34) {
                    IR4=buf[6];
                    }                
                    if (canId==35) {
                    IR5=buf[6];
                    }
                    if (canId==36) {
                    IR6=buf[6];
                    }
    
    SERIAL_PORT_MONITOR.print("|" + String(IR1) + "," + String(IR2)+ ","+ String(IR3)+ "," + String(IR4)+ "," + String(IR5) + "," + String(IR6)+"|\n");
                 String IRStringMessage2Send =("|" + String(IR1) + "," + String(IR2)+ ","+ String(IR3)+ "," + String(IR4)+ "," + String(IR5) + "," + String(IR6)+"|\n");
    
    
                 str_msg.data = IRStringMessage2Send;
                 pub_IRCanbus.publish( &str_msg );
                 nh.spinOnce();
                 delay(1000);
    
            }
        }
    }
    //============================================================
    //============================================================
    //END FILE

However, I faced with an error that says
"cannot convert 'String' to 'std_msgs::String::_data_type {aka const char*}' in assignment"
which I understand as String.msg is not String type but string type of data.

I am wondering if it would be possible to send these data as a String or string message as one line?
I am a bit new to C++ and ROS, so I would be grateful if you could give me any kind of suggestion that can aid my problem.

Thank you very much.

try sprintf()

i have tryed this and it compiles without error

uint8_t IR1 = 49;
uint8_t IR2 = 50;
uint8_t IR3 = 51;
uint8_t IR4 = 52;
uint8_t IR5 = 53;
uint8_t IR6 = 54;

void setup() {
  Serial.begin(115200);
  char IRStringMessage2Send[] = {
    '|',
    (char)IR1,
    (char)IR2,
    (char)IR3,
    (char)IR4,
    (char)IR5,
    (char)IR6,
    '\n'
    };
  Serial.write(IRStringMessage2Send, sizeof (IRStringMessage2Send));
}

void loop() {
}

you are missing a trailing null char '\0' to be able to use print afterwards. it might work if you get lucky an the next byte is null in memory or use

Serial.write(IRStringMessage2Send, sizeof IRStringMessage2Send);

but to the original question, instead of

    SERIAL_PORT_MONITOR.print("|" + String(IR1) + "," + String(IR2)+ ","+ String(IR3)+ "," + String(IR4)+ "," + String(IR5) + "," + String(IR6)+"|\n");
                 String IRStringMessage2Send =("|" + String(IR1) + "," + String(IR2)+ ","+ String(IR3)+ "," + String(IR4)+ "," + String(IR5) + "," + String(IR6)+"|\n");
   

there is no need to use more memory than needed... just use multiple write()

SERIAL_PORT_MONITOR.write('|');
SERIAL_PORT_MONITOR.write(IR1);
SERIAL_PORT_MONITOR.write(',');
SERIAL_PORT_MONITOR.write(IR2);
SERIAL_PORT_MONITOR.write(',');
SERIAL_PORT_MONITOR.write(IR3);
SERIAL_PORT_MONITOR.write(',');
SERIAL_PORT_MONITOR.write(IR4);
SERIAL_PORT_MONITOR.write(',');
SERIAL_PORT_MONITOR.write(IR5);
SERIAL_PORT_MONITOR.write(',');
SERIAL_PORT_MONITOR.write(IR6);
SERIAL_PORT_MONITOR.write('|');
SERIAL_PORT_MONITOR.write('\n');
1 Like

one single byte to all six IR's ?

//============================================================
#include <SPI.h>
#define CAN_2515
const int SPI_CS_PIN = 9;
const int CAN_INT_PIN = 2;
#include "mcp2515_can.h"
mcp2515_can CAN(SPI_CS_PIN); // Set CS pin
//============================================================
//ROS
#include <ros.h>
#include <std_msgs/String.h>
ros::NodeHandle  nh;
std_msgs::String str_msg;
ros::Publisher pub_IRCanbus("IRCanbus", &str_msg);
char frameid[] = "/IRdata";
//============================================================
const int LED = 8;
uint8_t IR1 = 49;
uint8_t IR2 = 50;
uint8_t IR3 = 51;
uint8_t IR4 = 52;
uint8_t IR5 = 53;
uint8_t IR6 = 54;
//============================================================
//============================================================
void setup() {
  //============================================================
  nh.initNode();
  nh.advertise(pub_IRCanbus);
  //============================================================
  SERIAL_PORT_MONITOR.begin(115200);
  pinMode(LED, OUTPUT);
  while (CAN_OK != CAN.begin(CAN_250KBPS)) {             // init can bus : baudrate = XX
    SERIAL_PORT_MONITOR.println("CAN init fail, retry...");
    delay(100);
  }
  SERIAL_PORT_MONITOR.println("CAN init ok!");
  //============================================================
}
//============================================================
//============================================================
void loop() {
  unsigned char len = 0;
  unsigned char buf[8];

  if (CAN_MSGAVAIL == CAN.checkReceive()) {         // check if data coming
    CAN.readMsgBuf(&len, buf);    // read data,  len: data length, buf: data buf

    unsigned long canId = CAN.getCanId();

    for (int i = 0; i < len; i++) { // print the data
      if (canId == 30)IR1 = buf[6];
      if (canId == 31)IR2 = buf[6];
      if (canId == 33)IR3 = buf[6];
      if (canId == 34)IR4 = buf[6];
      if (canId == 35)IR5 = buf[6];
      if (canId == 36)IR6 = buf[6];
      char IRStringMessage2Send[] = {
        '|',
        (char)IR1,
        ',',
        (char)IR2,
        ',',
        (char)IR3,
        ',',
        (char)IR4,
        ',',
        (char)IR5,
        ',',
        (char)IR6,
        '|',
        '\n'
      };
      Serial.write(IRStringMessage2Send, sizeof (IRStringMessage2Send));
      SERIAL_PORT_MONITOR.write(IRStringMessage2Send, sizeof (IRStringMessage2Send));

      str_msg.data = IRStringMessage2Send;
      pub_IRCanbus.publish( &str_msg );
      nh.spinOnce();
      delay(1000);
    }
  }
}
//============================================================
//============================================================
//END FILE

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.