Hi there,
This project has been pretty fun but recently I faced a roadblock and have been stuck for a while. Would be greatly appreciative of anyone who can solve this issue.
Objective: Use the Arduino to control the EPOS4 Motor
My Method: Use CAN communication
Connection Chain:
- Arduino MEGA
- CAN-BUS Shield 13262 (SparkFun)
- CAN-COM cable (Maxon 520857), I call this the RS232-CAN cable
- CAN end goes to EPOS4 Compact X11 connector
- The Maxon motor is a combination of three parts
- EC-i 40 Ø40 mm, brushless, 100 Watt, with Hall sensors | High Torque (Maxon 496661)
- Planetary Gearhead GP 42 C Ø42 mm, 3 - 15 Nm, Ceramic Version | Ceramic Version (Maxon 203124)
- Encoder ENC 16 EASY, 1024 pulses (Maxon 499361)
My main issue lies with the CAN-BUS Shield board. So let's start here
I understand that the CAN-BUS shield 13262 SparkFun product is built for OBDII usage by default.
However, it recommends "switching the jumpers" in order to operate using CAN Communication. I did that by swapping the wires inside the RS232-CAN cable because I could not figure out how to swap the pins on the CAN-BUS Shield board.
The image below shows the original wiring:
I rearranged the wires such that CANH on the CAN-BUS board goes to CANH on the EPOS4 X11 connection. CANL and GND on both boards are also now synced on the new pins. If you look at segment 2 of the image below, that is the final configuration. I used the multimeter to verify that the CANH and CANL lines on both boards are linked. I shorted the last two pins (Ground and Shield) together.
Now looking at segment 1 of the image above, you will see the pin connections between the CAN-BUS Shield and the Arduino MEGA. The Arduino MEGA's code will utilise the SPI.h library. And so I believe MOSI will be set automatically to pin 51, MISO will be set to pin 50, SCK will be set to pin 52, and CS will be pin 53.
The CAN-BUS Shield's schematic shows that pin 12, 11, 13, 10, and 2 are MISO, MOSI, SCK, CS, and interrupt respectively. I confirmed this by using a multimeter and checking that pins 12,11,13,10, and 2 are shorted to the MCP2515's respective MISO, MOSI, SCK, CS, and Interrupt pins.
Other Considerations
I am aware that it is good practice to have a 120ohm terminating resistor between the CANH and CANL lines at the start and end of the lines for both devices. However, only the EPOS4 compact CAN 50/5 module has this terminating resistor (in-built). And it is activated by turning on the 7th switch of the DIP switch in the middle of the EPOS4 Compact. The CAN-BUS Shield does not have this 120 ohm terminating resistor. It does have 100 ohm from both CANH and CANL lines going to ground after a decoupling resistor, but that does not count as a terminating resistor. I checked the MCP2515 and MCP2551 datasheets, and also the CAN-BUS Shield Schematic, it seems that there is no 120ohm resistor internally between the CANH and CANL lines that comes from that board. I did not do anything about this, and did not externally add a 120ohm resistor.
The Code (I believe this is the issue?)
#include <SPI.h>
const int SPI_CS_PIN = 53;
MCP_CAN CAN(SPI_CS_PIN);
void setup() {
Serial.begin(115200);
while (CAN_OK != CAN.begin(MCP_STDEXT, CAN_500KBPS, MCP_16MHZ)) {
Serial.println("CAN Init Failed");
delay(200);
}
Serial.println("CAN Init OK");
// Set Operation Mode to Profile Velocity Mode (typically 3 for EPOS4)
setOperationMode(0x03);
// Enable Drive
enableDrive();
// Set motor speed to 2000 RPM
setMotorRPM(2000);
}
void loop() {
// Empty loop
}
void setOperationMode(byte mode) {
byte message[] = {0x2F, 0x60, 0x60, 0x00, mode, 0x00, 0x00, 0x00};
CAN.sendMsgBuf(0x601, 0, 8, message); // Node ID should be adjusted
}
void enableDrive() {
// Control word for "switch on and enable operation"
byte message[] = {0x2B, 0x40, 0x60, 0x00, 0x0F, 0x00, 0x00, 0x00};
CAN.sendMsgBuf(0x601, 0, 8, message); // Node ID should be adjusted
}
void setMotorRPM(int rpm) {
long velocity = rpm * 60; // Adjust conversion factor as needed
byte message[] = {0x23, 0xFF, 0x60, 0x00, (byte)(velocity & 0xFF), (byte)((velocity >> 8) & 0xFF), (byte)((velocity >> 16) & 0xFF), (byte)((velocity >> 24) & 0xFF)};
CAN.sendMsgBuf(0x601, 0, 8, message);
}
What you see above is an attempt to simply drive the motor at 2000rpm. The purpose of this code is just to check that the CAN communication works. The output of the code is always:
CAN Init Failed
Init Failed
Entering Configuration Mode Failure...
CAN Init Failed
Entering Configuration Mode Failure...
CAN Init Failed
And this is where I got stuck. I have never done CAN coding in my life and this is a huge challenge to me. The connections are all good (or so it seems), yet the code does not work.
Huge thanks in to whoever is able to solve this issue.


