VESC CAN Message Structure

It’s probably too late now, but the vesc is open source :slightly_smiling_face: you don’t have to go through the trouble of reverse engineer anything, however you did a pretty good job figuring things out.

Message IDs are made of two parts, the lower 8 bits are for the actual node ID, while the remaining bits are the command packet IDs.

The CAN commands can be found here bldc/datatypes.h at master · vedderb/bldc · GitHub

typedef enum {
	CAN_PACKET_SET_DUTY = 0,
	CAN_PACKET_SET_CURRENT,
	CAN_PACKET_SET_CURRENT_BRAKE,
	CAN_PACKET_SET_RPM,
	CAN_PACKET_SET_POS,
	CAN_PACKET_FILL_RX_BUFFER,
	CAN_PACKET_FILL_RX_BUFFER_LONG,
	CAN_PACKET_PROCESS_RX_BUFFER,
	CAN_PACKET_PROCESS_SHORT_BUFFER,
	CAN_PACKET_STATUS, ...etc

You can also see how the message ID are composed from the different command functions: example

void comm_can_set_duty(uint8_t controller_id, float duty) {
	int32_t send_index = 0;
	uint8_t buffer[4];
	buffer_append_int32(buffer, (int32_t)(duty * 100000.0), &send_index);
	comm_can_transmit_eid(controller_id |
			((uint32_t)CAN_PACKET_SET_DUTY << 8), buffer, send_index);
}

And how the message id is decoded to get the node ID and packet command ID

if (rxmsg.IDE == CAN_IDE_EXT) {
				uint8_t id = rxmsg.EID & 0xFF;
				CAN_PACKET_ID cmd = rxmsg.EID >> 8;

Everything you need is just there in the source code :grin: https://github.com/vedderb/bldc/blob/master/comm_can.c

2 Likes