VESC Uart communication

vedder

100 W
Joined
Nov 5, 2011
Messages
249
I have finally written a tutorial for communicating with the VESC using UART. It would be nice if someone can give this a try:
http://vedder.se/2015/10/communicating-with-the-vesc-using-uart/
 
Great, I just tested it with my STM32 Discovery and it works well.
Only the 'val' command uses UART, all the other commands (help, info etc) don't require VESC.

The 'val' command indeed returns the values in the terminal:

Code:
ch> val
ch> 
Input voltage: 26.29 V
Temp:          24.29 degC
Current motor: 0.23 A
Current in:    0.00 A
RPM:           0.0 RPM
Duty cycle:    0.1 %
Ah Drawn:      0.0000 Ah
Ah Regen:      0.0000 Ah
Wh Drawn:      0.0000 Wh
Wh Regen:      0.0000 Wh
Tacho:         2 counts
Tacho ABS:     2 counts
Fault Code:    FAULT_CODE_NONE


For anyone interested in communicating to VESC using Arduino UART, you can use the script by pkondratyuk:
https://github.com/erwincoumans/ArduinoServoTxRx/tree/master/VescUart
Also CAN bus over Arduino+CAN bus shield (by Seeedstudio) works too, using the same packets as in this new Vedder UART Tutorial:
https://github.com/erwincoumans/ArduinoServoTxRx/blob/master/canbus/canbus.ino

IMG_5663.JPG
 
So I've been trying to get data back from my VESC this weekend, but no joy so far.

I'm using an Arduino, and based largely on pkondratyuk's code, just modified to call COMM_GET_VALUES which should return me a nice stream of data about voltages, amps, RPMs, etc.

I am no expert on Arduino or serial communication, but I expect to call this, then see a return stream from the VESC uart, but it seems to stay silent.

It might be worth mentioning that I can talk to VESC perfectly, and control it over uart from the same Arduino setup.

This is the function I've got:

Code:
void GetValues()
{
    unsigned char buff[9];
    int32_t ind = 0;
  
    buff[ind++] = 2;
    buff[ind++] = 5;
    buff[ind++] = COMM_GET_VALUES;
  
    uint16_t crc = crc16(buff + 2, 5);
    buff[ind++] = crc >> 8;
    buff[ind++] = crc;
  
    buff[ind++] = 3;
  
    WriteArray(buff,9);
}

I don't pass a val, only a command.

I wasn't sure if this was a large or small packet (2 or 3 for 2nd byte).

My VESC is running 1.6 firmware.

Anyone got any ideas or tips that may help? Thanks!
 
benj said:
So I've been trying to get data back from my VESC this weekend, but no joy so far.

I'm using an Arduino, and based largely on pkondratyuk's code, just modified to call COMM_GET_VALUES which should return me a nice stream of data about voltages, amps, RPMs, etc.

I am no expert on Arduino or serial communication, but I expect to call this, then see a return stream from the VESC uart, but it seems to stay silent.

It might be worth mentioning that I can talk to VESC perfectly, and control it over uart from the same Arduino setup.

This is the function I've got:

Code:
void GetValues()
{
    unsigned char buff[9];
    int32_t ind = 0;
  
    buff[ind++] = 2;
    buff[ind++] = 5;
    buff[ind++] = COMM_GET_VALUES;
  
    uint16_t crc = crc16(buff + 2, 5);
    buff[ind++] = crc >> 8;
    buff[ind++] = crc;
  
    buff[ind++] = 3;
  
    WriteArray(buff,9);
}

I don't pass a val, only a command.

I wasn't sure if this was a large or small packet (2 or 3 for 2nd byte).

My VESC is running 1.6 firmware.

Anyone got any ideas or tips that may help? Thanks!

That will not work. The length of the command is 1, not 5. The command you based this on is probably one where you send data after the command. Try this:

Code:
void GetValues()
{
    unsigned char buff[9];
    int32_t ind = 0;
  
    buff[ind++] = 2;
    buff[ind++] = 1; // This is the length of the payload. Just one in this case.
    buff[ind++] = COMM_GET_VALUES;
  
    uint16_t crc = crc16(buff + 2,  ind - 2);
    buff[ind++] = crc >> 8;
    buff[ind++] = crc;
  
    buff[ind++] = 3;
  
    WriteArray(buff, ind);
}

