Ask Your Question
0

Data loss in rosserial for arduino to pc [closed]

asked 2018-02-02 07:02:21 -0500

urad gravatar image

Hi there.

I using rosserial to communicate pc to arduino. I use timer interruptions for publishing.

But, when I use timer interruptions, rosserial said "wrong checksum for topic id and msg". This error occurs in almost same timing, such as one in 20 seconds.

Is there anyone who understands the cause?

Thanks in advance.

My codes here.

#include <ros.h>
#include <std_msgs/UInt64.h>
#include <CurieTimerOne.h>

ros::NodeHandle nh;

std_msgs::UInt64 msgs;
ros::Publisher unnamed_publisher("empty_topic", &msgs);

void intFunc()
{
    msgs.data = millis();
    unnamed_publisher.publish(&msgs);
}

void setup()
{
    nh.initNode();
    nh.advertise(unnamed_publisher);

    // Interrupt 50 hz
    int secToMicro = 1e6;
    int Hz = 100;
    CurieTimerOne.start(secToMicro / Hz, intFunc);
}

void loop()
{
    delay(100);
    nh.spinOnce();
}
edit retag flag offensive reopen merge delete

Closed for the following reason the question is answered, right answer was accepted by urad
close date 2018-02-07 22:57:45.483265

1 Answer

Sort by ยป oldest newest most voted
1

answered 2018-02-07 09:38:54 -0500

rreignier gravatar image

I have never encounter this issue, but you should not publish within an interrupt handler.

It is generally a bad idea to do complex things (such as serialize and send through a serial port) during an interrupt (note that your millis() counter will stop counting while you are in the handler so you should make it as short as possible).

You should set a flag in the interrupt and publish in your main loop if the flag is set.

Something like:

#include <ros.h>
#include <std_msgs/UInt64.h>
#include <CurieTimerOne.h>

ros::NodeHandle nh;

std_msgs::UInt64 msgs;
ros::Publisher unnamed_publisher("empty_topic", &msgs);
bool publish_flag = false;

void intFunc()
{
    msgs.data = millis();
    publish_flag = true;
}

void setup()
{
    nh.initNode();
    nh.advertise(unnamed_publisher);

    // Interrupt 50 hz
    int secToMicro = 1e6;
    int Hz = 100;
    CurieTimerOne.start(secToMicro / Hz, intFunc);
}

void loop()
{
    if(publish_flag)
    {
        unnamed_publisher.publish(&msgs);
        publish_flag = false;
    }

    nh.spinOnce();
    delay(1); // optional
}
edit flag offensive delete link more

Comments

Thank you for your answer. I didn't know how to gently use microcontrollers, especially about interrupts. I follow your advice and now it seems correctly works very well.

I am grateful for your support. Thanks!

urad gravatar imageurad ( 2018-02-07 21:07:55 -0500 )edit

Your welcome. If your question is answered, please mark the answer as correct so others will find this problem as solved.

rreignier gravatar imagerreignier ( 2018-02-08 02:42:55 -0500 )edit

Question Tools

1 follower

Stats

Asked: 2018-02-02 07:02:21 -0500

Seen: 170 times

Last updated: Feb 07 '18