Connecting a Laser Distance Measurer (Bosch Disto GLM 50 C) with Smartphone (Android Studio)
Asked Answered
S

2

11

I got stuck at a special problem (I think). For a study project I have to make an Android application that can connect to a Laser Distance Measurer (Bosch GLM 50 C Distometer). So far I went through countless tutorials and hints here at Stackoverflow and other sources.

I'm new to Android and am sligthly overwhelmed. The task is to create an app, that reads the measured distance on the Bosch device and display/save it on the smartphone via Bluetooth.

Now my concrete question is: Is it possible to read the data (e.g. 2.083m) sent from the Bluetooth device? Any suggestions how to achieve that?

I'm able to establish a connection with the device, following this tutorial I found:

package com.test.bluetooth;

import java.io.DataInputStream;

public class Main_Activity extends Activity implements OnItemClickListener {

TextView measuredValue;
ArrayAdapter<String> listAdapter;
ListView listView;
BluetoothAdapter btAdapter;
Set<BluetoothDevice> devicesArray;
ArrayList<String> pairedDevices;
ArrayList<BluetoothDevice> devices;
public static final UUID MY_UUID = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB");
protected static final int SUCCESS_CONNECT = 0;
protected static final int MESSAGE_READ = 1;
IntentFilter filter;
BroadcastReceiver receiver;
String tag = "debugging";
Handler mHandler = new Handler(){
    @Override
    public void handleMessage(Message msg) {
        // TODO Auto-generated method stub
        Log.i(tag, "in handler");
        super.handleMessage(msg);
        switch(msg.what){
        case SUCCESS_CONNECT:
            // DO something
            ConnectedThread connectedThread = new ConnectedThread((BluetoothSocket)msg.obj);
            // Toast.makeText(getApplicationContext(), "VERBUNDEN", 0).show();
            String s = "Verbindung erfolgreich";
            connectedThread.write(s.getBytes());
            Log.i(tag, "connected");
            break;
        case MESSAGE_READ:
            byte[] readBuf = (byte[])msg.obj;
            String string = new String(readBuf);
            // Toast.makeText(getApplicationContext(), string, 0).show();
            break;
        }
    }
};
@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);
    init();
    if(btAdapter==null){
        // Toast.makeText(getApplicationContext(), "Bluetooth nicht verfügbar", 0).show();
        finish();
    }
    else{
        if(!btAdapter.isEnabled()){
            turnOnBT();
        }

        getPairedDevices();
        startDiscovery();
    }


}
private void startDiscovery() {
    // TODO Auto-generated method stub
    btAdapter.cancelDiscovery();
    btAdapter.startDiscovery();

}
private void turnOnBT() {
    // TODO Auto-generated method stub
    Intent intent =new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
    startActivityForResult(intent, 1);
}
private void getPairedDevices() {
    // TODO Auto-generated method stub
    devicesArray = btAdapter.getBondedDevices();
    if(devicesArray.size()>0){
        for(BluetoothDevice device:devicesArray){
            pairedDevices.add(device.getName());

        }
    }
}
private void init() {
    // TODO Auto-generated method stub
    listView=(ListView)findViewById(R.id.listView);
    listView.setOnItemClickListener(this);
    listAdapter= new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1,0);
    listView.setAdapter(listAdapter);
    btAdapter = BluetoothAdapter.getDefaultAdapter();
    pairedDevices = new ArrayList<String>();
    filter = new IntentFilter(BluetoothDevice.ACTION_FOUND);
    devices = new ArrayList<BluetoothDevice>();
    receiver = new BroadcastReceiver(){
        @Override
        public void onReceive(Context context, Intent intent) {
            // TODO Auto-generated method stub
            String action = intent.getAction();

            if(BluetoothDevice.ACTION_FOUND.equals(action)){
                BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
                devices.add(device);
                String s = "";
                for(int a = 0; a < pairedDevices.size(); a++){
                    if(device.getName().equals(pairedDevices.get(a))){
                        //append 
                        s = "Gekoppelt";
                        break;
                    }
                }

                listAdapter.add(device.getName()+" "+s+" "+"\n"+device.getAddress());
            }

            else if(BluetoothAdapter.ACTION_DISCOVERY_STARTED.equals(action)){
                // run some code
            }
            else if(BluetoothAdapter.ACTION_DISCOVERY_FINISHED.equals(action)){
                // run some code



            }
            else if(BluetoothAdapter.ACTION_STATE_CHANGED.equals(action)){
                if(btAdapter.getState() == btAdapter.STATE_OFF){
                    turnOnBT();
                }
            }

        }
    };

    registerReceiver(receiver, filter);
     filter = new IntentFilter(BluetoothAdapter.ACTION_DISCOVERY_STARTED);
    registerReceiver(receiver, filter);
     filter = new IntentFilter(BluetoothAdapter.ACTION_DISCOVERY_FINISHED);
    registerReceiver(receiver, filter);
     filter = new IntentFilter(BluetoothAdapter.ACTION_STATE_CHANGED);
    registerReceiver(receiver, filter);
}


