| Vietnamese GPS - Intelligent on the go |
|
How to connect/retrieve NMEA sentences from bluetooth GPS
By ThreeSearch (Feb 19, 2007)
www.digitalmobilemap.com To connect/retrieve NMEA sentences from bluetooth GPS, your program needs to do the following tasks: 1. inquiry bluetooth device in range. 2. get bluetooth friendly name 3. select bluetooth GPS receiver from the list of detected devices. 4. search for service provided by GPS device. 4. get connection string from GPS device. 5. connect to and receive sentences from GPS device. Bluetooth GPS receiver provides L2CAP service, so your program needs to search for this service in order to get GPS's connection string url private UUID[] uuidSet; private UUID L2CAP_UUID = new UUID(0x0100); // L2CAP service uuidSet = new UUID[1]; uuidSet[0] = L2CAP_UUID; We need a ChoiceGroup to store a list of bluetooth friendly name of detected devices. We also need a vector to store detected devices. ChoiceGroup labels; Vector remoteDevices = new Vector(); LocalDevice localDevice; DiscoveryAgent discoveryAgent; Here is the sample code to inquiry bluetooth device in range: public void inquiryDevice() { inquiryCompleted = false; try { localDevice = LocalDevice.getLocalDevice(); discoveryAgent = localDevice.getDiscoveryAgent(); // inquiry bluetooth device in range // each time when a bluetooth device is discovered, DiscoveryListener will trigger procedure deviceDiscovered. // when inquiry completed, DiscoveryListener will trigger procedure inquiryCompleted discoveryAgent.startInquiry(DiscoveryAgent.GIAC, this); } catch (Exception e) { } } public void deviceDiscovered(RemoteDevice btDevice, DeviceClass cod) { try { labels.append(btDevice.getFriendlyName(false), null); // we need to remember bluetooth friendly name of detected device. remoteDevices.addElement(btDevice); // we also need to remember detected device by adding it to a vector list. numDevice++; // increase number of detected device by 1 } catch (Exception e) { } } public void inquiryCompleted(int discType) { inquiryCompleted = true; } After inquiry bluetooth device completed, we have a vector list that contain all the detected devices (remoteDevices) and a list of bluetooth friendly names (lables). Our program need to display the list of bluetooth friendly names and let user select one of them. When user selected one bluetooth friendly name from the list of bluetooth friendly names (lables) we will have the selected index (id). Pass this index (id) as a parameter to procedure startServiceSearch. Procedure startServiceSearch will get the element that has the same index with the selected index from the vector of detected devices (remoteDevices). Then we search for L2CAP service from selected device. Here is the sample code to search for L2CAP service: public void startServiceSearch(int id) { serviceSearchCompleted = false; try { // Search for Services remoteDevice = (RemoteDevice)remoteDevices.elementAt(id); // when a service is discovered, DiscoverLinstener will trigger procedure servicesDiscovered // when service search completed, DiscoverLinstener will trigger procedure serviceSearchCompleted int searchID = discoveryAgent.searchServices(null,uuidSet,remoteDevice,this); } catch (Exception e) { } } public void servicesDiscovered(int transID, ServiceRecord[] servRecord) { for(int i=0; i < servRecord.length; i++) { serviceUrl = servRecord[i].getConnectionURL(0,false); // when a service is discovered, we need to store connection url for later use. GPS receiver provides only one service. } } public void serviceSearchCompleted(int transID, int responseCode) { serviceSearchCompleted = true; } After search service completed you will have serviceUrl. This is GPS's connection string. We will use this connection string to connect to GPS receiver. Now we connect and retrieve data from bluetooth GPS receiver. private StreamConnection connection = null; private InputStream reader = null; // open connection to GPS try { if (connection == null) connection = (StreamConnection)Connector.open(serviceUrl); // how to get this serviceUrl has been discussed in above post if (reader == null) reader = connection.openInputStream(); } catch (IOException e) {} // when the connection is opened and ready, GPS will continueously send NMEA sentences by writing to OutputStream of the bluetooth connection. // our program need to continueously read data from InputStream of the bluetooth connection. The speed of reading in our program need to be same or faster than the speed of writing otherwise the stream will be overflow. byte data[]; int byteCount; string buffer; string sentence; while (your stop condition) { data = new byte[512]; try { byteCount = reader.read(data); // we read all data in InputStream if (byteCount == -1) // no data from inputStream { sentence = null; return; } buffer = new String(data,0,byteCount); // convert byte array data to string // parse NMEA sentence, I will explain later if (buffer.indexOf("$GPRMC") > -1) { sentence = buffer.substring(buffer.indexOf("$GPRMC")); if (sentence.indexOf("*") > -1) sentence = sentence.substring(0,sentence.indexOf("*")); else { if (buffer.indexOf("$GPGGA") > -1) { sentence = buffer.substring(buffer.indexOf("$GPGGA")); if (sentence.indexOf("*") > -1) sentence = sentence.substring(0,sentence.indexOf("*")); else sentence = null; } } } else { if (buffer.indexOf("$GPGGA") > -1) { sentence = buffer.substring(buffer.indexOf("$GPGGA")); if (sentence.indexOf("*") > -1) sentence = sentence.substring(0,sentence.indexOf("*")); else sentence = null; } else sentence = null; } } catch (IOException e) { sentence = e.getMessage(); } } // end of while (your stop condition) // close GPS connection try { if (reader != null) reader.close(); if (connection != null) connection.close(); reader = null; connection = null; } catch (IOException e) { reader = null; connection = null; } Let
me explain the logic of reading NMEA sentence.
|
WidgetBucks - Trend Watch - WidgetBucks.com
|