I am struggling with getting CAN working on ODrive. In my present config we have an ESP32 with a CAN Transceiver.
Motor is configured and we have control over the GUI. It’s allegedly configured for heartbeats and CAN ID 3.
Our setup:
We tried 2 approaches.
- Sending CAN commands directly.
- Making a custom wrapper to get the example to work.
Neither works. This post is about approach 1, I’ll share another post for approach 2.
My code for directly sending a CAN message to go to Torque Control.
#include <CAN.h>
void setup() {
Serial.begin(115200);
while (!Serial)
;
Serial.println("CAN Sender");
// start the CAN bus at 500 kbps
if (!CAN.begin(500E3)) {
Serial.println("Starting CAN failed!");
while (1)
;
}
}
// ID for ODrive
int canID = (0x003 << 5) + 0x00B;
// Control Mode
// velocity control = 2, torque control = 1
uint8_t stmp[8] = {0,0,0,0,0,0,0,1};
//uint8_t stmp[8] = {0,0,0,1,0,0,0,0};
//uint8_t stmp[8] = {1,0,0,0,0,0,0,0};
//uint8_t stmp[8] = {0,0,0,0,1,0,0,0};
// uint32_t myControlMode = 1;
// uint8_t stmp[8] = {0};
void loop() {
Serial.println("Coppying Message");
//memcpy(stmp, &myControlMode, sizeof(myControlMode));
Serial.println("Sending Message");
CAN.beginPacket(canID);
CAN.write(stmp, 8);
CAN.endPacket();
Serial.println("Waiting...");
delay(5000);
// try to parse packet
int packetSize = CAN.parsePacket();
if (packetSize) {
// received a packet
Serial.print("Received ");
if (CAN.packetExtended()) {
Serial.print("extended ");
}
if (CAN.packetRtr()) {
// Remote transmission request, packet contains no data
Serial.print("RTR ");
}
Serial.print("packet with id 0x");
Serial.print(CAN.packetId(), HEX);
if (CAN.packetRtr()) {
Serial.print(" and requested length ");
Serial.println(CAN.packetDlc());
} else {
Serial.print(" and length ");
Serial.println(packetSize);
// only print packet data for non-RTR packets
while (CAN.available()) {
Serial.print((char)CAN.read());
}
Serial.println();
}
delay(5000);
Serial.println();
}
}
My approach inspired by this post.