Have you given my tutorial a try yet? It should be easy to implement it on arduino.
 
Vedder,

While I am waiting for my VESC to get here, is there anything i can do to "emmulate" the VESC to try some of these things out?

Kinda like how they do it for Android programming
 
So I got a bit further with this implementation, I have data coming back from VESC, but it seems to be a garbled mess.

I have to use a Software based serial port, and I think it's dropping serial data or not processing fast enough to stream the packets correctly.

Vedder, I did try your header files and instructions, but my Arduino seems to hang in my send_packet function, probably this SoftwareSerial port not liking something.

I've ordered a BLE UART adaptor http://www.adafruit.com/product/2479, so I can just chuck that directly on the VESC UART output, and talk to it without an Arduino interface, which is cool, but I had other plans with the Bean I'll have to drop.
 
Time for an update. I have moved onto the Adafruit UART friend and now have different problems and odd results!

This should be a simple setup, RX to TX, TX to RX, also connecting the Adafruit CTS to GND. Set all baud rates to 9600 and should be good to go.

Now the good news :D The VESC does respond to COMM_GET_VALUES. I thought I was winning...but the response isn't quite right.

Raw message packet back - this looks great - the expected start byte and end byte and 60 bytes

Code:
(uint8_t [256]) messageReceived = {
  [0] = '\x02'
  [1] = '8'
  [2] = '\x04'
  [3] = '\0'
  [4] = '\xec'
  [5] = '\0'
  [6] = '\xec'
  [7] = '\0'
  [8] = '\xec'
  [9] = '\0'
  [10] = '\xec'
  [11] = '\0'
  [12] = '\xed'
  [13] = '\0'
  [14] = '\xed'
  [15] = '\0'
  [16] = '\xed'
  [17] = '\xff'
  [18] = '\xff'
  [19] = '\xff'
  [20] = '\xfd'
  [21] = '\0'
  [22] = '\0'
  [23] = '\0'
  [24] = '\x01'
  [25] = '\x03'
  [26] = '\xb6'
  [27] = '\0'
  [28] = '\0'
  [29] = 'S'
  [30] = '\x96'
  [31] = '\0'
  [32] = '\xea'
  [33] = '\0'
  [34] = '\0'
  [35] = '\0'
  [36] = '/'
  [37] = '\0'
  [38] = '\0'
  [39] = '\0'
  [40] = '\0'
  [41] = '\0'
  [42] = '\0'
  [43] = '\x04'
  [44] = 'W'
  [45] = '\0'
  [46] = '\0'
  [47] = '\0'
  [48] = '\t'
  [49] = '\0'
  [50] = '\0'
  [51] = '\x7f'
  [52] = '\xa9'
  [53] = '\0'
  [54] = '\0'
  [55] = '\x7f'
  [56] = '\xa9'
  [57] = '\0'
  [58] = '\xf5'
  [59] = '<'
  [60] = '\x03'
}

This is the payload - again looks great, command 4 which is COMM_GET_VALUES and 55 bytes

Code:
(uint8_t [256]) payload = {
  [0] = '\x04'
  [1] = '\0'
  [2] = '\xec'
  [3] = '\0'
  [4] = '\xec'
  [5] = '\0'
  [6] = '\xec'
  [7] = '\0'
  [8] = '\xec'
  [9] = '\0'
  [10] = '\xed'
  [11] = '\0'
  [12] = '\xed'
  [13] = '\0'
  [14] = '\xed'
  [15] = '\xff'
  [16] = '\xff'
  [17] = '\xff'
  [18] = '\xfd'
  [19] = '\0'
  [20] = '\0'
  [21] = '\0'
  [22] = '\x01'
  [23] = '\x03'
  [24] = '\xb6'
  [25] = '\0'
  [26] = '\0'
  [27] = 'S'
  [28] = '\x96'
  [29] = '\0'
  [30] = '\xea'
  [31] = '\0'
  [32] = '\0'
  [33] = '\0'
  [34] = '/'
  [35] = '\0'
  [36] = '\0'
  [37] = '\0'
  [38] = '\0'
  [39] = '\0'
  [40] = '\0'
  [41] = '\x04'
  [42] = 'W'
  [43] = '\0'
  [44] = '\0'
  [45] = '\0'
  [46] = '\t'
  [47] = '\0'
  [48] = '\0'
  [49] = '\x7f'
  [50] = '\xa9'
  [51] = '\0'
  [52] = '\0'
  [53] = '\x7f'
  [54] = '\xa9'
  }

