CANopen and Arduino

Hi guys,

my project is about manipulating a robot with CAN messages. Originally there is a remote controller for the robot, but I want to controll the robot with my laptop via CANopen. So below is what I have done so far:

  1. Step : I first manipulated the robot with my remote controler.

  2. Step : Meanwhile I saved all the messages in a sd-card of my arduino (MEGA2560).

  3. Step : From my laptop I sent the saved messages back to the robot to replay what I have done with the remote controller.

  4. Step : The robot seems to do what I have done in the 1. Step, but with a smaller scale.

(e.g. I moved like 50 cm in z-direction in 1. Step. The robot actually moves just 10 cm in 4. Step)

My guess is that the speed the CAN messages are sent with is not correct. My CANopen expects every 50ms a signal but I am sending with 115200 baud rate. Can someone explain me how this problem can be handled ? I have just no clue, how I can calculate the approriate speed with this baudrate.

Hi,

I think we need more info, CanBus speeds are 250kbs or 500kbs or 1Mbs etc, 115200 is your serial monitor speed.

Also what are you sending?
For example, are you sending the final position for a particular movement, OR a little movement at a time to complete a movement.

What is the robot, data/specs link?
What was the original remote?
Is the robot a CanOpen device, or have you added CanOpen?

What is your hardware and software?

Thanks. Tom.. :slight_smile:

Thanks for those questions.

The speed of CANBus is 125 kbs.

Also what are you sending?

I am sending a little movement at a time to move the axis into the direction of joystick.

What is the robot, data/specs link?

The robot is a demolishing robot from Brokk.

Is the robot a CanOpen device, or have you added CanOpen?

It is a CanOpen device.

What is your hardware and software?

Arduino Mega 2560 with two MCP2515 CAN controller.Software that I am using is Arduino 1.8.7.

115200 is your serial monitor speed

Sure? According this page Serial.begin() - Arduino Reference I can set the baudrate with Serial.begin(115200) ...

The CANopen is a standard one, which means 11 bit for each frame. To achieve the CAN bus speed 125kbps,
I need 125000 / 11 = 11363 baudrate ? Is this reasonable?

Hi,
The fact that the distance is smaller, would not be due to your PC serial comms speed, that would, if it had an effect just slow down the response time.

I wonder if the old remote loaded parameters to the robot on startup. this included step sizes for the drive motor encoders, or are the motors stepper units?

Tom... :slight_smile:

TomGeorge:
I wonder if the old remote loaded parameters to the robot on startup. this included step sizes for the drive motor encoders, or are the motors stepper units?

The robot consists of hydraulic motors. With stepper motors it would be too easy :slight_smile:

Hi,
How does the robot know how far it has traveled?

Tom... :slight_smile:

Currently, the robot doesnt know anything. He just follows the CAN messages that I sent.

This has something to do with the speed of the message sending. If I put delay(1) in my loop() the robot travels much further. I guess in this case with delay the robot receives the message that he has to move much longer, so he travels further. But I do not know how to calculate the appropriate delay. Is my calculation reasonable at all?

The CANopen is a standard one, which means 11 bit for each frame. To achieve the CAN bus speed 125kbps,
I need 125000 / 11 = 11363 baudrate ? Is this reasonable?

So do you send code to turn say left and it will keep turning left until it is sent another code to stop.

xman236:
Currently, the robot doesnt know anything. He just follows the CAN messages that I sent.

This has something to do with the speed of the message sending. If I put delay(1) in my loop() the robot travels much further. I guess in this case with delay the robot receives the message that he has to move much longer, so he travels further. But I do not know how to calculate the appropriate delay. Is my calculation reasonable at all?

I would think from that comment, you are sending an open then close command to the hydraulic valve that supplies the motor.
When you add a delay, you delay the time between open and close commands, so the motor runs for longer period.
Again, nothing to do with PC serial speed, your original remote just sent the open closed signals further apart than you are with your remote setup.
How do you know that the commands that you are sending, should be making the robot move further.
Tom... :slight_smile:

TomGeorge:
When you add a delay, you delay the time between open and close commands, so the motor runs for longer period.

