Projects Research & Design Hub

Build a Multi-Purpose GPS Tracker

Written by Carlo Tauraso

BLE MCU-Based Design

It’s easy to share your location using your phone. But what if you could add that location-sharing functionality to a GPS tracker? In this article, Carlo designs and builds a device with a GPS module, capable of notifying your position to an Android App in real time and sending GPS data via SMS. It uses Nordic Semiconductor’s nRF51822 BLE SoC.

  • How to build a GPS module, capable of notifying your position to an Android App in real time and sending GPS data via SMS
  • How to know the format and meaning of “NMEA Sentences.”
  • How to use the Adafruit “Ultimate GPS” GPS breakout board
  • How to develop firmware for GPS-based device
  • How to develop an app using Android Studio and the BluetoothLeGatt template
  • Nordic Semiconductor’ nRF51822 BLE SoC
  • MediaTek MT3339 chipset
  • “MT3339 PC Tool” software
  • GlobalTop Technology FGPMMOPA6C GPS module
  • 12mm coin cell (CR1220) battery
  • Adafruit “Ultimate GPS” GPS breakout board
  • Android Studio and the BluetoothLeGatt template

During outdoor activities, you often need to track and share your position with a friend or family member at certain points in your route, and even in situations where you are not sure of data network coverage. During my bike rides, for example, sometimes I would like to share my position. But because my smartphone is in my backpack, I have to stop to take it out—maybe with sweaty or dirty hands. A device capable of recording my training, while able to share my position simply by pressing a button, would be useful.

In my previous article [1] (Circuit Cellar 354, January 2020), I promised myself to improve my project firmware using Bluetooth Low Energy (BLE) notifications, a system to transfer data from server to client quickly and automatically, instead of explicitly requesting them. Therefore, I considered making a device with a GPS module, capable of notifying my position to an Android app in real time, and sending GPS data via SMS.

With all that in mind, this article describes my device called RemoteBLE tag. RemoteBLE tag is a GPS tracker based on the nRF51822 SoC from Nordic Semiconductor and a GPS breakout board from Adafruit Industries with functions that include a BLE remote control. By pressing a small button, you can send GPS data to another mobile phone, using the Bluetooth and SMS services made available by your smartphone.

There are many GPS trackers on the market, but it is nice to find the joy and satisfaction of DIY, especially looking an ecological future based more and more on reuse. By reading this article and my prior one, developers will be able to appreciate the differences between two methods commonly used for client-server communication in Bluetooth technology.

To design a device that can locate your position, you need to know the format and meaning of what are normally called “NMEA Sentences.” NMEA stands for National Marine Electronics Association, an association of electronic device manufacturers that has developed and manages the protocol used by most localization systems on the market—especially in the nautical sector. The historical NMEA 0183 is formally an interface protocol, developed to allow devices from different manufacturers to communicate. We can think of NMEA as a kind of “Esperanto”—a simple and universal language understandable by everyone.

Often, the tasks for which NMEA was developed are only partially explained. NMEA is seen in most cases as a set of strings to be received and interpreted, to derive information such as position, speed and altitude. It also includes an exchange of commands, and therefore a kind of collaboration between devices from different manufacturers to carry out more complex tasks. A Garmin navigator, for example, can send data to a Raymarine autopilot, which will receive information from an Airmar wind transducer, and will command the actuators on the rudder to drive the boat on the right route.

This collaboration is not very “democratic,” because communication is only one way. The protocol allows a talker device to send ASCII data to multiple low-speed (4,800bps) receiver devices. Despite some limitations and wiring complexity, this protocol has survived for several decades and is still a point of reference. In 2009, a new communication standard called NMEA 2000 was born. It is faster, bidirectional, in digital format and is able to manage multiple talkers, thus simplifying the wiring rules.

In my project, I use a breakout board based on MediaTek’s MT3339 chipset [2], compatible with the standard NMEA 0183 v.3.01. During the GPS module initialization, the nRF51822 configures it to output a single sentence called GPRMC (Recommended Minimum Navigation Information), which contains the essential data to extract longitude and latitude. An example of a GPRMC sequence with its basic fields and their ASCII format is given in Table 1.