But when I unpack and grab the values out - it all seems wrong. These values are taken with the VESC on 6S, full throttle applied over PPM.

Code:
(bldcMeasure) values = {
  avgMotorCurrent = -17783250
  avgInputCurrent = 120.32
  dutyCycleNow = 0
  rpm = 4
  inpVoltage = 2227.19995
  ampHours = 0.230399996
  ampHoursCharged = 836.633605
  tachometer = 0
  tachometerAbs = 0
  fault_code = 11108096
}

I have mostly used the C code from RollingGecko https://github.com/RollingGecko/VescUartControl, but also tried Vedders header files and get the same results.

Not sure what the heck is wrong now! If the baud rate was wrong I wouldn't expect to see the message and payload packet looking so fine with the correct byte count and start/stop bits in place.

Any ideas anyone?
 
You seem to run an old VESC furmware, can you try with the latest one? Also, I would leave UART speed default to 115200.
 
erwincoumans said:
You seem to run an old VESC furmware, can you try with the latest one? Also, I would leave UART speed default to 115200.

Thanks for the tips. I have to run at 9600 because the Adafruit UART only runs at that speed.

I'm also stuck on Firmware 1.6 as updating via BLDC tool isn't working for me. I've tried OSX and Windows variants, and firmware 1.7 to 1.14, but none of them seem to stick.

BLDC reports that the FW upload works, but when I power cycle the VESC, it's still stuck on 1.6. Going to look for a stlink programmer, perhaps that will fix it?
 
benj said:
erwincoumans said:
You seem to run an old VESC furmware, can you try with the latest one? Also, I would leave UART speed default to 115200.

Thanks for the tips. I have to run at 9600 because the Adafruit UART only runs at that speed.

I'm also stuck on Firmware 1.6 as updating via BLDC tool isn't working for me. I've tried OSX and Windows variants, and firmware 1.7 to 1.14, but none of them seem to stick.

BLDC reports that the FW upload works, but when I power cycle the VESC, it's still stuck on 1.6. Going to look for a stlink programmer, perhaps that will fix it?

Get the stm discovery kit, it has an st-link onboard. It is cheap from Amazon, and you can use Vedders UART code on it.

The separate st-link v2 programmer never worked for me.
 
benj said:
erwincoumans said:
You seem to run an old VESC furmware, can you try with the latest one? Also, I would leave UART speed default to 115200.

Thanks for the tips. I have to run at 9600 because the Adafruit UART only runs at that speed.

I'm also stuck on Firmware 1.6 as updating via BLDC tool isn't working for me. I've tried OSX and Windows variants, and firmware 1.7 to 1.14, but none of them seem to stick.

BLDC reports that the FW upload works, but when I power cycle the VESC, it's still stuck on 1.6. Going to look for a stlink programmer, perhaps that will fix it?

This will happen if the VESC has no bootloader, so whoever supplied it probably forgot about the bootloader. It could also be because of the windows or osx versions of bldc tool since I only run linux on my computers and never tested those, but if everything else works the bootloader is the most likely problem. You can upload the bootloader with a swd programmer if you install the toolchain as I described in my post.

I had a quick look at the arduino api (which seems very limited regarding callbacks from interrupts), so I think I can have a look at making the uart example run on it. In general I don't like the arduino platform so much since it is designed in such a limiting way. No threads, no callbacks from interrupts (the serial callback is run from main), slow access to gpio pins etc. I get the feeling that arduino is not made for complex projects, but for blinking a few LEDs or printing a bit on the serial port the first time you touch a microcontroller. A few years ago I made many quite complex projects with AVR microcontrollers (the ones used on arduino) and I think arduino would mostly have been in the way.
 
Hi everyone,

I am searching for a way to connect a bluetooth remote (arduino remote) to the vesc. I have wired a bluetooth to the vesc rx->tx,tx->rx but beside that i dont know much how to deal with it.
For now, i just want to throttle and brake. I guess later on i will want to read data over bluetooth too but for now just basic commands.
Can anyone help?
Thank you
Cheers
 
Back
Top