Does anyone have a well detailed write-up on the VESC CAN message structure? I’ve tried reverse engineering the code but it’s not making a whole lot of sense compared to what’s broadcast. I’ve found out that vedder seems to be using extended message IDs, and laid a bit of J1939 thinking in that the node id is essentially the source address in the status broadcast message. The last 2 bytes appear to be the commanded duty cycle in tenths of percent. I’ve yet to attempt commanding or intercepting command messages yet but I’ll be continuing this and if I map out the whole message structure, I’ll share my findings cause CAN is a very robust communication system that more of us should be using for safety.
Bit of an update, I’ve got the status broadcast message mostly solved, mostly meaning I’m not sure what increments the current is getting sent in. btw I’m using an arduino with a can bus module using the MCP_CAN library to run these tests. Also keep in mind that if your CAN bus is connected to more than 2 vescs, you need to mind the terminating resistors, probably will need to desolder them from the other vescs.
The ID is an extended ID: 0x00000900
The 9 is the message type, in this case it’s the status broadcast, the zeros after the 9 are what node it’s being sent from, in this case node 0, kinda like a J1939 source address. With my experiments so far, this is pretty much how you format the messages for transmitting them. In the case of transmission, the node number to the vesc you want to command, and the message type to what parameter you want to command. The message types are as follows:
- Duty Cycle Set: 0
- Current Set: 1
- Current Set Brake: 2
- RPM Set: 3
- Pos(ition?) Set: 4
- 5-8 have something to do with rx buffers, haven’t messed with it yet.
- and status which is 9 as I said earlier.
The status message payload is organized as follows:
- bytes 1-4 are the current RPM as a whole number, from most significant byte to least significant, respectively.
- bytes 5 and 6 are the current current, most to least, but I’m not sure what units yet.
- bytes 7 and 6 are the current dutycycle in 10ths of a percent, from most to least.
I’m still looking into making coherent commands, for some reason commanding rpm or current at 1 causes it to max out, and has a tendency to overflow repeatedly, think it’s a datatype packing issue, might make a library when I figure it out.