TABLE 1 – GPRMC sentence ASCII format.For my project, the yallow highlighted fields are the fundemental values.

For my project, the yellow highlighted fields in Table 1 are fundamental. The Status field determines whether the GPS position is fixed or not. I consider the values of the Latitude and Longitude fields only when the Status equals V, discarding the other cases.

The numerical values of Latitude and Longitude are in degrees and decimal minutes format. Google Maps recognizes this format, but to make it even more compatible, I convert it to decimal degrees. The calculation is simple: just divide the decimal minutes by 60 to get the decimal digits of the degrees. 45 degrees 41.8407′ becomes 45.697345 degrees. This makes it easier to generate the SMS string interpretable by Android smartphones as a direct link for Google Maps.

RemoteBLE tag is also capable of tracking locations. The MT3339 chipset has an embedded logger function named “Locus.” The GPS engine uses chip-internal flash to log the position data. With two-sector flash (128KB), you can log up to 32 hours in Interval Mode (one record every 15 seconds). In Figure 1 you can see the default configuration found on the module I purchased.

FIGURE 1- MT3339 Default configuration parameters

As you can see, the GPS modules are configured in Interval Mode—one Basic record (16 bytes) every 15 seconds with UTC, Latitude, Longitude, Height and Valid check. Recording takes place in Full & Stop mode, so when the memory is full, it stops. At the end, you can transfer all the recorded data directly to a PC by using a simple cable with an RS232 TTL-to-USB converter and free “MT3339 PC Tool” software distributed by the manufacturer (more on that software later). With this PC Tool, you also can make special configurations on the GPS module, such as downloading EPO data (Extended Prediction Orbit) for supporting 7/14 days of satellite orbit prediction, activating AIC (Active Interference Cancellation) to let users get better navigation quality, or simply detecting the NMEA sentences for test.

The circuit consists of a core module based on the nRF51822 SoC, just like in my previous article [1]. For this project, however, I used a cheaper and smaller board, which you can find on the Internet by searching for the keyword “HW-651.” It is built around the nRF51822, a multiprotocol SoC for ULP wireless application. produced by Nordic Semiconductor. It incorporates an Arm Cortex M0 CPU, 256KB flash memory, 32KB RAM memory and a powerful 2.4GHz radio transceiver.

The GPS breakout board is the excellent “Ultimate GPS” from Adafruit [3]. The board is based on GlobalTop Technology’s FGPMMOPA6C GPS module, which embeds the MT3339 chipset and a 66-channel high-sensitivity receiver (-165dB) and a built-in antenna. (GlobalTop was acquired by Sierra Wireless). To keep the module configurations in memory (speed, NMEA filter sentences and so on) and to use the built-in RTC, you can add a 12mm coin cell (CR1220) as back-up battery. In my project, I used a version 2 board, so you have to cut the trace between the two RTC-labeled solder pads on the back, before inserting the coin cell. In the latest version, there is a built-in diode, so there is nothing to cut.

The nRF51 series RF transceiver is interoperable with BLE and other 2.4GHz protocol implementations. As shown in the schematic (Figure 2), the nrf51822 is in the basic configuration, with a 16MHz oscillator crystal and a little impedance network adapter for the integrated PCB antenna. I added a high-brightness LED (D2) connected to pin P0.20 for circuit status indication. I use a current-limiting resistor (R4) of 470Ω, but in some cases, it is possible to reach 330Ω, making the LED particularly visible. Table 2 shows the parts list for this project.

The RemoteBLE Tag schematic
C1, C2 = 12pF cap
C3 = 2.2nF cap
C4 = 1pF cap
C5 = 3.9pF cap
C6 = 1.5pF cap
C7, C8,C11 = 100nF cap
C9 = 1nF cap
C10 = 47nF cap
C12 = 0.1µF
C13, C14 = 10µF cap
R1, R4 = 470Ω res
R2 = 4.7kΩ res
R3 = 10kΩ res
X1 = 16MHz crystal
L1 = 4.7nH ind
L2 = 27nH ind
L3 = 3.3nH ind
S1 = micro switch
D1 = LED red
D2 = LED white
BT1 = 3.6V battery Li-ion 750mAh
BT2 = 3.0V battery CR1220
U1 = nRF51822
U3 = MIC5225-3.3V
TABLE 2 – Parts list for my RemoteBLE project

