My build is stalled because I’m in over my head with trying to code an ESP32 (tinypico) to interact with my VESC and DieBieMS over CAN bus to drive some lighting.
The good news is I’ve got the hardware together and working enough to read the CAN communication happening on the system, but I just don’t know where to go from here.
I need help and and willing to pay a good market rate for it. I figured I’d ask here first before I went onto some of the freelance websites.
I don’t have time to pickup freelance work these days, but if you’re still willing to take a crack at it yourself, I recommend checking out our Robogotchi Firmware repos as we deal with parsing the VESC protocol and making can-forward requests.
You mean for the lighting system? TJA1050 CAN transceiver, two step down buck converters, one 60v to 12v, and one 12v to 5v. The brake light is going to be N type PWM controlled, it’s a single color 12v strip. The running lights are 5v RGBW SK6812, two strips, both driven by its own data line, 20 LEDs per strip. Everything taps into the DBMS’s 2nd CAN port.
Why do you step down the 12v to 5v instead of stepping down the 60v again? Im not saying its wrong Im just curious as I imagine the power loss due inefficiency would add together. Is it because the 12v to 5v buck converter is much smaller then the one that can step down 60v to 12v?
I get that part, he needs 12V for the leds and the 5v is I for the tinypico I guess. I’m a bit confused here though, as the esp32 is 3.3v chip so probably he is using the onboard regulator to step it down third time.
I was just wondering why the double(triple) step down, although I dont know if it really matter efficiency wise or the loss is neglectable.
Sorry for the derail, im stopping it and starting to look into how efficient these converters are
It will be a slow project for me since I won’t be riding until spring. I would love the support! I can keep a steady support of beers to your door round the clock haha.
Also I have a bunch of TJA1050’s I’ll mail you one for free, DM me your address if you’d like.
The single color brake light strip is the 12v row true. The runner lights are 5v
For added measure, I think at least I’ve found the right door to knock on to figure this out.
If you’re connecting directly through UART there is a PPM state comm request called → ‘COMM_GET_DECODED_PPM’ and I’m 90% this is what Metr and others use to track throttle position.
And I believe the implementation for getting that info through CAN looks something like this from the rESCue repo. Though rESCue currently uses a mix of ERPM inputs as I understand it to determine whether the brake light should be one. As I understand it though this won’t result in brake lighting unless there is negative current. Meaning no light on during motion free sitting at a stop light etc.
Hey guys, I’m slowly trying to work through this as best I can. I got a lot of support from various people that reached out to me or vice versa, to take this project on myself and ask questions as I go so that I can learn from it. I’m a bit stuck at the moment.
I believe I am getting a VESC response now with PPM information, though I am having trouble understanding the output format. My short Arduino code is below.
My primary question is, have I gone about this correctly to read the PPM info, is the output as expected, and can anyone advise of the parsing format or where I can dig to find it?
It looks like not all CAN frames are captured. Things are happening pretty fast and on high BAUD rates it gets impossible to capture and print all frames with printf.
For example on the screenshot you attached, first line is “New extended frame from 0x00000511…”. The data you are interested in starts after 0x1F (COMM_GET_DECODED_PPM). On the screenshot you have 6 bytes of data after 0x1F.
What it does is writes 0x1F into the buffer and then it writes 8 bytes of data. First 4 bytes are ppm_decoded_level and then 4 bytes which are last_pulse_len. I don’t remember why, but trust me you want last 4 bytes (last_pulse_len)
When you get those 4 bytes, you need to put them into int32 and then divide by 1000000 to get ms value, like this one:
But first you need to print missing frames. Lowering CAN baud rate might help. Try CAN_SPEED_100KBPS instead of CAN_SPEED_500KBPS. Don’t forget to change CAN BAUD rate on VESC as well.
What you should get is 3 frames right after each other.
That’s it!! It’s working! Hats off to you Roman! .
I adjusted the baud rate down to 125kbps in my arduino sketch, the VESC, and the DieBieMS. Unfortunately the DieBieMS stopped communicating when I did this. I think I’ll write Danny @JTAG about why that might be. But I cut the DBMS out of the CAN network and talked directly ESP32 to VESC I’ve now got two FILL_RX_BUFFERs frames and a PROCESS_RX_BUFFER frame upon each request.
I’m not sure that I’ll need the (last_pulse_len) value for my purposes? And I don’t think I understand what its doing in the first place.
The output from the four bytes after the COMM_GET_DECODED_PPM once converted to int32 and divided by 1000000 represent the throttle position -1 to +1 which is exactly what I had hoped for. VESC is doing the work to report % from the calibrated position in VESC Tool.
Roman thanks a bunch for the direction. I feel I cleared the first of a few hurdles finally. Off for a beer in celebration then back to it in trying to manipulate the data outside of the serial print. And also trying to figure out where these ghost frames 0x000005AE are coming from.