Ask Your Question
0

Doubt regarding serial communication

asked 2015-07-09 04:44:20 -0500

vinjk gravatar image

updated 2015-07-09 20:44:54 -0500

Hi all,

I am new to ROS and Linux. I am using ROS Indigo on Ubuntu 14.04 LTS. I am trying to establish serial communication with an microcontroller using ROS serial package ( https://github.com/wjwwood/serial ). Came across an example program by garyservin ( https://github.com/garyservin/serial-... ). The program works well.

The instruction packet I want to send to MCU has start bytes "@@". However, when I try to publish to this to the topic "write" I get this error:

rostopic: error: Argument error: while scanning for the next token found character '@' that cannot start any token   in "<string>", line 1, column 1:
    @@1233
    ^

Similarly if I try to send a number I get this error:

ERROR: Unable to publish message. One of the fields has an incorrect type:
  field data must be of type str

The datatype used in the example program is std_msgs/String.

What I want to send is actually data in hex code. Something like 0x40 0x40 0x09 0x01 0x00 0x00 0x02 0x0d 0x0a

Could someone guide me on how to solve this problem?

UPDATE

#include <ros/ros.h>
#include <serial/serial.h>
#include <std_msgs/String.h>
#include <std_msgs/Empty.h>

serial::Serial ser;

void write_callback(const std_msgs::String::ConstPtr& msg){
    ROS_INFO_STREAM("Writing to serial port" << msg->data);
    ser.write(msg->data);
}

int main (int argc, char** argv){
    ros::init(argc, argv, "serial_example_node");
    ros::NodeHandle nh;

    ros::Subscriber write_sub = nh.subscribe("write", 1000, write_callback);
    ros::Publisher read_pub = nh.advertise<std_msgs::String>("read", 1000);

    try
    {
        ser.setPort("/dev/ttyACM0");
        ser.setBaudrate(9600);
        serial::Timeout to = serial::Timeout::simpleTimeout(1000);
        ser.setTimeout(to);
        ser.open();
    }
    catch (serial::IOException& e)
    {
        ROS_ERROR_STREAM("Unable to open port ");
        return -1;
    }

    if(ser.isOpen()){
        ROS_INFO_STREAM("Serial Port initialized");
    }else{
        return -1;
    }

    ros::Rate loop_rate(5);
    while(ros::ok()){

        ros::spinOnce();

        if(ser.available()){
            ROS_INFO_STREAM("Reading from serial port");
            std_msgs::String result;
            result.data = ser.read(ser.available());
            ROS_INFO_STREAM("Read: " << result.data);
            read_pub.publish(result);
        }
        loop_rate.sleep();

    }
}

Thanks!

edit retag flag offensive close merge delete

Comments

It looks like you're writing a node in python which is publishing to a topic with the std_msgs/String type. You should post the source for that program if you want help with it, or follow @William's suggestion and just modify the example program.

ahendrix gravatar imageahendrix ( 2015-07-09 18:57:52 -0500 )edit

Sorry about that. The program is the same one made by garyservin (see the link). I've posted the program in my question for your convenience. It's C++ program.

vinjk gravatar imagevinjk ( 2015-07-09 20:46:27 -0500 )edit

The error message you post is clearly coming from a python program, and not for the sample code. If you're publishing to the write topic using rostopic, please include the exact command you're running.

ahendrix gravatar imageahendrix ( 2015-07-09 23:02:07 -0500 )edit

This is the exact command I tried to run

rostopic pub /write -r 100 std_msgs/String @@1233
vinjk gravatar imagevinjk ( 2015-07-10 00:39:51 -0500 )edit

Did you try putting the string you want to send in quotes?

William gravatar imageWilliam ( 2015-07-10 02:05:57 -0500 )edit

@William I had tried that as well

vinjk gravatar imagevinjk ( 2015-07-10 03:34:53 -0500 )edit

2 Answers

Sort by ยป oldest newest most voted
0

answered 2015-07-10 03:32:29 -0500

vinjk gravatar image

Hi @William , @ahendrix

I solved the problem. I did as per William's suggestion used UInt8MultiArray datatype. But before writing it to the serial port I convert it to string.

void write_callback(const std_msgs::UInt8MultiArray::ConstPtr& msg)
{
    std::string str(msg->data.begin(), msg->data.end());
    ser.write(msg->data);
}

I used the command below (just an example) to publish to topic /write

rostopic pub /write std_msgs/UInt8MultiArray '{data: [64,64,11,1,1,1,2,208,32,13,10]}'
edit flag offensive delete link more

Comments

Thank you guys for your time.

vinjk gravatar imagevinjk ( 2015-07-10 03:37:12 -0500 )edit
1

answered 2015-07-09 16:12:54 -0500

William gravatar image

This isn't the most efficient way to talk with your micro, you could just modify the example to write directly to you micro or you could modify the node to take an array of uint8_t's rather than a string.

edit flag offensive delete link more

Comments

tried as you suggested. Used std_msgs/UInt8MultiArray instead of std_msgs/String

void write_callback(const std_msgs::UInt8MultiArray::ConstPtr& msg){        
    //ROS_INFO_STREAM("Writing to serial port " << msg->data);
    ser.write(msg->data);
}

Nothing is send or received

vinjk gravatar imagevinjk ( 2015-07-09 22:17:18 -0500 )edit

[character limit reached in prev comment so writing this here]

I executed this in another terminal

rostopic pub /write std_msgs/UInt8MultiArray '{data: [82, 79, 83]}' -r 1
vinjk gravatar imagevinjk ( 2015-07-09 22:21:16 -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

1 follower

Stats

Asked: 2015-07-09 04:44:20 -0500

Seen: 552 times

Last updated: Jul 10 '15