The switch S1 on pin P0.08 has a dual function. If you press it during logging, it sends the SMS with GPS location. And if you press it during power-up, it puts the nRF51822 in download mode. Pins P0.05 and P0.06 are configured, respectively, as RX and TX line of RS232 communication bus between the nrf51822 and the GPS breakout board. Pin P0.16, configured as digital output, is connected to the MIC5225 “ENABLE” line. The pull-up resistor R3 keeps it at a high logic level. The nRF51822 can control the power supply of the GPS module. Setting the pin P0.16 high/low it turns on/off the module.

I made some measurements to determine the best size battery. During tracking, the circuit absorbs about 27mA. With a small, 3.7V, 750mA-hour lithium-ion battery, 15 hours of operation can be reached, which is more than enough for common use.

To ensure a simple and very small assembly, I created an interconnection layer. The small card allows you to connect the two cards simply, adding only one LED, one microswitch and two pull-up resistors, is shown in Figure 3 (the green card in the lower left corner). The interconnection board also includes a connection strip for the battery, the JTAG bus (VCC, SWDIO, SWCLK, GND) to update the firmware, and the RS232 TTL port (GND, RX, TX) for data download.

FIGURE 3 – The Tag assembly

In Figure 4, you can see the top and bottom copper layer of the interconnection card and its PCB design with pinout details. As you can see, it is a small card with a simple scheme to connect the two breakout boards together. Assembly takes place by welding the cards to the interconnecting layer with one above the other, like a sandwich. Three views of the assembled prototype board are shown in Figure 5.

FIGURE 4 – The interconnection layer with pinout details
FIGURE 5 – Three views of the assembled prototype board

As in my previous article [1], I use the SDK ver.10 for the nrF51xxx series, and the Softdevice S110, (both supplied by Nordic Semiconductor). The firmware differs from the previous one in the way it communicates with the Android app. In the previous project, the sensor values were read through a user interaction. In this project, the app is notified when the GPS position value changes. This communication mode is useful when you need to monitor a sensor parameter and you want the most up-to-date value on your smartphone.

A lot of literature on the Internet concerns the development of firmware/software for Bluetooth devices. But often this communication mode is not explained simply enough for beginners. Therefore, in the next paragraphs I’ll discuss what changes are necessary, starting with the template of the last article—a Swiss army knife—for all those who want to take advantage of this feature.

Refer to the source code of the custom_peripheral_service.c procedure, which is available for download on Circuit Cellar’s article code and files download webpage. During the service configuration that provides the values of the GATT characteristics, a new descriptor called CCD (Client Configuration Descriptor) must be added. Therefore, I declares a new variable cccd_md, I allocate it and I assigned read and write permissions on it. To enable notifications on the second characteristic (the one defined as read-only) I added one flag that enables notifications char_md.char_props.notify = 1 and the pointer to the new descriptor char_md.p_cccd_md = & cccd_md. This is for the static data infrastructure.

Then, I changed the dynamic part—the way in which the value of the second characteristic is updated. To do this, in the custom_service_update_data function, I replaced the sd_ble_gatts_value_set sub-function with the sd_ble_gatts_hvx. The acronym HVX stands for “Handle Value X,” where X can be Indication or Notification. The function parameters are a connection handle and a pointer to a structure of type ble_gatts_hvx_params_t, which contains the information relating to the characteristic to be notified. Once these changes have been made, the client-side notification flow still needs to be enabled.

Another interesting aspect of the firmware concerns the initialization of the GPS module. Although developing a parser for receiving NMEA sentences is a common operation, in this case I sent commands to the GPS module to configure it and activate or deactivate predefined features. The MT3339 chipset can interpret and execute a series of commands inserted in the so-called MTK NMEA packet. They consist of a preamble character ($), a Talker ID (PMTK), a Packet Type (a numeric identifier from 000 to 999), some Data Fields and a Checksum.

