Initialization of obd adapter - android

I am developing a android application which reads Obd data from vehicle's Obd adapter via bluetooth... I am facing issue while initializing the adapter. I have sent following Obd commands in sequence to initialize the obd :
atz (received OK)
atsp0 (Received OK)
ate0 (Received OK)
0100 (This is the part where issue occurs)...
Some times for this command i receive BUSINIT:ERROR.. And after that for every vehicle command (except AT commands) same error is repeated..
I want to know the Exact initialization sequence ?

It seems your obd initialization and obd protocol selection failed. You should follow these steps:
AT D
AT Z
AT E0
AT L0
AT S0
AT H0
AT SP 0
When protocol selection command response without any error like listed below, your connection is OK and you can request new commands like '0100' command.
Errors:
UNABLE TO CONNECT
BUS INIT... ERROR
?
NO DATA
STOPPED
ERROR
Command Explanation:
AT D -> Set all to defaults
AT Z -> Reset Obd
AT E0 -> Echo off
AT L0 -> Line feed off
AT S0 -> Spaces off
AT H0 -> Headers off
AT SP 0 -> Set Protocol to 0 "Auto", search all protocols and connect it with proper protocol for that obd
For AT SP command, if you know your vehicle's obd interface protocol, you can choose that specific protocol other than make Auto and search all possible protocols. You can use different inputs:
Protocol Parameters: Hex[0,1,2, ... ,B,C]
Auto select protocol and save.
AUTO -> 0
41.6 kbaud
SAE_J1850_PWM -> 1
10.4 kbaud
SAE_J1850_VPW -> 2
5 baud init
ISO_9141_2 -> 3
5 baud init
ISO_14230_4_KWP -> 4
Fast init
ISO_14230_4_KWP_FAST -> 5
11 bit ID, 500 kbaud
ISO_15765_4_CAN -> 6
29 bit ID, 500 kbaud
ISO_15765_4_CAN_B -> 7
11 bit ID, 250 kbaud
ISO_15765_4_CAN_C -> 8
29 bit ID, 250 kbaud
ISO_15765_4_CAN_D -> 9
29 bit ID, 250 kbaud (user adjustable)
SAE_J1939_CAN -> A
11 bit ID (user adjustable), 125 kbaud (user adjustable)
USER1_CAN -> B
11 bit ID (user adjustable), 50 kbaud (user adjustable)
USER2_CAN -> C

Just wanted to put my two cents in. I've been recently developing an application in C++ and LabVIEW to communicate to a ELM-327 - based bluetooth module to retrieve information from my car's ECU. Sometimes the initialization sequence fails, sometimes it works. What I've found is that the 'keywords' bytes of the ECU protocol initialization are sometimes not being detected correctly. I think my bluetooth module is the problem, because it turns out is a chinese clon of a legit ELM-327. How do I know that? If you issue the command ATI , it would reply "ELM-327 ver. 1.5", and according to the manufacturer, they NEVER released a 1.5 version =D
What has worked for me is something like this:
Open communication, send ATZ
ATSP0
ATSS (This enables the recommended protocol search order)
010D
If 4. fails, then close communication, wait 3 or more seconds and GO TO 1
More OBD-II or AT-Commands.
The BUSINIT:...ERROR response means that the ELM-327 was unable to finsh the start-up sequence of the ECU protocol. Also, before sending an OBD-II command, like 010C, you can initialize the communications with the ATSI command, if your can happens to use the ISO-9141-2 or ISO-14230-4 KWP protocols.
You can find out what protocol your car uses if you send the command ATDP to the ELM-327 after succesfull automatic detection.
Hope this helps.

"AT E0"
"AT L0"
"AT ST 00"
"AT SP 00"
Works for me.
And one more thing... I send all these commands one after another with the delay of 500ms! Without a delay the initialization fails almost every time, don't forget, this is bluetooth and it requires more time to send and receive responds...

Your initialisation sequence should work if the hardware is fully OBD-II compatible and the car is OBD-II compliant. If you still get errors on the 0100 command, check the ignition is on and the hardware is fully operational.

0100 is the first command which will reach the actual car.
The AT commands are tor the (ELM327)-chip. So something is wrong with the communication between OBD connector and the car. Connection between your app and the connector is fine.
Obdkey is most likely to be right about the OBD-II compatibility. Please try to use an existing app to prove that, if it doesn't work, something is wrong with your car, or connector.
Btw: It's helpfull to state which obd-II adapter you have, and maybe your car.

Related

Connection Loop With "Ethernet to USB" adapters problem

I have a problem with my video streaming connection setup.
I'm trying to create a cabled connection setup. But I have a problem.
My setup is between two android devices and here is the connections;
Device A -> usb-ethernet adapter -> ethernet cable -> ethernet-usb adapter -> Device B
I can create a connection and send pings between both devices but there is no smooth values on it.
E.g My exceptation is about 1ms but there is 10-13 ms and sometimes it can be 1500ms and etc. And because of it I lost my video streaming and see unsafe connection.
I think there is a loop between two ethernet to usb adapter and source of my problem is that loop.
That is the question, how can I prevent that loop and create stable connection with this setup? Is there any idea about it?
Thanks.
Device A -> usb-ethernet adapter -> ethernet cable -> ethernet-usb adapter -> Device B
There's no loop. A loop requires a bridge/switch and an additional (redundant) link.
Any round-trip delay beyond 1 ms indicates a larger problem: bad cable, duplex mismatch, crappy USB adapters, crappy TCP/IP stack, network congestion, CPU overload.
A simple IPv4 over Ethernet ping (default 32 bytes data) has a total size of 8(L1) + 18(L2) + 20(L3) + 8(ICMP) + 32(data) = 86 bytes. Even over 10 Mbit/s that's just .14 ms plus processing overhead (perhaps another .1 ms).

Emulating BLE Services (BLE Sniffer)

Long Description:
I have a DJI Osmo Mobile 3 gimbal with Bluetooth 5.0, which supports ActiveTrack 3.0 technology. It connects to your phone via Bluetooth and using the DJI Mimo app you can select an object and track it.
I want to implement this technique in Python using OpenCV.
As I understood, the phone calculates position of the object using computer vision and then sends the coordinates via Bluetooth to the gimbal, which then follows them. I connected to the gimbal with NRF Connect app for android and looked for its services and characteristics, and this is what I found:
Services
Some unknown information getting sent
UPD: looks like the 4 bytes after 57 on the picture mean the joystick values. Fisrt 2 are responsible for left-right tilt, the other ones indicate up-down state. Looks like all of them can be max. 256, but I don't understand, why do they need 2 bytes for each action?
First 2 Bytes:
d2, 03 (210, 3) - full right
c2, fb (194 251) - full left
Last 2 Bytes:
5a, 04 (90, 4) - full up
a6, fc (166, 252) - full down
HID Control, which doesn't return any information
The characteristic with UUID
0xFFF5
Looks like what I need, but now I need to find out, in which format the coordinates are getting sent. For this purpose I want do simulate same BLE services as on the gimbal and let the phone think it is a real one. After the connection it should send data to some of the characteristics. So now the main question.
Main question:
How to emulate BLE Services and their Characteristics using Android, RPI, ESP32 or whatever to get data being sent to those characteristics? Is there any app, library or piece of code for such purpose?
I've seen dongles like CC2045, which are designed to work on 2.4GHz frequencies and sniff BLE Traffic, but it will take for a long time for them to arrive to me. Also nRF52840 based donglas are not an option right now. So I want to implement it using things I have. Is it possible? Thanks!

ELM327 Bluetooth communication issue

I made an Android app to communicate with an ELM327 OBD-II dongle via bluetooth.
When I test the app with a bluetooth serial terminal (CoolTerm / macOS) the app is receiving and sending data without an issue.
Using my app to transfer commands to the ELM will result in broken and splitted answers.
Output:
DataReceivedHandler: 9V
DataReceivedHandler: 9V>
DataReceivedHandler: 11.
DataReceivedHandler: 9V>
The example above should show the result of the AT RV command which queries the battery's voltage of the vehicle (I sent the command multiple times).
Expected (good) result should look like this: >11.9V
Before I send the first command to query OBD values the ELM is initialized by these AT-commands:
AT D
AT Z
AT E0
AT L0
AT S0
AT H0
AT SP 0
If you have any idea how to get clear answers from the ELM, please let me know.
Thanks in advance!
Found the solution..
The terminal program was sending \n and the ELM sends \r for the termination of the statement.

Detecting whether a BLE device is connectable on Android

