ESP32/ESP32s3 DIY build progress

making decent headway on the DIY route. i have a few PIDs decoded for G8X m3/m4

50hz RPM
25hz GEAR

RPM and PEDAL come in at 100hz but the Bluetooth LE drivers on all the Arduino devices are terrible. nRF52 or ESP32!

My basic design is an Adafruit Feather ESP32s3 (or Adafruit Huzzah32 ESP32) with Feather Wing CAN bus transceiver (ESP32 has a SJA1000-like CAN controller built into the chip) The ESP32s3 is newer chip with Bluetooth 5.0, but drivers are so terrible, there is not real gains, I just prefer the USB-C vs USB micro B.

I started out with a nRF52 chip, but its performance was maybe 100 frames / second total. The ESP32s3 I can get about 350 frames / second before the Bluetooth stack starts dying.

I have developed my own CAN bus driver, so i can take lots of shortcuts since i only care about reading data. I can get over 2500 frames / second (the max my car broadcasts over the PT-CAN bus) without issue.

The ESP32 is dual-core, so i have CAN bus on one core, Bluetooth on the other, use a FreeRTOS Queue to pass data from the CAN bus interrupt handler to the bluetooth core and send that over Bluetooth LE to racechrono.

RaceChrono screenshot:
ESP32 build:

Next steps are to see if i can write my own BLE slimmed down driver with the ESP32 SDK and get past that 350 frames / second mark.

It would be nice to have a WiFi interface to RaceChrono for DIY devices, as that I feel is much more stable / performance drivers in the arduino world, vs trying to use BLE for performance path. BLE is fine for basic communication, but none of the Arduino drivers are hardened for performance on the BLE side.


  • edited September 2022
    one other idea i had, since i have so many free CPU cycles on the ESP32 side, was to aggregate PIDs into one BLE message. right now all data is basically 1 or 2 bytes, but the CAN frame is 8 bytes. i could aggregate say all the 50hz messages into one pid, 25hz into another, etc, then use the same PID and different offsets on the RaceChrono iOS/Android side, reducing the BLE messages by potentially 4x, but adding some latency with the aggregation step, but at 25/50/100 hz, it may not matter...

    could also just reduce the BLE payload to PID + value, instead of sending all the extra CAN data so each BLE message would be 4 bytes for PID and 1-2 bytes for data. that would reduce the data payload in each BLE from 12 bytes total to 5-6 bytes total
  • Nice project!
  • edited October 2022

    email me at if you are interested in trying out my integrated ESP32-S3 CAN board with built in 12V power support from car/bike
  • @MagnusThome sorry, i don't have any 12v available to me easily from where i need to hook into the CANbus and a small 600 mAh battery lasts several days, so plenty of power for a single track day, so i dont really have a good way to use and/or test your setup.
  • Sorry about late reply. dirtyfreebooter wrote: "It would be nice to have a WiFi interface to RaceChrono for DIY devices, as that I feel is much more stable / performance drivers..."

    A WiFi interface is available, and I have been using it for a year or so -- streaming $RC3 and GPS data via an old ESP8266 serial/WiFi interface at insane speeds. It is definitely faster and more stable than the Bluetooth SPP I used before.
  • @DrMotor is there any API documentation or example github repo for setting up the WiFi connection between device and phone?
  • edited April 17
    @dirtyfreebooter There's no setup as such. RaceChrono will ask you IP address and TCP port where to connect, when you configure TCP/IP DIY device. You can connect the Wi-Fi from phone's Wi-Fi settings as usual.
  • edited April 20
    Like AOL said, but more details: You can set up an ESP8266 as WiFi access point so your phone can connect to it. I do it like this on a BlackPill board:

    > send_string( "AT+CWSAP_CUR=\"\",\"\",5,3\r\n" );
    > delay(1000);
    > send_string( "ATE0\r\n" ); // Echo off
    > send_string( "AT+UART_CUR=1000000,8,1,0,0\r\n" ); // 1Mbps, 8 bits, 1 stop bit, no parity, flow control
    > LL_USART_Disable( RC_dev ); // disable to change baud rate
    > LL_USART_SetBaudRate( RC_dev, 96000000U, LL_USART_OVERSAMPLING_16, 1000000 );
    > LL_USART_Enable( RC_dev );
    > send_string( "AT\r\n");
    > send_string( "AT+GMR\r\n");
    > send_string( "AT+CWMODE_CUR=2\r\n"); // 2 = softAP mode (allow phone to connect via WiFi)
    > send_string( "AT+CIPMODE=0\r\n" ); // Prepare normal mode
    > send_string( "AT+CIFSR\r\n" ); // Query IP address
    > send_string( "AT+CIPMUX=1\r\n"); // Enable multiple connections.
    > send_string( "AT+CIPSERVER=1\r\n"); // Create a TCP server. Default port = 333
    > delay(1000); // wait for connection

    The serial port "RC_dev" is connected to the ESP8266 . You might need to insert some delays to let the ESP process the AT-commands -- check via a logic probe! This function sends data to RaceChrono:

    > void send_AT(char* str) {
    > size_t len = strlen(str);
    > if ( len > 0 )
    > {
    > char at_com[]="AT+CIPSEND=0,xxx\r\n";
    > sprintf(&at_com[13],"%03u\r\n",len);
    > send_string(at_com); // Book the transmission and length
    > delay(1); // wait for ">" ToDo: Read and check the response
    > send_string(str);
    > }

    > void send_string(char* str) {
    > size_t len = strlen(str);
    > for (; len > 0; --len, ++str) {
    > LL_USART_TransmitData8( RC_dev, *str );
    > while (!LL_USART_IsActiveFlag_TXE(RC_dev)) {} // Blocking mode
    > }
    > *(str-len)=0; // clear the buffer, strlen=0

  • oh but i see you can't add a WiFi DIY device as a CAN bus device. Or at least I was unable to figure that out with v8.0.7 on iOS. BLE with ESP32-S3 on Arduino Release v2.0.10 based on ESP-IDF v4.4.5 .. the BLE stack is certainly the bottleneck in terms of throughput. Being able to send over WiFi would be an interesting test.

    since all CAN bus packets would fit in UDP packet, it would be interesting to test WiFi + UDP, and interesting to pack more than 1 CAN bus data frame into a UDP packet as well, but the dual core ESP32 with CAN bus interrupts on one core and networking on another core seem to do well enough.
Sign In or Register to comment.