My first build: CAN-Bus and GPS through Bluetooth LE

edited May 2019 in DIY builds
I've just released my first build in open source. It's reference device to showcase the new Bluetooth LE "do it yourself" APIs for GPS and CAN-Bus data in RaceChrono Pro v6.0 (beta). Let me know what you think.


  • I will follow this post, it's interesing for programmable ECU
  • Great work and good documentation!
    Thumbs up :)
  • Hello, I have a DTA ECU with CAN-bus, I try to understand your code => you make the choice of the IDs readed directly in the app ?
    I would like to build it this winter.
  • I'm not sure if I understand the question. The app writes to the UUID 2 to create a filter. This selects which packet IDs are read and which are just dropped.
  • Ok, I understand now. In the app, we see the CAN-IDs available and the filters are sent through the BLE. Am I right ?
    Your code is very nice but complicated for me.
    I read some documentations on the BLE Characteristics but I have also to understand the CAN Bus documentation.
    Somes years ago, I read the Serial Stream on a old ECU with an Arduino, it was easier. :)
    Thanks for your explanations, I will order the parts and try it.
  • Hello,
    I received my parts and I look at more your code.
    The Arduino IDE doesn't want to compile because the Adafruit's library has been modify.
    I made two corrections but I can't test it for the moment.
    void canBusFilterWriteCallback(BLECharacteristic& chr, uint8_t* data, uint16_t len, uint16_t offset) {
    void canBusFilterWriteCallback(uint16_t offset,BLECharacteristic* chr, uint8_t* data, uint16_t len ) {

    void bluetoothStart() {
    uint8_t mac[6] = { 0, 0, 0, 0, 0, 0 };
    void bluetoothStart() {
    uint8_t mac[6] = { 0, 0, 0, 0, 0, 0 };

    It compile now, I don't use the GPS'code.
    If you can look at and say me if I am in the good way.

    Best Regards
  • Probably just different version of the Adafruit libraries. I believe your change mirrors the functionality exactly. I will revisit the project at some point.
  • I will try on my car ASAP and keep you informed.
  • Hi everyone!

    I would like to briefly introduce my project to you. I have an old Kawasaki ZX6R (2002, carburetor) which has neither OBD-II nor CAN-Bus. Instead I collect my data using some sensors and an Arduino with Bluetooth LE. I have a 9-DOF IMU to read accelerations and calculate lean angle. By counting pulses (frequency measurement) I get the pretended speedometer value and RPM and calculate the gear form that. There´s an external GPS board connected to the Arduino, so I know the real speed and can send a corrected pulse signal to the speedometer. The throttle grip position can be determined by measuring the voltage of throttle valve sensor and so on... quite a bit of stuff already.

    Thanks to the documentation on GitHub from the first post, I was able to get all the Bluetooth LE stuff to work already! (I haven't tested GPS yet).

    So far I have 3 questions/remarks:

    1. OBD-II channels vs. CAN-Bus channels
    I see in OBD-II channels I can define a postfix, so for example I can separate suspension travel front and rear.
    Is that option missing for CAN-Bus channels? I couldn´t figure out how this can be done.

    2. Combined acceleration
    I know the combined acceleration is usually calculated by RaceChrono from the GPS data. As I can directly measure all accelerations very fast and reliable, I want to use it rather than GPS data. I can send longitudinal and lateral acceleration in separate channels, but how to combine them? There is an entry "combined acceleration" in the list of channels that can be created, but how is it meant to use?

    3. Bluetooth LE payload
    To increase the data throughput, I packed several data values under the same PID. For example Gear and RPM can be packed in only 2 bytes (3 bit for Gear, 13 bit for RPM/2). Throttle and Brake position need only one byte each and so on. You can put a lot of different data into a single 8-byte parameter. This way I achieve much higher update rate because I don´t have to send the BLE characteristic everytime for each single value.
    Actually a BLE characteristic can transfer 20 byte, 4 bytes are used for the PID, so 16 bytes of payload would be possible. Unfortunately only 8 bytes can be accessed in the channel. Is it worth considering increasing the bytes per chanel?

    Thanks for your great work and documentation!

    Best regards
  • Hi @GiuseppeBinomi

    Sounds like a great project! I've been thinking adding a dedicated IMU input API, but it will work through CAN-Bus API too :)

    1. I will check that there's no bug related to this. It should work just same as OBD-II...

    2. Combined acceleration is basically sqrt(pow(lateralAcc) + pow(longitudinalAcc)). You can easily add that channel, if you have both accelerations available.

    3. Yep, I don't see a reason why it could not be variable packet length. I will experiment with it, and if it works will roll out to next major version.

  • Thanks for your fast reply!

    2. Ah now I see the combined acc channel is a scalar value. I misunderstood that.
    I thought about the video overlay for combined acceleration which is a 2-D chart.
    I can show longitudinal acc and lateral acc channel in two charts, then the red dot is bouncing up and down in one chart and bouncing side to side in the other chart.

    When I add the combined acc channel from GPS to the overlay this is obviously a 2-D value.

    So my problem is, I have 2 scalar values (longitudinal and lateral acc) from CAN-Bus channels and I want them to show up combined in the 2-D chart. I can calculate the vector length like you suggested, but then it is still a scalar (1-D value) value, not showing the direction of the force.

    Best regards
  • aolaol
    edited 3:24PM
    1. Looks like a bug, a wrong field is showing up when you press "show more"

    2. That gauge uses three different channels. The number is "combined" and y-axis is "longitudinal" and x-axis is "lateral". What you need to do is to calculate lateral and longitudinal accelerations from your 3D IMU. For a car it would be easy, just point your sensor so that one axis is aligned to lateral and one is longitudinal. For a motorbike longitudinal would work same way, but to get lateral acceleration, you need to rotate the 3D matrix according to the lean angle...

    PS. Both 1. and 3. will be addressed in the next release, minor or major which ever comes first.
Sign In or Register to comment.