ElectricMotorcycleForum.com

Makes And Models => Energica => Topic started by: Woale on July 24, 2018, 02:27:25 PM

Title: EVA CANbus or Bluetooth notification values
Post by: Woale on July 24, 2018, 02:27:25 PM
Hi folks,

in an attempt to setup a Raspberry Pi Zero for on-board camera and data logging, though not sure if energica pushed the secure CAN concept (http://www.tapps-project.eu/?p=665) on the production models, does anyone know where a CANbus connector/port is located on the EVA model, or anyone been able log data from the CANbus ?

Cheers,
Woale

(edited post to update subject)
Title: Re: EVA CANbus
Post by: greentorque79 on July 26, 2018, 06:55:27 PM
That sounds interesting! 👍🏻 Would be great to know more if this is possible and what camera you would use also and how to access the raspberry pie.

Title: Re: EVA CANbus or Bluetooth notification values
Post by: Woale on October 02, 2018, 08:44:22 PM
Okay, I've abandoned a "wired" solution for data logging... if anyone is interested, the OBD port is located underneath the lefthand tank cover.

Now, for a possible "wireless" data logging solution, from a Raspberry Pi Zero, connection can be setup with my EVA over Bluetooth Low Energy.
Similar to how the 'My Energica' mobile app communicates, once connected, it's fairly easy to subscribe to notifications from 2 distinct proprietary Characteristics.
Up to 15 values per second are obtained from 1 Characteristic, which I hope at least contain speed, rpm, power, torque, range, soc, ... a few samples (hexadecimal);
1A-01-F9-FF-BB-11-00-01
1A-FE-07-24-11-9B-29-51
00-FF-E6-28-E4-3F-00-00
01-FF-01-01-02-00-00-00
1A-00-00-00-74-6C-C5-0C
1A-01-F9-FF-BB-11-00-01
1A-FE-03-28-11-9B-29-51
04-00-67-0C-00-00-00-00
04-FE-91-36-00-00-00-00
02-00-62-3C-3E-55-00-19
00-FF-6D-2C-E4-3F-00-00
02-01-83-00-00-00-00-00
02-02-E8-FD-88-0C-FE-FF
01-FF-01-01-02-00-00-00


The second Characteristic, I presume is related to the Trip meter, as it can not only be read, but also written to.

Has anyone figured out how to make sense of those values ?
Title: Re: EVA CANbus or Bluetooth notification values
Post by: togo on February 15, 2020, 06:21:36 AM
> Okay, I've abandoned a "wired" solution for data logging... ...

Why?  Technical difficulties?

Title: Re: EVA CANbus or Bluetooth notification values
Post by: Hans2183 on February 22, 2021, 09:29:11 PM
Anyone has decoded those canbus messages for Energica already? If someone is willing to share (PM) me a longer sample I can give it a try. Should contain some common words we can try.
Title: Re: EVA CANbus or Bluetooth notification values
Post by: PWM on February 23, 2021, 01:18:19 AM
Since we're on the subject, most within the community are less inclined to code up a PI or Arduino for can bus logging / sniffing device.

This seems like a good alternative to hobby electronics being considered...can anyone comment please?
https://www.csselectronics.com/screen/product/can-logger-sd-canedge1/language/en (https://www.csselectronics.com/screen/product/can-logger-sd-canedge1/language/en)

Not sure if the following would eliminate need for Wireshark tool...?
https://www.csselectronics.com/screen/product/obd2-dbc-file (https://www.csselectronics.com/screen/product/obd2-dbc-file)

Don't mean to derail OP's thread, but augment discussions for the less knowledgeable like myself that are interested in the end application.
Title: Re: EVA CANbus or Bluetooth notification values
Post by: Hans2183 on February 23, 2021, 02:26:53 AM
This might help decoding BLE communication with the bike

Code: [Select]
public static final UUID EnergicaServiceUUID = UUID.fromString("14839AC5-7D7F-415D-9A43-167340CF233A");
these are the ones (ab)used by energica

Code: [Select]
public class BleDefinedUUIDs {

    public static class Characteristic {
        public static final UUID APPEARANCE = UUID.fromString("00002a01-0000-1000-8000-00805f9b34fb");
        public static final UUID BATTERY_LEVEL = UUID.fromString("00002a19-0000-1000-8000-00805f9b34fb");
        public static final UUID BODY_SENSOR_LOCATION = UUID.fromString("00002a38-0000-1000-8000-00805f9b34fb");
        public static final UUID ENERGICA_NOTIFY = UUID.fromString("0734594B-A8E8-4B1B-A6B2-CD5243059A58");
        public static final UUID ENERGICA_WRITE = UUID.fromString("8B00ACE8-EB0C-49B1-BBEA-9AEE0A26E1A4");
        public static final UUID FIRMWARE_REVISION_STRING = UUID.fromString("00002a26-0000-1000-8000-00805f9b34fb");
        public static final UUID HEART_RATE_MEASUREMENT = UUID.fromString("00002a37-0000-1000-8000-00805f9b34fb");
        public static final UUID MANUFACTURER_STRING = UUID.fromString("00002a29-0000-1000-8000-00805f9b34fb");
        public static final UUID MODEL_NUMBER_STRING = UUID.fromString("00002a24-0000-1000-8000-00805f9b34fb");
    }

Code: [Select]
public class BleNamesResolver {
    private static SparseArray<String> mAppearance = new SparseArray<>();
    private static HashMap<String, String> mCharacteristics = new HashMap<>();
    private static SparseArray<String> mHeartRateSensorLocation = new SparseArray<>();
    private static HashMap<String, String> mServices = new HashMap<>();
    private static SparseArray<String> mValueFormats = new SparseArray<>();

    static {
        mServices.put("00001811-0000-1000-8000-00805f9b34fb", "Alert Notification Service");
        mServices.put("0000180f-0000-1000-8000-00805f9b34fb", "Battery Service");
        mServices.put("00001810-0000-1000-8000-00805f9b34fb", "Blood Pressure");
        mServices.put("00001805-0000-1000-8000-00805f9b34fb", "Current Time Service");
        mServices.put("00001818-0000-1000-8000-00805f9b34fb", "Cycling Power");
        mServices.put("00001816-0000-1000-8000-00805f9b34fb", "Cycling Speed and Cadence");
        mServices.put("0000180a-0000-1000-8000-00805f9b34fb", "Device Information");
        mServices.put("00001800-0000-1000-8000-00805f9b34fb", "Generic Access");
        mServices.put("00001801-0000-1000-8000-00805f9b34fb", "Generic Attribute");
        mServices.put("00001808-0000-1000-8000-00805f9b34fb", "Glucose");
        mServices.put("00001809-0000-1000-8000-00805f9b34fb", "Health Thermometer");
        mServices.put("0000180d-0000-1000-8000-00805f9b34fb", "Heart Rate");
        mServices.put("00001812-0000-1000-8000-00805f9b34fb", "Human Interface Device");
        mServices.put("00001802-0000-1000-8000-00805f9b34fb", "Immediate Alert");
        mServices.put("00001803-0000-1000-8000-00805f9b34fb", "Link Loss");
        mServices.put("00001819-0000-1000-8000-00805f9b34fb", "Location and Navigation");
        mServices.put("00001807-0000-1000-8000-00805f9b34fb", "Next DST Change Service");
        mServices.put("0000180e-0000-1000-8000-00805f9b34fb", "Phone Alert Status Service");
        mServices.put("00001806-0000-1000-8000-00805f9b34fb", "Reference Time Update Service");
        mServices.put("00001814-0000-1000-8000-00805f9b34fb", "Running Speed and Cadence");
        mServices.put("00001813-0000-1000-8000-00805f9b34fb", "Scan Parameters");
        mServices.put("00001804-0000-1000-8000-00805f9b34fb", "Tx Power");
        mCharacteristics.put("00002a43-0000-1000-8000-00805f9b34fb", "Alert Category ID");
        mCharacteristics.put("00002a42-0000-1000-8000-00805f9b34fb", "Alert Category ID Bit Mask");
        mCharacteristics.put("00002a06-0000-1000-8000-00805f9b34fb", "Alert Level");
        mCharacteristics.put("00002a44-0000-1000-8000-00805f9b34fb", "Alert Notification Control Point");
        mCharacteristics.put("00002a3f-0000-1000-8000-00805f9b34fb", "Alert Status");
        mCharacteristics.put("00002a01-0000-1000-8000-00805f9b34fb", "Appearance");
        mCharacteristics.put("00002a19-0000-1000-8000-00805f9b34fb", "Battery Level");
        mCharacteristics.put("00002a49-0000-1000-8000-00805f9b34fb", "Blood Pressure Feature");
        mCharacteristics.put("00002a35-0000-1000-8000-00805f9b34fb", "Blood Pressure Measurement");
        mCharacteristics.put("00002a38-0000-1000-8000-00805f9b34fb", "Body Sensor Location");
        mCharacteristics.put("00002a22-0000-1000-8000-00805f9b34fb", "Boot Keyboard Input Report");
        mCharacteristics.put("00002a32-0000-1000-8000-00805f9b34fb", "Boot Keyboard Output Report");
        mCharacteristics.put("00002a33-0000-1000-8000-00805f9b34fb", "Boot Mouse Input Report");
        mCharacteristics.put("00002a5c-0000-1000-8000-00805f9b34fb", "CSC Feature");
        mCharacteristics.put("00002a5b-0000-1000-8000-00805f9b34fb", "CSC Measurement");
        mCharacteristics.put("00002a2b-0000-1000-8000-00805f9b34fb", "Current Time");
        mCharacteristics.put("00002a66-0000-1000-8000-00805f9b34fb", "Cycling Power Control Point");
        mCharacteristics.put("00002a65-0000-1000-8000-00805f9b34fb", "Cycling Power Feature");
        mCharacteristics.put("00002a63-0000-1000-8000-00805f9b34fb", "Cycling Power Measurement");
        mCharacteristics.put("00002a64-0000-1000-8000-00805f9b34fb", "Cycling Power Vector");
        mCharacteristics.put("00002a08-0000-1000-8000-00805f9b34fb", "Date Time");
        mCharacteristics.put("00002a0a-0000-1000-8000-00805f9b34fb", "Day Date Time");
        mCharacteristics.put("00002a09-0000-1000-8000-00805f9b34fb", "Day of Week");
        mCharacteristics.put("00002a00-0000-1000-8000-00805f9b34fb", "Device Name");
        mCharacteristics.put("00002a0d-0000-1000-8000-00805f9b34fb", "DST Offset");
        mCharacteristics.put("00002a0c-0000-1000-8000-00805f9b34fb", "Exact Time 256");
        mCharacteristics.put("00002a26-0000-1000-8000-00805f9b34fb", "Firmware Revision String");
        mCharacteristics.put("00002a51-0000-1000-8000-00805f9b34fb", "Glucose Feature");
        mCharacteristics.put("00002a18-0000-1000-8000-00805f9b34fb", "Glucose Measurement");
        mCharacteristics.put("00002a34-0000-1000-8000-00805f9b34fb", "Glucose Measurement Context");
        mCharacteristics.put("00002a27-0000-1000-8000-00805f9b34fb", "Hardware Revision String");
        mCharacteristics.put("00002a39-0000-1000-8000-00805f9b34fb", "Heart Rate Control Point");
        mCharacteristics.put("00002a37-0000-1000-8000-00805f9b34fb", "Heart Rate Measurement");
        mCharacteristics.put("00002a4c-0000-1000-8000-00805f9b34fb", "HID Control Point");
        mCharacteristics.put("00002a4a-0000-1000-8000-00805f9b34fb", "HID Information");
        mCharacteristics.put("00002a2a-0000-1000-8000-00805f9b34fb", "IEEE 11073-20601 Regulatory Certification Data List");
        mCharacteristics.put("00002a36-0000-1000-8000-00805f9b34fb", "Intermediate Cuff Pressure");
        mCharacteristics.put("00002a1e-0000-1000-8000-00805f9b34fb", "Intermediate Temperature");
        mCharacteristics.put("00002a6b-0000-1000-8000-00805f9b34fb", "LN Control Point");
        mCharacteristics.put("00002a6a-0000-1000-8000-00805f9b34fb", "LN Feature");
        mCharacteristics.put("00002a0f-0000-1000-8000-00805f9b34fb", "Local Time Information");
        mCharacteristics.put("00002a67-0000-1000-8000-00805f9b34fb", "Location and Speed");
        mCharacteristics.put("00002a29-0000-1000-8000-00805f9b34fb", "Manufacturer Name String");
        mCharacteristics.put("00002a21-0000-1000-8000-00805f9b34fb", "Measurement Interval");
        mCharacteristics.put("00002a24-0000-1000-8000-00805f9b34fb", "Model Number String");
        mCharacteristics.put("00002a68-0000-1000-8000-00805f9b34fb", "Navigation");
        mCharacteristics.put("00002a46-0000-1000-8000-00805f9b34fb", "New Alert");
        mCharacteristics.put("00002a04-0000-1000-8000-00805f9b34fb", "Peripheral Preferred Connection Parameters");
        mCharacteristics.put("00002a02-0000-1000-8000-00805f9b34fb", "Peripheral Privacy Flag");
        mCharacteristics.put("00002a50-0000-1000-8000-00805f9b34fb", "PnP ID");
        mCharacteristics.put("00002a69-0000-1000-8000-00805f9b34fb", "Position Quality");
        mCharacteristics.put("00002a4e-0000-1000-8000-00805f9b34fb", "Protocol Mode");
        mCharacteristics.put("00002a03-0000-1000-8000-00805f9b34fb", "Reconnection Address");
        mCharacteristics.put("00002a52-0000-1000-8000-00805f9b34fb", "Record Access Control Point");
        mCharacteristics.put("00002a14-0000-1000-8000-00805f9b34fb", "Reference Time Information");
        mCharacteristics.put("00002a4d-0000-1000-8000-00805f9b34fb", "Report");
        mCharacteristics.put("00002a4b-0000-1000-8000-00805f9b34fb", "Report Map");
        mCharacteristics.put("00002a40-0000-1000-8000-00805f9b34fb", "Ringer Control Point");
        mCharacteristics.put("00002a41-0000-1000-8000-00805f9b34fb", "Ringer Setting");
        mCharacteristics.put("00002a54-0000-1000-8000-00805f9b34fb", "RSC Feature");
        mCharacteristics.put("00002a53-0000-1000-8000-00805f9b34fb", "RSC Measurement");
        mCharacteristics.put("00002a55-0000-1000-8000-00805f9b34fb", "SC Control Point");
        mCharacteristics.put("00002a4f-0000-1000-8000-00805f9b34fb", "Scan Interval Window");
        mCharacteristics.put("00002a31-0000-1000-8000-00805f9b34fb", "Scan Refresh");
        mCharacteristics.put("00002a5d-0000-1000-8000-00805f9b34fb", "Sensor Location");
        mCharacteristics.put("00002a25-0000-1000-8000-00805f9b34fb", "Serial Number String");
        mCharacteristics.put("00002a05-0000-1000-8000-00805f9b34fb", "Service Changed");
        mCharacteristics.put("00002a28-0000-1000-8000-00805f9b34fb", "Software Revision String");
        mCharacteristics.put("00002a47-0000-1000-8000-00805f9b34fb", "Supported New Alert Category");
        mCharacteristics.put("00002a48-0000-1000-8000-00805f9b34fb", "Supported Unread Alert Category");
        mCharacteristics.put("00002a23-0000-1000-8000-00805f9b34fb", "System ID");
        mCharacteristics.put("00002a1c-0000-1000-8000-00805f9b34fb", "Temperature Measurement");
        mCharacteristics.put("00002a1d-0000-1000-8000-00805f9b34fb", "Temperature Type");
        mCharacteristics.put("00002a12-0000-1000-8000-00805f9b34fb", "Time Accuracy");
        mCharacteristics.put("00002a13-0000-1000-8000-00805f9b34fb", "Time Source");
        mCharacteristics.put("00002a16-0000-1000-8000-00805f9b34fb", "Time Update Control Point");
        mCharacteristics.put("00002a17-0000-1000-8000-00805f9b34fb", "Time Update state");
        mCharacteristics.put("00002a11-0000-1000-8000-00805f9b34fb", "Time with DST");
        mCharacteristics.put("00002a0e-0000-1000-8000-00805f9b34fb", "Time Zone");
        mCharacteristics.put("00002a07-0000-1000-8000-00805f9b34fb", "Tx Power Level");
        mCharacteristics.put("00002a45-0000-1000-8000-00805f9b34fb", "Unread Alert Status");

http wise they only seem to have this news service http://service.energicamotor.com/api/news

Code: [Select]
{"data":[{"newsId":45,"title":"New dealerships in Germany","publishedDate":"2020-03-27 18:00:00","newsURL":"http:\/\/service.energicamotor.com\/news\/45"},{"newsId":44,"title":"The Electrifying Podcast vol 1, featuring Eric Granado","publishedDate":"2020-03-26 20:00:00","newsURL":"http:\/\/service.energicamotor.com\/news\/44"}, ...
Title: Re: EVA CANbus or Bluetooth notification values
Post by: Hans2183 on August 06, 2021, 10:22:11 PM
I just found this response looking for some OBDII PID information for Energica :D. Since my last response I shared this video showing the BLE info fully decoded.

https://youtu.be/42581f3_Szc

Source code is also available at https://bitbucket.org/cappelleh/energica-bluetooth-android/src/master/
Title: Re: EVA CANbus or Bluetooth notification values
Post by: Hans2183 on August 08, 2021, 02:27:51 PM
Standard OBDII data

SOH or State of Health is one of the OBDII can bus values that can be received using a cheap OBDII dongle. My bike is only 5.000 km "old" so should return 100%. This is a full example of a message decoded from my bike.

Code: [Select]
OBDII PID
5B 91 1 Hybrid battery pack remaining life with formula 100/255*A

actual request from device including response

312 41.521761 LGElectr_2a:bf:68 (Nexus 5X) 66:1e:11:00:f1:43 (OBDII) SPP 19 Sent "015B\r"

315 41.587085 66:1e:11:00:f1:43 (OBDII) LGElectr_2a:bf:68 (Nexus 5X) SPP 25 Rcvd "7EF037F0133\r"
316 41.588481 66:1e:11:00:f1:43 (OBDII) LGElectr_2a:bf:68 (Nexus 5X) SPP 25 Rcvd "7EF03415BFF\r"
317 41.686086 66:1e:11:00:f1:43 (OBDII) LGElectr_2a:bf:68 (Nexus 5X) SPP 15 Rcvd "\r>"
318 41.722038 LGElectr_2a:bf:68 (Nexus 5X) 66:1e:11:00:f1:43 (OBDII) SPP 21 Sent "ATCAF0\r"

7EF     // response identifier
03      // data length
7F      //
01      // service ID
33

7EF     // response identifier
03      // data length
41      //
5B      // PID
FF      // 255 value for SOH = 100% converted with formula

That is OBDII standard compliant 15765-4 CAN (11 Bit ID, 500 KBit). Other working requests using standard OBDII protocol described at https://en.wikipedia.org/wiki/OBD-II_PIDs#Service_01 are in AT CRA 7EF mode and then I get clear 7EF response for requests like 0902 (service 09 PID 02) for vin, 015B for SOH, 0142 for 12V voltage and 0146 for air temp. Those responses all checkout on my bike.

There are likely more EV specific OBD PID values to be harvested here but I don't really have a good overview to be honest.


Manufacturer OBDII data

Besides standard OBDII data there is also Manufacturer specific data. This is data communicated using the OBDII protocol but with non standard identifiers and formulas.

For the Battery Temp this is the message we request and receive:

Code: [Select]
326 41.845333   LGElectr_2a:bf:68 (Nexus 5X)    66:1e:11:00:f1:43 (OBDII)   SPP 23  Sent "ATCRA200\r"
329 41.886801   66:1e:11:00:f1:43 (OBDII)   LGElectr_2a:bf:68 (Nexus 5X)    SPP 18  Rcvd "OK\r\r>"
330 41.915828   LGElectr_2a:bf:68 (Nexus 5X)    66:1e:11:00:f1:43 (OBDII)   SPP 18  Sent "001\r"
333 41.961850   66:1e:11:00:f1:43 (OBDII)   LGElectr_2a:bf:68 (Nexus 5X)    SPP 35  Rcvd "200164764170C01FFFE\r\r>"

The data requested within that AT CRA 200 mode is 001 and the response received is 200164764170C01FFFE. If I link that back to the info I have from the moment of the readout my SOC was at 71 and the battery temp was at 23C.

Code: [Select]
200
16  // 22 in dec ? maybe second batt temp sensor
47  // 71 in dec matches SOC
64  // 100 in dec ?
17  // 23 in dec matches batt temp
0C
01
FF
FE


Title: Re: EVA CANbus or Bluetooth notification values
Post by: togo on November 13, 2021, 03:01:27 AM
Anyone has decoded those canbus messages for Energica already? If someone is willing to share (PM) me a longer sample I can give it a try. Should contain some common words we can try.

Thank you for doing it Hans and publishing the results of your effort!

https://www.youtube.com/watch?v=42581f3_Szc

https://bitbucket.org/cappelleh/energica-bluetooth-android/src/master/

https://play.google.com/store/apps/details?id=be.hcpl.android.energica
Title: Re: EVA CANbus or Bluetooth notification values
Post by: Hans2183 on November 14, 2021, 12:21:52 AM
We have all the values on that VCU by now, last 4 are for battery voltage and power.

Code: [Select]
200
16  // 22 in dec
47  // 71 in dec matches SOC
64  // 100 in dec
17  // 23 in dec matches batt temp
0C  // see next
01  // 0C01 is 3084 /10 = 308.4 pack V
FF  // see next
FE  // DC is 25*x+y/10

still need to update that in the app. If I find more I'll put it here also https://bitbucket.org/cappelleh/emap-canbus/src/master/ Need to start checking other VCU now.
Title: Re: EVA CANbus or Bluetooth notification values
Post by: EVriderDK on January 11, 2022, 01:36:05 AM
Thanks a lot Hans!
Title: Re: EVA CANbus or Bluetooth notification values
Post by: Hans2183 on January 17, 2022, 12:28:24 PM
Thanks a lot Hans!
No problem!


Currently working on the iOS version, I can leave some progress here for those interested. I have a base app that I'll extend for this, code can be found here https://bitbucket.org/cappelleh/emapp-ios/src/master/ currently working on branch:

Code: [Select]
feature/obd2-connection-1
First step is to connect to the BLE services from those OBD2 bluetooth dongles. They all use the same UART service and characteristics. For iOS it's important to get a dongle that supports Bluetooth 4.0 and Bluetooth Low Energy. Android isn't that picky.

There is a great BLE tutorial for iOS available at https://www.freecodecamp.org/news/ultimate-how-to-bluetooth-swift-with-hardware-in-20-minutes/

That one is to connect to a LED matrix project so uses different UUID. For this to work with the OBD2 dongles we need below UART specific UUID.

from https://stackoverflow.com/questions/61090365/what-ble-characteristic-should-i-use-in-a-ble-ios-device-for-obdii

Quote
Service Service: UUID: 0000fff0-0000-1000-8000-00805f9b34fb
use the notify of this one...

Charac.: UUID: 0000fff1-0000-1000-8000-00805f9b34fb
Can read: false Can write: false Can notify: true

Charac.: UUID: 0000fff2-0000-1000-8000-00805f9b34fb
use the write of this one... Can read: false Can write: true Can notify: false

At this point I have that part working 8) . Next step is to send the right AT messages to the bluetooth dongle so we get the proper info back.

For these OBD2 adapters it might be possible to configure some profiles for generic BLE apps. The trickiest part then would be to transfer the response into something readable. Though if you can convert from base 16 to 10 you could get temp readouts that way.

For the Energica BLE connection this approach will never work and will always need a separate app like I'm working on (and Energica has in the app store). Reason for that is they do some sort of handshaking between the bike and the phone to allow a connection. That is also why you can and have to link a device first on the bike. Plus the data received once that connection is set up isn't as easy as converting hex to decimal.

I'll focus on OBD2 first since that contains the battery temp I'm interested in.
Title: Re: EVA CANbus or Bluetooth notification values
Post by: Hans2183 on January 17, 2022, 07:43:53 PM
Step 2: after scanning connect to Service UUID 0000fff0-0000-1000-8000-00805f9b34fb and listen for discovery of required characteristics.

For Notify Charasteristics with UUID 0000fff1-0000-1000-8000-00805f9b34fb on detection enable notifications, this will allow us to receive responses from the OBDII dongle.

Code: [Select]
func peripheral(_ peripheral: CBPeripheral, didDiscoverCharacteristicsFor service: CBService, error: Error?) {
        if let characteristics = service.characteristics {
            for characteristic in characteristics {
                if characteristic.uuid == ObdBluetooth.charxNotifyUUID {
                    notifyChar = characteristic
                    peripheral.setNotifyValue(true, for: notifyChar!)

Note that this is just initial code, proper safeguards are needed instead of unwrapping with ! for example.

On discovery of the write characteristic with UUID 0000fff2-0000-1000-8000-00805f9b34fb we can start sending data. The OBDII dongle expects bytes but we can easily feed it byte data from String message. For example the startup sequence to configure the OBDII dongle would look like:

Code: [Select]
} else if characteristic.uuid == ObdBluetooth.charxWriteUUID {
                    writeChar = characteristic
                    writeOutgoingValue(data: "ATWS\r")
                    writeOutgoingValue(data: "ATE0\r")
                    writeOutgoingValue(data: "ATH1\r")
                    writeOutgoingValue(data: "ATCAF0\r")
                }

with writeOutgoingValue method

Code: [Select]
func writeOutgoingValue(data: String){
        let valueString = (data as NSString).data(using: String.Encoding.utf8.rawValue)
        if let peripheral = self.peripheral {
            if let writeChar = self.writeChar {
                peripheral.writeValue(valueString!, for: writeChar, type: CBCharacteristicWriteType.withResponse)
              }
          }
      }

Some example output

Code: [Select]
Receiving data
Value Recieved: OK
>

If you print the responses all of these should already render something like "OK". At this point you can send and receive data strings. Next step is to request specific data and make a proper app around this to handle this communication with data parsing in the background and have a nice GUI to show the results.
Title: Re: EVA CANbus or Bluetooth notification values
Post by: Hans2183 on January 17, 2022, 08:28:48 PM
Step 3: In this final step I’ll show how to get temp and SOC values from the bike using this communication channel.

Similar to how we did the initial config we can also send and receive more Energica specific data. For example with the command ATCRA200 followed by 001. That ATCRA200 is a filter on address 200, 001 is that we just want to see 1 message. The can bus is a very busy environment so you typically just update on given intervals

Code: [Select]
// request some data
writeOutgoingValue(data: "ATCRA200\r")
writeOutgoingValue(data: "001\r")

The response we get is a sequence of hex values. Based on position and formulas described here we can convert these to decimals  https://bitbucket.org/cappelleh/emap-canbus/src/master/

Code: [Select]
Receiving data
Value Recieved: 200 0A 60 64 0B 0C E
Receiving data
Value Recieved: 3 FF FE
>

In this case we received 200 0A 60 64 0B 0C E3 FF FE which translates to
Code: [Select]
0A     = min batt temp 10 °C
60       = SOC 96%
64       = SOH 100%
0B       = max batt temp 11°C
0C E3  = 3299 /10 = 329,9 V

Now with some beers and some evenings I can make this all into a simple app update. For now the update will probably be a button for us to press and get an update. The fancy things will follow later.
Title: Re: EVA CANbus or Bluetooth notification values
Post by: Hans2183 on January 19, 2022, 01:30:09 AM
Just pushed an update to the app store with the first version with OBDII connection integrated. The screenshot is from development but with actual data from my bike. Also tested with a real connection.

(https://i.ibb.co/ykQJw7P/Simulator-Screen-Shot-i-Phone-13-mini-2022-01-18-at-16-36-32.png) (https://ibb.co/94rjFSg)

It's all very rough at this point. The Android version has evolved quite a bit including background services running and pushing data to https://ev-monitor.com. Those features will slowly make their way into this app also. For now you can connect and retrieve the current values by pressing the center blue button.

So if you just want to know current battery temp this will work. I'll add the charge speed and charge state flag later on in one of the updates. The app is still pending approval but if you become a pilot you can already download it.

Android version https://play.google.com/store/apps/details?id=be.hcpl.android.emapp
iOS version https://apps.apple.com/app/id1559468042?fbclid=IwAR262m6qf-x368mweND2HjopkhEq3U1-6v_dn53QNmpnOawGAk8c7X-KXjE

I'll probably skip the Energica BLE connection all together for this app. It was fun working my way around the "security" but there is no extra data, in fact there is less. The only benefit of the Energica BLE connection (besides the fun of making it work better than the original app) is that you don't need to plug in an OBD dongle. It's on when the key is on (and while charge).

I just have an OBDII bluetooth dongle plugged in and it only comes out when I'm at my dealer when he needs to attach my bike to the shops computer. This way the connection is also always available. I'm an iOS user myself but I've been using an Android test phone just for pushing the data.

I'm using the dongle from Power Cruise Control that you can get (here in Europe) as a kit from amazon (see link below). It's not overly expensive and it works great and is small. I've tried their app also but found the estimates not too accurate (those on the bike are better) and for me it's too expensive for what it does.

(https://i.ibb.co/1ffyV3B/Screenshot-2022-01-18-at-20-16-13.png) (https://ibb.co/1ffyV3B)

from https://www.amazon.de/gp/product/B08PL2F11P/ref=ppx_yo_dt_b_asin_title_o03_s00?ie=UTF8&psc=1

An alternative is this dongle, it's important to look for one with Bluetooth 4.0 or higher so that BLE is supported. Otherwise they won't work with iOS. Also not all copies (read cheaper dongles) support the full stack. Most of the typical clear blue ones and the black and yellow ones simply don't work for non standard OBD data like Energica requires.

In my opinion it's also best to stay away from the wifi enabled ones. First of all my app won't connect to those. I could technically make that work but honestly wifi is just not the way to go for these applications. BLE is way better suited.

(https://i.ibb.co/0j9YP2N/Screenshot-2022-01-18-at-20-16-45.png) (https://ibb.co/0j9YP2N)

from https://www.amazon.de/gp/product/B07PLDC2SC/ref=ppx_yo_dt_b_asin_title_o00_s00?ie=UTF8&psc=1

Update : this black dongle is available in many variants (check Ali) and although the one I received worked not all of these do. Also on energica the 12V power supply is completely cut off when the bike isn't running or charging so you have to press the on/off button on these on startup. Since its behind a panel that might not be convenient at all. If I find another one working I'll report back.
Title: Re: EVA CANbus or Bluetooth notification values
Post by: Hans2183 on January 19, 2022, 01:37:22 AM
This is the OBDII port location on the bike

(https://i.ibb.co/VHxMrR6/Screenshot-2022-01-18-at-20-32-31.png) (https://ibb.co/n3BQZ9p)

And these are some screenshots from the data visualised on http://ev-monitor.com. Note that I still need to integrate that into the iOS app.

(https://i.ibb.co/Qpb2ZpW/DD4-B53-BD-90-B2-4676-9591-5-FF28-DF54348.jpg) (https://ibb.co/hL7PkLG)
(https://i.ibb.co/DYbCrPv/CA1914-B7-5-CA8-4-F53-8-B27-309-F55-C234-A3.jpg) (https://ibb.co/XD4sYfK)
(https://i.ibb.co/rG7KvJR/7-ABB6-CEA-FD3-D-4475-9921-9-D03-DE031037.jpg) (https://ibb.co/Z6LRNCp)

(I've shared these before on facebook and on my blog)
Title: Re: EVA CANbus or Bluetooth notification values
Post by: Hans2183 on February 04, 2022, 08:11:41 PM
I was making this keynote to explain how the BLE connection works (as I never really did that in detail) https://www.dropbox.com/s/90sbuynwvboklvs/Energica-BLE-details.pdf?dl=0

(https://i.ibb.co/0G1wjdx/Screenshot-2022-02-04-at-15-09-21.png) (https://ibb.co/9rBM9C7)

And was thinking it might be worth it to trigger a few of the missing requests from below image

(https://i.ibb.co/ggJVDSm/Screenshot-2022-02-04-at-14-58-08.png) (https://ibb.co/C0Q2nbm)

The missing ones are

Code: [Select]
{4, 17, 1, -1, 0, 0, 0, 0, 0, 0}
{4, 17, 3, -1, 0, 0, 0, 0, 0, 0}
{4, 17, 5, -1, 0, 0, 0, 0, 0, 0}
...
{4, 17, 19, -1, 0, 0, 0, 0, 0, 0}
{4, 17, 26, -1, 0, 0, 0, 0, 0, 0}
{4, 17, 28, -1, 0, 0, 0, 0, 0, 0}

Anyone tried that before? The risk is limited as long as you don't put any data after the -1 position. Having a 1 there is enough to trigger something (like the horn or worse). But even then it's safe to play around. I've done some tests with the speed limit for example and it respects the system limit at all time.

If anything is received the question then is how to parse it obviously. I've been focusing on OBDII data myself lately.
Title: Re: EVA CANbus or Bluetooth notification values
Post by: Hans2183 on May 10, 2022, 02:15:26 PM
I've tried the other ble requests recently and got no new responses at all. So safe to say we have the supported responses covered. That route is closed.

On the ones we do receive we had around 5 bytes left that weren't parsed yet. Someone jumped in and discovered that one byte is battery temperature. Unlike obd2 it's a single max value instead of min/max but that is still very nice as an indication without the need for obd dongles. App updates are coming.

(https://i.ibb.co/1nVL3Z0/Screenshot-20220510-104033.png) (https://ibb.co/YW9362N)
(https://i.ibb.co/bQRJrgS/Screenshot-20220510-104049.png) (https://ibb.co/MZ56RDY)
(https://i.ibb.co/qYT5c3q/Screenshot-20220510-104412.png) (https://ibb.co/wh5sPFG)

The other 4 are 1,0 and 0,0 and logged for now. We'll see if that changes to anything useful.

Focus now will be on the OBDII data since BLE seems to be complete. On OBDII there is plenty of stuff to discover.