For example, I used the PMTK251 command to set the TTL RS232 port communication speed to 9,600bps, the PMTK314 command to filter the NMEA sentences received by limiting the incoming traffic to the parser, and so on. You can find the syntax of all MTK packets in the datasheet [4]. To calculate the checksum, you can use a nice online application [5]. The algorithm is the same as the one used for NMEA sentences. Like all references in this article, those links are all available in the RESOURCES section at the end of this article.

After the GPS module initialization, the firmware listens on the serial port by parsing the incoming GPRMC sentences. The Latitude and Longitude values are packaged in the GATT characteristic, according to the format shown in Figure 6. When the user presses the SW-PB switch, the SMS flag is set to 1 and the app sends the SMS with GPS coordinates. The app does not send the SMS if position is not fixed.

FIGURE 6 – Android app IAQnet

I developed the app using Android Studio and the BluetoothLeGatt template provided with the environment. Let’s focus on the most useful part for developers: The activation of the notification flow for GATT characteristic values.

All changes are grouped in the module. In the GUI, I replaced the Button used to request the values updates with a Switch associated with two functions. One is for the ON state (readCustomCharacteristicOn), which enables notifications for the Longitude and Latitude fields, and one is for the OFF state (readCustomCharacteristucOff), which disables them.

There are two important basic points in the readCustomCharacteristicOn function. The first concerns the setCharacteristicNotification method, which receives two input parameters: an identifier that establishes which GATT characteristic you can receive notifications on, and a Boolean value that enables/disables it. The second activates the notifications flow by assigning the value ENABLE_NOTIFICATION_VALUE to the descriptor property 0x2902 (corresponding to the Client Configuration Descriptor created in the firmware).

You must not explicitly request the reading of the characteristic, because the onCharacteristicChanged event triggers at each value change. This event generates a broadcast message “ACTION_DATA_AVAILABLE” managed by the mGattUpdateReceiver object present in the module. The receiver discriminates the type of broadcast message and acts accordingly, executing the displayData function, which converts the GATT characteristic values into values assigned to the user interface fields. The function readCustomCharacteristicOff is exactly complementary to the readCustomCharacteristicOn. The user has the option to activate the real-time updating of the Latitude, Longitude values at any time.

Another interesting source code portion concerns the sending of GPS coordinates via SMS. I used a particular token called PendingIntent. If you give this token to another application, it allows the latter foreign application to execute some code (Intent) with your application’s permissions. In my project, I created an “SMS_SENT” type Intent, and I delivered it to an SMSmanager object, which exposes various methods for sending text messages. I used the “SendTextMessage” method, at which I passed the recipient’s number, the message string and the token relating to the “SMS_SENT” intent created earlier. A BroadcastReceiver object filters “SMS_SENT” type intents by returning the relative activity result. Therefore, I can check the result of the sending operation. Listing 1 shows the relevant source code section in the “displayData” method.

