OBDII simulation via BLE


I'm building data streaming from Vems ECU to RaceChrono and I'd like to ask for advice.
The ecu has no can/obd but has AIM stream, so the first idea was to catch the stream, parse, send it as fake CAN stream via BLE.
The most satisfying is I've bought seeed XIAO nRF52840 board and done this in one night, that's was not so tricky:
00001ff8-0000-1000-8000-00805f9b34fb sevice
two characteristics:
00000001-0000-1000-8000-00805f9b34fb BLERead | BLENotify
00000002-0000-1000-8000-00805f9b34fb BLEWrite

Connected this as BLE DIY
And this started working, you may see few seconds of my screen capture

My special thanks for everyone who shared their experiments, I'll do the same after some cleanup.

Maybe it was a good moment to say myself "well done" and stop but I decided to try to do some extra steps.
Doing like I've done I may share any data grouped into any possible fake can packets which need to be decoded on the racechrono side (which is also not a big deal)
So I decided to try to simulate some OBD BLE adapter and send data per request. In this way I understand that requesting individual pids are more time costly, at the same time configuration on the racechrono side may be much easier, just add pids.

So, I taken a look at some $5 chinese BLE ELM327 which exposes
0000fff0-0000-1000-8000-00805f9b34fb Service with the following characteristics
0000fff1-0000-1000-8000-00805f9b34fb, BLERead | BLENotify
0000fff2-0000-1000-8000-00805f9b34fb BLEWrite
I done the same and expected I'll use read/write characteristics as TX/RX of ELM serial protocol

First run was quite promising, I saw in terminal that my board receives ATZ command
I see also 0x13 every few seconds sent by racechrono and ... nothing more.

I tried to send back different responses, different line endings, nothing helped.

May be you can give me an idea what am I missing with the OBD BLE simulation?


  • Yeah, it should work as "Carista" configuration option, when using those UUIDs. RaceChrono sends 0x13 when it has not received what it expected to receive, which is a prompt. It will send it again until it sees a proper prompt. Please follow what happens when you send ATZ to the real OBD-II reader.
  • Since I did a similar solution (Use KWP2000 messages via K-Line and convert to OBD2), I have added all needed AT commands and responses, to be as compatible to all OBD2 / ELM327 Apps possible.
    Maybe this helps:
    There is a list below the code.

    Within the code, the AtCommands.ino processed the requests. And sends due to the response type
    [OK] + CarriageReturn (0x0D) + Prompt (0x3E)
    where OK is mostly needed if no other result will be responded.
  • aol_of_RaceChrono, thank you for the response, I'll try to connect it as Carista and observe what's going.

    And one more question, can you suggest any tool which is comfortable to monitor multiple characteristics?

  • edited April 2023
    @F29R just a quick update, the $5 chinese reader's UUID's match Carista. The ones you configured earlier match the RaceChrono DIY device's BLE configuration, which is not OBD-II, but a completely custom protocol ...
  • @TriB many thanks
    May be 0x3e does the trick, I'll try

  • @aol_of_RaceChrono
    Yes, that's it
    for DIY uuid binary data to be sent (4bytes id + variable length data), that's already working good, your and timurrrr examples are great to be followed

    for OBD uuid (carista-like) ascii terminal protocol to be used, I'll try to do it like @TriB described

  • edited April 2023
    your message was very helpful, 0x3E was the key of my problem, communication RaceChrono <--> fake obd estabilished

    Going forward!
  • @TriB, @aol_of_RaceChrono
    Many thanks for your advices, them made this working

    Next step is to test it in the car.
  • Very good! The 0x3E character is the prompt in ELM327 protocol.
Sign In or Register to comment.