Fardriver BLE Communication

not.py

🔌 New-ish
Joined
Feb 9, 2025
Messages
49
Location
United Kingdom, England
Welcome, I'm currently in the works of reversing Fardriver's BLE communication to make my own custom dashboard app.
Thought I should document it in case anyone in the future decides to try.

I'm a total newbie to all kinds of serial & bluetooth communication but I've been doing python for multiple years now.
Feel free to correct me on anything I say.

Also check out: Fardriver controller serial protocol reverse engineering if your interested in the serial communication.
Lots of helpful info in there regarding how data is sent as well.



Current findings:
Address 0xEE:
First nibble: Direction switch. 0 for forwards / 8 for reverse.
Second nibble: Mode switch. B for 1 / 3 for 2 / 7 for 3.
Fourth nibble: Breaking. F for break / D for normal.
Next 4 nibbles seem to count up as the wheel spins, maybe for the speedo?
Example: 09 1D 29 32 00 00 00 00 00 00 00 00


Address 0xE2:
Nibbles 12-15: RPM

These are all my findings from tonight, will be back with more soon.
 
Last edited:

Someone managed to connect all the important parameters to the ESP. I checked it and it works :) However, there are often problems with connecting the controller to the ESP32. It doesn't connect immediately, only after a while.
 
i try this, and my reading are all 0, the uuid are the same as in the github, using nrf connect. i'm sure its correct. i wonder whyy :(
I will send you my code that works in serial monitor and on ILI9341 and ESP32 wroom.
I'm still making a new layout using squareline studio but I'm waiting for my esp32 S3 N16R8 to arrive to test it.

 
Last edited:
I will send you my code that works in serial monitor and on ILI9341 and ESP32 wroom.
I'm still making a new layout using squareline studio but I'm waiting for my esp32 S3 N16R8 to arrive to test it.

oh wow thank you. i definitely will try thiss.
thank you. i'll get back to you ASAP. i'm still using small oled screen.. cheers..
 
Heyy goood news.. it workss.. ahahahah oh my.. THANK YOU SO MUCH! woohooo.. time to upgrade to lvgl..

And i wonder if you can sniff the jikong bms too.. i tried and it works. But in other valur its in correct.. i attach some picture my attempt to connect to jk bms.
 

Attachments

  • 20250926_203506.jpg
    20250926_203506.jpg
    1.4 MB · Views: 27
  • 20250926_201059.jpg
    20250926_201059.jpg
    1.7 MB · Views: 32
Are you referring to the handbrake signal? If so, could you share the code for this function? Thanks to gtp chat, I also decoded the reading for DNR gears:

In fardriver data :
C:
int dnrMode = 0; // 0=Neutral, 1=Drive, 2=Reverse

In proces packet :
C:
// ---- DNR detection ----
  uint8_t dnrByte = pData[0];
  uint8_t newDnr = dnrByte & 0x03;  // 0=N,1=D,2=R (bitowo z testów)
  static uint8_t lastDnr = 255;

  if (newDnr != lastDnr) {
    lastDnr = newDnr;
    controllerData.dnrMode = newDnr;

    Serial.print("🕹️ Tryb DNR zmieniony: ");
    switch (newDnr) {
      case 0:
        Serial.println("NEUTRAL");
        break;
      case 1:
        Serial.println("DRIVE");
        break;
      case 2:
        Serial.println("REVERSE");
        break;
      default:
        Serial.println("Nieznany");
        break;
    }
  }
  break;
}
 
Last edited:
Are you referring to the handbrake signal? If so, could you share the code for this function? Thanks to gtp chat, I also decoded the reading for DNR gears:

In fardriver data :
C:
int dnrMode = 0; // 0=Neutral, 1=Drive, 2=Reverse

In proces packet :
C:
// ---- DNR detection ----
  uint8_t dnrByte = pData[0];
  uint8_t newDnr = dnrByte & 0x03;  // 0=N,1=D,2=R (bitowo z testów)
  static uint8_t lastDnr = 255;

  if (newDnr != lastDnr) {
    lastDnr = newDnr;
    controllerData.dnrMode = newDnr;

    Serial.print("🕹️ Tryb DNR zmieniony: ");
    switch (newDnr) {
      case 0:
        Serial.println("NEUTRAL");
        break;
      case 1:
        Serial.println("DRIVE");
        break;
      case 2:
        Serial.println("REVERSE");
        break;
      default:
        Serial.println("Nieznany");
        break;
    }
  }
  break;
}
Wow, thats a new found great. Let me try that. Oh thr motor temp is zero from your code, maybe a wrong byte.

What i mean by brake signal when you pressed the brake the motor wont run.

BRAKE SIGNAL:
Packet: 0xE2 (Address 0)
Byte: 3
Bit: 7

I found this byte for the brake.

Now, for the soc reading i think i beed to connect to bms and read it from there. Already done but some false reading, need to find the right byte.
 
Everything works fine for me :) I wonder if there are any other parameters that would be useful to decode, e.g. throttle voltage, phase current.
 
Hi guys and good job on both implementations. I too have been doing something similar for more than a year now: 1767004027632.png
I'm using a esp32 to make communication to my factory supersoco display and also send stats to my secondary screen. I'm also gathering data via ble from foth my nd72680 and my JK bms. What I am missing though and I didn't get around to debugging on the bike is the cruise control bit. It's probably hidden somewhere in frame types EE, E8 or E2. Did you find it by any chance? Thanks.
 
im making a easy to use fardriver and even do a tunning and your bms, but you need a ble module for your controler to works perfectly,

ypu can also doing navigation with it

here you go

 

Attachments

  • 2ABEDA9F-CFFA-4258-BA80-F0C448CC83C0.png
    2ABEDA9F-CFFA-4258-BA80-F0C448CC83C0.png
    1.5 MB · Views: 2
  • IMG_9985.PNG
    IMG_9985.PNG
    279.1 KB · Views: 3
  • 334A079B-70AD-4D79-9052-27CF44BA01EF.png
    334A079B-70AD-4D79-9052-27CF44BA01EF.png
    1.5 MB · Views: 3
  • a9662428-679f-4c70-8d84-8409b362780a.jpg
    a9662428-679f-4c70-8d84-8409b362780a.jpg
    78.3 KB · Views: 4
  • 17ae3776-6017-4176-bf72-10f1f0ea882d.jpg
    17ae3776-6017-4176-bf72-10f1f0ea882d.jpg
    192.3 KB · Views: 1
  • a40157b4-47c4-4f11-ba2c-9848e896e87e.jpg
    a40157b4-47c4-4f11-ba2c-9848e896e87e.jpg
    93.7 KB · Views: 2
  • IMG_0219.PNG
    IMG_0219.PNG
    279.6 KB · Views: 1
Back
Top