Yes, thats probably the reason. Then I do calculate the correct delay time? Because without delay the robot moves too less and with delay(1) too much. So some delay must be added with delayMicroseconds() if I am guessing right.

TomGeorge:
How do you know that the commands that you are sending, should be making the robot move further.

The commands that I am sending are just a repetition of commands that the remote controller sent. So ideally the result robot motion must be the same. But with my commands the robot touches a box. As I manipulated the robot with the remote controller the box was not contacted with the robot.

During the capture phase how did you verify that you recorded 100% of the packets?

SD cards have a very slow write transaction throughput. You will find many projects in this forum where people complain about this problem. SD cards are optimised for infrequent, but large writes, whereas the limited memory of an Arduino means that you need to do lots of small writes.

The only workaround is to switch to a faster storage medium such as FRAM memory, or send the data out of the serial port to a PC for capture.

Can you save each command from remote separately then send each as needed through the computer

mikb55:
The only workaround is to switch to a faster storage medium such as FRAM memory, or send the data out of the serial port to a PC for capture.

So do you think that the speed that the captured messages are resent with is not the problem? As the effect of delay() clearly shows the robot's movement is totally dependant how fast I send the captured message.

Now, appart from the storage problem, how can this sending speed be calculated?

xman236:
So do you think that the speed that the captured messages are resent with is not the problem? As the effect of delay() clearly shows the robot's movement is totally dependant how fast I send the captured message.

Now, appart from the storage problem, how can this sending speed be calculated?

When capturing the packets bypass the SD card and send the data to a computer. Check to see if the number of packets that the computer receives is higher than before. If so, then your SD card bottleneck is causing you to lose data.

For each packet you capture you also need to record a time stamp. When you replay the packets you send them with gaps corresponding to the original time stamps.

Even if you get the recording and playback perfect I'm not sure how useful this open loop system is going to be in the real world. A demolition robot moves on dusty ground and therefore the amount of track slip will vary over time causing positioning errors that will accumulate.

But what about the baudrate of the arduino? The arduinos sending speed depends on this baudrate.

The CANbus speed is 125kbps and the baudrate of arduino that I set with Serial.begin(115200) is way too fast than 125000 kbps / 11 bit. Does this mean that I must delay the loop() in my code or is my calculation not correct?

Hi,
Can you edit your code and add a press button to the mega, so instead of the PC giving the command to the motor, the button does?

Can you please post your code for the mega?

Thanks.. Tom.. :slight_smile:

xman236:
But what about the baudrate of the arduino? The arduinos sending speed depends on this baudrate.

The CANbus speed is 125kbps and the baudrate of arduino that I set with Serial.begin(115200) is way too fast than 125000 kbps / 11 bit. Does this mean that I must delay the loop() in my code or is my calculation not correct?

The bus speed doesn't tell you how many packets per second are sent from the controller to the robot. That is something that you need to measure using test equipment that is not constrained by storage or serial port limitations. Once you have some numbers you can calculate the average and peak bandwidth needed.

Hello guys,
I post here because I'm having a very similar problem with pretty much the same tools used by xman236.
I'm new to CANBus, in the sense that I never used it in my practice before, but... I did my homework and read the whole thing, to the best of my knowledge and abilities.

I'm also working with a robot, not a demolition one but a small surveillance robot.
It too has a remote control and by means of an oscilloscope first (that was my first instinct maybe because of my electronics engineering "upbringing") and later through reading the data with an Arduino Uno and an MCP2515 SPI shield, I managed to catch what I should send the robot in order to replicate what it received through the remote.
My ultimate goal is to be able to control the robot with a Raspberry Pi ( not an Arduino because I need network access to it and so I need the Ethernet part later).

I am close to achieveing my goal I think, although by no means the robot interprets the commands. The signal on the scope looks jittery and not clean, I admit.
I am generating them with an Arduino board and reading it at the same time with a second Arduino.
The Arduino at the receiving end shows the same as the remote does, same timing and all, but I imagine the signal I'm generating is bad.

I would like to validate this with you guys and of course I'm open to suggestions, etc.
Thanks in advance.

Regards from Argentina.
:confused: