Current I am working on OBDII. While in bluetooth discovery to connect obd, How I determine which device is obd and which device is normal bluetooth device.Because I want auto connect my app with obd.
Is there any common characteristic of obd device which help me to determine this is OBD device?
My Code which I am trying for pairing obd device as per name.
//Register receiver for bluetooth discovery
private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if (BluetoothAdapter.ACTION_DISCOVERY_STARTED.equals(action)) {
//discovery starts, we can show progress dialog or perform other tasks
} else if (BluetoothAdapter.ACTION_DISCOVERY_FINISHED.equals(action)) {
//discovery finishes, dismiss progress dialog
} else if (BluetoothDevice.ACTION_FOUND.equals(action)) {
//bluetooth device found for pair
try {
// Here I want to know device is obd or not?
BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
//Make pair of obd device as per name:
if (device != null && !device.getName().equals("")) {
LogUtils.LOGE("NEW DEVICE", device.getName());
if (device.getName().equals(OBD_DEVICE_NAME_ONE) ||
device.getName().equals(OBD_DEVICE_NAME_TWO) ||
device.getName().equals(OBD_DEVICE_NAME_THREE)) {
pairDevice(device);
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
};
//Send pairing request to OBD Device
private void pairDevice(BluetoothDevice device) {
try {
Method method = device.getClass().getMethod("createBond", (Class[]) null);
method.invoke(device, (Object[]) null);
} catch (Exception e) {
e.printStackTrace();
}
}
After Pairing OBD Device with name, It will autoconnect and work fine.
Only good way to find out, is to connect and to send:
ATI
Which will return a ID, which always contain ELM327.
Related
I tried to create a simple android application to connect to my ELM327 device to get some car diagnostic data. But I wasn't able to set up the bluetooth connection b/t my android phone and my ELM327 device.
My code is very simple as below:
public class Bluetooth {
protected BluetoothAdapter mBluetoothAdapter= BluetoothAdapter.getDefaultAdapter();
private ConnectThread mConnectThread = null;
private AcceptThread mAcceptThread = null;
private WorkerThread mWorkerThread = null;
private BluetoothDevice mOBDDevice = null;
private BluetoothSocket mSocket = null;
private String uuid;
Bluetooth() {
mBluetoothAdapter= BluetoothAdapter.getDefaultAdapter();
Set<BluetoothDevice> pairedDevices;
if (mBluetoothAdapter == null || !mBluetoothAdapter.isEnabled())
return;
pairedDevices = mBluetoothAdapter.getBondedDevices();
if (pairedDevices.size() > 0) {
// There are paired devices. Get the name and address of each paired device.
for (BluetoothDevice device : pairedDevices) {
String deviceName = device.getName();
String deviceHardwareAddress = device.getAddress(); // MAC address
//TODO: check whether this is OBD and whether it is connected
//by sending a command and check response
if (deviceName.contains("OBD")) {
mOBDDevice = device;
uuid = device.getUuids()[0].toString();
break;
}
}
}
mBluetoothAdapter.cancelDiscovery();
}
/**
* Start the chat service. Specifically start AcceptThread to begin a session
* in listening (server) mode. Called by the Activity onResume()
*/
public synchronized void connect()
{
try {
// Get a BluetoothSocket to connect with the given BluetoothDevice.
// MY_UUID is the app's UUID string, also used in the server code.
mSocket = mOBDDevice.createRfcommSocketToServiceRecord(UUID.fromString(uuid));
} catch (IOException e) {
Log.e(TAG, "Socket's create() method failed", e);
}
try {
// Connect to the remote device through the socket. This call blocks
// until it succeeds or throws an exception.
mSocket.connect();
} catch (IOException connectException) {
// Unable to connect; close the socket and return.
try {
mSocket.close();
} catch (IOException closeException) {
Log.e(TAG, "Could not close the client socket", closeException);
}
return;
}
}
}
In the mainactivity, I will first new a Bluetooth class then call bluetooth.connect():
mBluetooth = new Bluetooth();
mBluetooth.connect();
When I debug the program, I was able to get my ELM327 bluetooth device by querying all the bonded devices with a name of "OBD". I also was able to get the device's uuid and create a socket using createRfcommSocketToServiceRecord. But in the connect function, mSocket.connect() always fail with a return value of -1 and get a IOexception.
My questions are:
When my android application connect to the ELM327 device, my android phone is the bluetooth client and my ELM327 device is the bluetooth server, is this understanding correct?
Is there a server program running on my ELM327 device listening and accept incoming connection? Is this defined behavior of ELM327 protocol?
Any idea why mSocket.connect()has failed? Any idea on how to look into this issue? Or any obvious error in my program? Thanks.
problem solved. see source codes below:
public synchronized void connect() throws IOException {
try {
// Get a BluetoothSocket to connect with the given BluetoothDevice.
// MY_UUID is the app's UUID string, also used in the server code.
mSocket = mOBDDevice.createRfcommSocketToServiceRecord(UUID.fromString(uuid));
} catch (IOException e) {
Log.e(TAG, "Socket's create() method failed", e);
}
try {
// Connect to the remote device through the socket. This call blocks
// until it succeeds or throws an exception.
mSocket.connect();
} catch (IOException e1) {
Log.e(TAG, "There was an error while establishing Bluetooth connection. Falling back..", e1);
Class<?> clazz = mSocket.getRemoteDevice().getClass();
Class<?>[] paramTypes = new Class<?>[]{Integer.TYPE};
try {
Method m = clazz.getMethod("createRfcommSocket", paramTypes);
Object[] params = new Object[]{Integer.valueOf(1)};
mFallbackSocket = (BluetoothSocket) m.invoke(mSocket.getRemoteDevice(), params);
mFallbackSocket.connect();
mSocket.close();
mSocket = mFallbackSocket;
} catch (Exception e2) {
Log.e(TAG, "Couldn't fallback while establishing Bluetooth connection.", e2);
mSocket.close();
//throw new IOException();
}
}
inputStream = mSocket.getInputStream();
outputStream = mSocket.getOutputStream();
}
I don't know much about Android, although I know about OBD2 and the lot.
It depends on the type of your adapter. If you have a WiFi adapter, you can consider the adapter being the server and you the client. You connect to a socket and then read from it. In the case of a Bluetooth adapter, it's different. If you connect via rfcomm, it's a serial protocol and neither is the server nor the client. If you connect via BTLE, the OBD2 dongle is the Peripheral and you are the Central.
On WiFi adapters, yes. This behavior is not part of ELM327 though. ELM327 only specifies the serial commands. How you transfer these is not part of the spec, since it happens on the layer above (WiFi, rfcomm, BTLE, USB, etc.).
Are you sure that rfcomm works via the socket interface? It's a serial interface, so I would have expected file-like operations.
Using Google Glass, I am able to discover Bluetooth devices and see their address and information. However, I cannot get the Glass to pair (bond) with them.
Update
Following the instructions on this page now I'm trying to get the bonding, but for some reason the BluetoothDevice.ACTION_BOND_STATE_CHANGED.equals(action) is never happening.
private void pairDevice(BluetoothDevice Ddevice) {
Log.d("MY_LOG", "Try to pair " + Ddevice.getName());
try{
Method m = Ddevice.getClass().getMethod("createBond", (Class[]) null);
m.invoke(Ddevice, (Object[]) null);
Log.d("MY_LOG", "Pairing " + Ddevice.getName());
}catch(Exception e){
Log.d("MY_LOG", "Error: ");
e.printStackTrace();
}
}
In the LOG I always get "Pairing DeviceName" but when I search for the bonded devices, it remains empty.
Any help will be greatly appreciated.
So I will answer my own question as I just found the way.
So first, the discovery of devices is quite easy, in onCreate() I used (besides all other sort of code you need):
MyBT = BluetoothAdapter.getDefaultAdapter();
MyBT.startDiscovery();
Filter = new IntentFilter(BluetoothDevice.ACTION_FOUND); // Register the BroadcastReceiver
Filter2 = new IntentFilter(BluetoothDevice.ACTION_PAIRING_REQUEST); // Register the Bond changing state
registerReceiver(mReceiver, Filter); // Don't forget to unregister during onDestroy
registerReceiver(mReceiver, Filter2); // ******
Then at the BroadcastReceiver you need to manage the devices and the pairing requests:
private final BroadcastReceiver mReceiver = new BroadcastReceiver() { // Create a BroadcastReceiver for ACTION_FOUND
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if (BluetoothDevice.ACTION_FOUND.equals(action)) { // When discovery finds a device
BluetoothDevice BTdevice = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE); // Get the BluetoothDevice object from the Intent
ListDev.add(BTdevice); // Add the device to an array adapter to show...
}
if(BluetoothDevice.ACTION_PAIRING_REQUEST.equals(action)){
BluetoothDevice device = ListDev.get(selectedDevice);
byte[] pinBytes = getStrFromName(device.getName(),7,11).getBytes(); // My devices had their own pin in their name, you can put a constant pin here...
try {
Log.d("MY_LOG", "Try to set the PIN");
Method m = device.getClass().getMethod("setPin", byte[].class);
m.invoke(device, pinBytes);
Log.d("MY_LOG", "Success to add the PIN.");
try {
device.getClass().getMethod("setPairingConfirmation", boolean.class).invoke(device, true);
Log.d("MY_LOG", "Success to setPairingConfirmation.");
} catch (Exception e) {
Log.e("MY_LOG", e.getMessage());
e.printStackTrace();
}
} catch (Exception e) {
Log.e("MY_LOG", e.getMessage());
e.printStackTrace();
}
}
}
};
After that the device is bonded and you can manage the connection with the UUID and the sockets just as in the Android webpage example.
Hope this helps!
We have a Bluegiga Bluetooth module that is set up to work as hands free device.
After initial pairing, I need my application to initiate connection to it via HFP programmatically. Can this be achieved in Android?
Using hidden api works for me!
// get default bluetooth adapter
BluetoothAdapter mAdapter = BluetoothAdapter.getDefaultAdapter();
// get bounded device on Android
Set<BluetoothDevice> devices = mAdapter.getBondedDevices();
if (devices.size() > 0) {
for (Iterator<BluetoothDevice> it = devices.iterator(); it.hasNext();) {
BluetoothDevice device = it.next();
// treat the device the default buletooth device you needed
mCurrentDevice = device;
// break;
}
} else {
return;
}
// another method to get headset(HFP) profile
mAdapter.getProfileProxy(mContext, new BluetoothProfile.ServiceListener() {
#Override
public void onServiceConnected(int profile, BluetoothProfile proxy) {
Log.e("log", "headset proxy connected");
try {
BluetoothHeadset mCurrentHeadset = (BluetoothHeadset) proxy;
// check whether or not current device hfp is connected or not, if not,
// try to connect the channel between phone and device using hidden api
if (mCurrentHeadset.getConnectionState(mCurrentDevice) != BluetoothHeadset.STATE_CONNECTED) {
Method connectMethod = mCurrentHeadset.getClass().getMethod("connect", mCurrentDevice.getClass());
connectMethod.setAccessible(true);
Boolean returnValue = (Boolean) connectMethod.invoke(proxy, mCurrentDevice);
Log.e("log", "headset proxy connected " + returnValue);
}
} catch (Exception e) {
e.printStackTrace();
}
}
#Override
public void onServiceDisconnected(int profile) {
Log.e(LogTag.TAG, "headset profile disconnected");
}
}, BluetoothA2dp.HEADSET);
I want to connect an Android phone and an Arduino Mega 2560 with bluetooth (JY-MCU) to open or close LED. Here's my Arduino code:
#include <SoftwareSerial.h>
#define arduinoRx 2
#define arduinoTx 3
int gelen_veri;
int LedCikis = 8;
SoftwareSerial bluetooth(arduinoRx,arduinoTx);
void setup()
{
bluetooth.begin(9600);
}
void loop()
{
if(bluetooth.available()>0)
{
gelen_veri=bluetooth.read();
switch(gelen_veri)
{
case 'A' :
digitalWrite(LedCikis,HIGH);
break;
case 'K' :
digitalWrite(LedCikis,LOW);
break;
default:
break;
}
}
}
In addition I have Android code:
onlight.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
// TODO Auto-generated method stub
try {
// String msg = "A\n";
// mmOutputStream.write(msg.getBytes()); // transmitter nesnemize 'A' karakterini ilettik.
mmOutputStream.write('A');
} catch (IOException ex) {
Log.e("hata", ex.getMessage());
}
}
});
offlight.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
// TODO Auto-generated method stub
try {
mmOutputStream.write('K'); // aynı şekilde transmitter nesnemize 'K' karakterini ilettik.
} catch (IOException ex) {}
}
});
}
When I debug my Android code everything is normal. But it doesn't work. Help me please.
Do you know blueArduıno? You can try and test your program & bluetooth devıce to understand where is the problem.
void findDevice() {
mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
if (!mBluetoothAdapter.isEnabled()) {
Intent enableBluetooth = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivityForResult(enableBluetooth, 0);
}
final Set<BluetoothDevice> pairedDevices = mBluetoothAdapter.getBondedDevices(); //daha önceden eşleşmiş cihazların listesi alındı
if (pairedDevices.size() > 0) {
for (BluetoothDevice device : pairedDevices) {
if (device.getName().equals("HC-06")) // JY MCU ; bizim bluetooth modulumuzun default ismi.
{
mmDevice = device; // JY-MCU bizim mmDevice nesnesimiz oldu .
break;
}
}
myLabel.setText("Bluetooth Device Found");
}
}
And
void connectBT() throws IOException {
try {
BluetoothDevice device = mBluetoothAdapter.getRemoteDevice("20:13:05:06:54:98");
// Benim bluetooth modulumun MAC adresi.
UUID uuid = UUID.fromString("00001101-0000-1000-8000-00805f9b34fb");
// Standard UUID. Çok büyük ihtimalle sizinde alacağınız modulün UUID numarası aynı olacaktır
mmSocket = device.createRfcommSocketToServiceRecord(uuid);
mmSocket.connect();
mmOutputStream = mmSocket.getOutputStream();
mmInputStream = mmSocket.getInputStream();
} catch (IOException e) {
Log.d("BLUETOOTH_CLIENT", e.getMessage());
}
}
they are my connection methods. As debug result of android is normal, i thought that arduino code has any problem or my bluetooth device. How can i understand where is the problem???
If you are using your phone did you use any bluetooth api ?
Anyway you can try the following
Download Bluetooth chat source which is widely available
https://www.google.com.sg/search?q=bluetooth+chat+&oq=bluetooth+chat+&aqs=chrome..69i57j0l3.2172j0&sourceid=chrome&ie=UTF-8#q=bluetooth+chat+source
OR use bluetooth SPP from android market
Install and test by sending characters from the send message to test for connectivity .
Subsequently you can read through the example and get a feel of using the bluetooth api .
You can do so by using bluetoth spp from android market or google bluetooth sample code (bluetoothchat) to test whether e issues is with android code or arduino.
I am trying to connect to a BLE devices based on CC2540 from TI (I have the keyfob from TI, and another device from connectblue OLP425) with my Motorola RAZR, the only succes I had so far is an app named Propagation on the market that I don't have access to the sources.
I tried to connect to the device with this code but the biggest thing I don't understand is the UUID,
I downloaded an app on a iPad 3 and I found a device has the following UUID
00000000-0000-0000-ff31-1a064f8c5966
private static final UUID SPP_UUID = UUID.fromString("00000000-0000-0000-ff31-1a064f8c5966");
BluetoothDevice bd =BluetoothAdapter.getDefaultAdapter().getBondedDevices().iterator().next();
//I only have I device paired that is the Bluetooth Low Energy Device so using the first Device returned by the iterator is fine.
try {
BluetoothSocket bs = bd.createRfcommSocketToServiceRecord(UUID);
bs.connect();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
All I get is a Service discovery failed in logcat
In almost all the example everyone is using
00000000-0000-1000-8000-00805f9b34fb
If I go further in the app it syas that the battery service is UUID 0x180f
I would just like to create an app the read the value of this service which is a simple decimal value
anyone has any succes pairing with a BLE device in the past?
thank you
Jonathan
I've been able to connect to my CC2540 with the Heart Rate Monitor.
I flashed the firmware using the CCDebugger and using 0000180d-0000-1000-8000-00805f9b34fbas the UUID i've been able to read a value.
Using the Motorola_BLE_profile sample app with some modifications.
primaryServices = mGattService.getGattPrimaryServices(device);
if (primaryServices == null) {
String message = "Connection failed !";
Toast.makeText(mContext, message, Toast.LENGTH_SHORT).show();
return;
}
for (i = 0; i < primaryServices.length; i++) {
Log.v(TAG, "primary service " + primaryServices[i]);
if (primaryServices[i].equalsIgnoreCase(hrmUUID)) {
try {
status = mGattService.connectGatt(device, hrmUUID, callback1);
if (status == true){
mDevice = device;
mLeState = CONNECTING;
BluetoothLeReceiver.isDevicePickerPending = false;
} else {
String message = "Connection failed !";
Toast.makeText(mContext, message, Toast.LENGTH_SHORT).show();
}
} catch (Exception e) {
Log.e(TAG,"Exception while calling gatt Connect");
}
return;
if (i == primaryServices.length) {
Log.v(TAG,"Primary Service not found");
String message = "Connection failed !";
Toast.makeText(mContext, message, Toast.LENGTH_SHORT).show();
}