I am working on a project for configuring beacons. A certain amount of time after being powered on, a beacon becomes unconfigurable until it is power-cycled. In order to show a list of the configurable beacons, I am looking at certain characteristics (Bluetooth device name, certain manufacturer data in the advertising packet). I also need to know if it is "connectable", i. e. if the PDU Type in the BLE advertising packet for the device indicates that it is connectable. I've searched the Android Bluetooth classes high and low, both in Android 4.X and 5.X and haven't been able to find anything that will tell me this information.
I realize that one way to determine the beacon connectability is to connect up to it, e. g.: device.connectGatt(...). However, I've seen it take over two minutes sometimes before a callback to onConnectionStateChange comes back with STATE_DISCONNECTED. Also, there may be many of these beacons in an environment, and connecting up to every single one that might be configurable would be inefficient.
The iOS equivalent of this attribute can be found in the advertisementData dictionary under the key CBAdvertisementDataIsConnectable in the CBCentralManagerDelegate callback method centralManager:didDiscoverPeripheral:advertisementData:RSSI.
So, the question is: is there a way on Android to determine whether or not a BLE device is "connectable" from advertising data or scan result or ... ?
UPDATE: AS of the finalized APIs in the Android O SDK, the ScanResult class (itself added as of Android 5.0) now has the isConnectable() method. Detecting connectable advertisements is possible only on Android 8.0+. See here for more info: https://developer.android.com/reference/android/bluetooth/le/ScanResult.html#isConnectable()
Prior to Android 8.0, unfortunately it is not possible.
A connectable advertisement is determined by the PDU Header byte 0. You can see this in the example structure below:
d6 be 89 8e # Access address for advertising data (this is always the same fixed value)
40 # Advertising Channel PDU Header byte 0. Contains: (type = 0), (tx add = 1), (rx add = 0)
24 # Advertising Channel PDU Header byte 1. Contains: (length = total bytes of the advertising payload + 6 bytes for the BLE mac address.)
05 a2 17 6e 3d 71 # Bluetooth Mac
The problem is on devices prior to Anroid 8.0, the Android scanning APIs give you no access to these headers. You get exactly three fields in the callback from Android 4.x:
onLeScan(BluetoothDevice device, rssi, byte[] scan data)
The scan data byte array starts after the header bytes mentioned above. And from what I can see of the BluetoothDevice definition, none of the fields or methods tell you if it is a connectable advertisement -- the class is just a container for the bluetooth mac address with methods to exercise functions on the bluetooth stack. And there are no methods in IBluetooth.aidl which is the private interface to the bluetooth stack (and what BluetoothDevice calls to get its info) that can get this flag.
It appears that this information is not passed up to the Java layer from the BlueDroid stack prior to Android 8.0.
It should be possible since Nordic's nRF Master Control Panel does this.
After some digging I think I know how it does this. I'm not sure it's the right way to do it though.
I tried using the LE Advertiser and setting the device as connectable. In the Nordic app, a device is set as connectable depending on the bytes found at scanResult.getFlags().
I found that this code works for my devices:
int flags = scanResult.getScanRecord().getAdvertiseFlags();
if ((flags & 2) == 2) {
//connectable
}

how to request OBD parameters and receive them

I'm new to android and I thought to develop a bluetooth app to retrieve parameters from an OBDII device. I have downloaded the sample bluetooth chat application and configured it. The problem is how and what is the message that I need to send to the OBDII device in order to receive the parameters? and how should I handle them in the application side?
Thank you.
You're question is not very specific, but I will give you some guidelines.
First of all, test with an exisiting OBD-II reader application if your car actually works.
The ELM327-bluetooth-connector you have (I assumed it's a ELM327) translates ASCII commands to voltages. So all you have to do, is send some ASCII commands, and you get ASCII-values back.
The OBD protocol knows several modes and parameter's, but I will explain to get real-time data. That's mode 1.
Mode 1 Sending
This is kinda simple as it is.
Mode 1 is '01'.
After that part, you have to send a parameter ID with it. 0C is for RPM, 0D is for speed. (Look into the link below).
And after each command you have to send a Carriage Return. (CR = '\r')
So basically, for speed, you have to send:
'010D\r'
Receiving Mode 1
The answer you will get back from a Mode 1 query, starts with '41'.
After that the parameter ID is returned, and then the value.
The value is most of the time in hex. You will have to do some conversion to read a human readable value. For more information, see the link, as formula's to convert are provided too.
Example:
'410D17'
So 17 is the value of your current speed in hex. 17 to decimal is 23, so you're driving with 23 km/h.
This wikipedia page has some good information about it:
OBD-II Parameters

Categories

Resources