//Send SMS if gps is fixed and button pressed
if ((data.substring(0,2) != "00") & (data.charAt(19)=='1')) {
String nrdest = phonenr.getText().toString();
linkSMS = "My Position is:";
linkSMS = linkSMS + data.substring(0,2)+'°'+data.substring(2,4)+'.'+data.substring(4,9)+',';
linkSMS = linkSMS + data.substring(9,12)+'°'+data.substring(12,14)+'.'+ data.substring(14,19);
PendingIntent sentPI = PendingIntent.getBroadcast(this, 0, new Intent ("SMS_SENT"),0);

//Check the SMS is really sent
registerReceiver(new BroadcastReceiver() {
public void onReceive(Context context, Intent intent) {
if (getResultCode()==Activity.RESULT_OK){
Toast.makeText(getApplicationContext(), "Position sent", Toast.LENGTH_LONG).show();
else{ Toast.makeText(getApplicationContext(), "Error! Can't send position", Toast.LENGTH_LONG).show();
}, new IntentFilter("SMS_SENT"));

SmsManager smgr = SmsManager.getDefault();
smgr.sendTextMessage(nrdest, null, linkSMS, sentPI, null);
} } }

LISTING 1 – The Intent/Receiver system to send SMS

In Figure 7 you can see how the app starts by scanning all the Bluetooth devices present in the surrounding area. Tap on the REMOTEtag link (C3:4F:DE:F7:F8:EA MAC address), and the app will connect with the tag. Now, you can optionally select the phone number with which to share the position, and then turn the switch “Activate Notification” to “Yes,” so the GPS position values are updated in real time. Remember that only fixed positions are displayed, so if you see all zero values, it means that a fixed position has not yet been reached.

FIGURE 7 – Android app GPS RemoteBLE

To start the RemoteBLE tag, simply connect the battery to the board’s GND and VCC pins (see Figure 5). After turning on the circuit, the red LED on the GPS card starts flashing once per second while searching for satellites. Once the initialization is complete, the white LED flashes five times quickly. The tag goes into the Bluetooth connection status. Position tracking starts when a fix is found. From that moment, the red LED changes from one flash per second to one flash every 15 seconds to save energy.

Now, run the app—remember to answer affirmatively to all authorization requests (send SMS, read Contacts and so on) and activate Bluetooth. A list of nearby devices is displayed. Tap on REMOTEtag and connect. The app form has a button to select a recipient’s phone number from the contacts. When you want to send your position, just press the small switch on the card until the white LED lights up, releasing it afterward.

To download the tracking data, there is an interesting program provided by the manufacturer called “MT3339 PC Tool”—mentioned earlier in the article (Figure 8). You can easily find it on the Internet [6] or get it from this project’s files and source codes folder. The folder is available for download on Circuit Cellar’s article code and files download webpage. If you power up the circuit, keeping the switch S1 pressed, the white LED will light up constantly, and the RemoteBLE enters the Data Download mode. Connect a cable with TTL-RS232 converter directly to the GND, TX, RX pins (see Figure 5 again). Run the PC Tool, click on the “Locus” tab and then on the “Save” button. If you click on the “Parse” button, you can convert the downloaded binary data into an XML-format file compatible with Google Maps, and view your outdoor activity route.

FIGURE 8 – Android app GPS RemoteBLE

This project can be a useful application example for users who want to experience the notification system made available by Bluetooth. If you read it together with my previous article [1], you will have an overview of two common communication methods used in BLE with self-made electronic devices. The two source code templates solve most of the communication needs of our small projects.

Future development will involve exploiting the multiprotocol characteristics of the Nordic nrf51xxx SoC family. For example, consider the potential of other protocols such as ANT+, which is widely used in sports devices. An interesting evolution could be to test interfacing with some commercial device, or the innovations introduced in Bluetooth version 5. For now, I hope that reading this was interesting and fun. See you in the next one! 



[1] “Device Measures Indoor Air Quality” By Carlo Tauraso, Circuit Cellar 354, January, 2020.
[2] MT3339 chipset
[3] Adafruit “Ultimate GPS” breakout board
[6] Download at MT3339 GPS PC Tool

Adafruit Industries |
MediaTek |
Nordic Semiconductor |


Don't miss out on upcoming issues of Circuit Cellar. Subscribe today!

Note: We’ve made the October 2017 issue of Circuit Cellar available as a free sample issue. In it, you’ll find a rich variety of the kinds of articles and information that exemplify a typical issue of the current magazine.

Would you like to write for Circuit Cellar? We are always accepting articles/posts from the technical community. Get in touch with us and let's discuss your ideas.
Become a Sponsor
+ posts

Carlo Tauraso ([email protected]) studied computer engineering at the University of Trieste in Italy and wrote his first assembler code for the Sinclair Research ZX Spectrum. He is currently a senior software engineer, who does firmware development on network devices and various types of micro-interfaces for a variety of European companies. Several of Carlo’s articles and programming courses about Microchip Technology PIC MCUs (USB-PIC, CAN bus PIC, SD CARD, C18) have been published in Italy, France and Spain. In his spare time, Carlo enjoys playing with radio scanners and homemade metal detectors.