CAN bus shield -- using as a transmitter and receiver?

Hi everyone,

I’ve recently started a project using arduino and CAN where I want to be able to control servo motors through CAN. Currently, I have two arduinos + CAN shields on the CAN bus, where one is transmitting a CAN message to tell the receiver where the servo’s position should be. I am using the mcp_can.h library.

However, I am looking into using the CAN shield as both a transmitter and receiver, where the arduino controlling the servo can also send CAN messages back to the transmitter to report the servo’s position, for example. I am having some trouble implementing this, and I can’t find code anywhere that solves this problem. Attached is the code I have so far, MCP2515_T is the code that acts as the transmitter, and Servo_Test is for the receiver (servo controller). I believe the problem could be that CAN messages from the transmitter and receiver are being sent at the same time.

Any help would be greatly appreciated!

MCP2515_T.ino (1.77 KB)

Servo_Test3.ino (1.82 KB)

I believe the problem could be that CAN messages from the transmitter and receiver are being sent at the same time.

No. this is not a problem in CAN. The CAN bus drivers care about conflicting/busy bus. See CAN bus - Wikipedia

One of your problems is

delay(d);

delay = sleeping.
When your sender is sleeping he will not read messages from the other bus members.

Additionally you have to understand: don't think in an one-two-one "Request - Response" approach.
Each CAN Member is just sending its data. Additionally it can listen to messages on the bus.

So your "sender" just sends out "I want the Servo 42 to be set to 0815".
And then listens to the CAN Bus.

All other bus members will receive this message. But (in your case ) only one will react on that.
This other module will answer like "This is Servo 42, the new state is 0815".
Consider: There could also be a third device, like let's say a display which displays the states of the servos so this would also react on the Message of Servo 42.

if you have any delays in your "Sender" Sketch, it might miss the "This is Servo 42, the new state...".

So get rid of the delay. Write non-blocking code (like the IDE example BlinkWithoutDelay). Care about that your sketch can process "Sending" and "Reading" in near parallel.

This solved the problem. Thank you for the thorough response!