@Override
protected void onPause() {
    // TODO Auto-generated method stub
    super.onPause();
    unregisterReceiver(receiver);
}

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        // TODO Auto-generated method stub
        super.onActivityResult(requestCode, resultCode, data);
        if(resultCode == RESULT_CANCELED){
            Toast.makeText(getApplicationContext(), "Bluetooth muss aktiviert sein", Toast.LENGTH_SHORT).show();
            finish();
        }
    }
    public void onItemClick(AdapterView<?> arg0, View arg1, int arg2,
            long arg3) {
        // TODO Auto-generated method stub

        if(btAdapter.isDiscovering()){
            btAdapter.cancelDiscovery();
        }
        if(listAdapter.getItem(arg2).contains("Gekoppelt")){

            BluetoothDevice selectedDevice = devices.get(arg2);
            ConnectThread connect = new ConnectThread(selectedDevice);
            connect.start();
            Log.i(tag, "in click listener");
        }
        else{
            // Toast.makeText(getApplicationContext(), "Gerät ist nicht gekoppelt", 0).show();
        }
    }

    private class ConnectThread extends Thread {

        private final BluetoothSocket mmSocket;
        private final BluetoothDevice mmDevice;

        public ConnectThread(BluetoothDevice device) {
            // Use a temporary object that is later assigned to mmSocket,
            // because mmSocket is final
            BluetoothSocket tmp = null;
            mmDevice = device;
            Log.i(tag, "construct");
            // Get a BluetoothSocket to connect with the given BluetoothDevice
            try {
                // MY_UUID is the app's UUID string, also used by the server code
                tmp = device.createRfcommSocketToServiceRecord(MY_UUID);
            } catch (IOException e) { 
                Log.i(tag, "get socket failed");

            }
            mmSocket = tmp;
        }

        public void run() {
            // Cancel discovery because it will slow down the connection
            btAdapter.cancelDiscovery();
            Log.i(tag, "Verbindung - läuft");
            try {
                // Connect the device through the socket. This will block
                // until it succeeds or throws an exception
                mmSocket.connect();
                Log.i(tag, "Verbindung - erfolgreich");
            } catch (IOException connectException) {    Log.i(tag, "connect failed");
                // Unable to connect; close the socket and get out
                try {
                    mmSocket.close();
                } catch (IOException closeException) { }
                return;
            }

            // Do work to manage the connection (in a separate thread)

            mHandler.obtainMessage(SUCCESS_CONNECT, mmSocket).sendToTarget();
        }



        /** Will cancel an in-progress connection, and close the socket */
        public void cancel() {
            try {
                mmSocket.close();
            } catch (IOException e) { }
        }
    }

    private class ConnectedThread extends Thread {
        private final BluetoothSocket mmSocket;
        private final InputStream mmInStream;
        private final OutputStream mmOutStream;

        public ConnectedThread(BluetoothSocket socket) {
            mmSocket = socket;
            InputStream tmpIn = null;
            OutputStream tmpOut = null;

            // Get the input and output streams, using temp objects because
            // member streams are final
            try {
                tmpIn = socket.getInputStream();
                tmpOut = socket.getOutputStream();
            } catch (IOException e) { }

            mmInStream = tmpIn;
            mmOutStream = tmpOut;

        }

        public void run() {
            byte[] buffer;  // buffer store for the stream
            int bytes; // bytes returned from read()

            // Keep listening to the InputStream until an exception occurs
            while (true) {
                try {
                    // Read from the InputStream
                    buffer = new byte[1024];
                    bytes = mmInStream.read(buffer);
                    // Send the obtained bytes to the UI activity
                    mHandler.obtainMessage(MESSAGE_READ, bytes, -1, buffer)
                            .sendToTarget();

                } catch (IOException e) {
                    break;
                }
            }
        }

        /* Call this from the main activity to send data to the remote device */
        public void write(byte[] bytes) {
            try {
                mmOutStream.write(bytes);
            } catch (IOException e) { }
        }

        /* Call this from the main activity to shutdown the connection */
        public void cancel() {
            try {
                mmSocket.close();
            } catch (IOException e) { }
        }
    }

}

After that, I found this example, that should read the incoming data from the device, but it didn't work:

try {
        Log.d((String) this.getTitle(), "Closing Server Socket.....");
        mmServerSocket.close();``

        InputStream tmpIn = null;
        OutputStream tmpOut = null;

        // Get the BluetoothSocket input and output streams

        tmpIn = socket.getInputStream();
        tmpOut = socket.getOutputStream();

        DataInputStream mmInStream = new DataInputStream(tmpIn);
        DataOutputStream mmOutStream = new DataOutputStream(tmpOut);

        // here you can use the Input Stream to take the string from the client  whoever is connecting
        //similarly use the output stream to send the data to the client


        text.setText(mmInStream.toString());
    } catch (Exception e) {
        //catch your exception here
    }
Sligo answered 31/10, 2016 at 19:15 Comment(5)
Could you please share the links with tutorials you've mentioned about?Quintal
Any update on this issue ?Devonian
Hi, did you get any plausible solution?Brynhild
Hi did you get a solution?Monnet
Bosch now have an official API. Was it not available when you asked? Or is it the objective of your exercise to do it without the official API?Assiniboine
I
4

The Bosch PLR 50 C (basically the cheaper version) uses the protocol known from the Bosch PLR 15. I could imagine the GLM 50 C also using it.

There is a post on EEVBlog.com that outlines the most important commands:

Example measure: send C04000EE --> reply 00 04 13 0E 00 00 32
Change endianness: 13 0E 00 00 --> 00 00 0E 13 distance in mm: 0x00000E13*0,05 = 180mm

Illegal answered 7/2, 2018 at 12:47 Comment(0)
H
3

There is a reverse engineered protocol: pymtprotocol available at github page for Bosch GLM 100 C, which is a device from the same series, so hopefully it would work with GLM 50 C. Unfortunately it's Mac OS X only, I would like it was OS independant so I could try it on Ubuntu before trying to rewrite protocol for Android. I'm beginner at programming and whatever I tried I ended up in a blind alley. If someone could fork pymtprotocol and make it available for Linux or Android I would much appreciate it.

P.S. all credits go to Peter Iannucci.

Holsworth answered 3/3, 2018 at 12:3 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.