This blog is the first in a series of articles which aim to demonstrate how the beta release of the ArcGIS Maps SDK for Java (with ARM Linux support) can be used for IoT data recording apps.
The libraries used in this article are available on request by emailing ARM64LinuxNative@esri.com.
Introduction
In this blog, I’ll walk through how to make an inexpensive GPS data logger using a Raspberry Pi to collect location updates every 10 seconds, and write them to a hosted data service on the ArcGIS platform. Potential uses of this kind of hardware could include vehicle or other mobile asset tracking; you could even make your own fitness or pet tracker.
I’m using the Raspberry Pi platform for this blog post series as they are particularly well suited for IoT projects. The Raspberry Pi has a good range of hardware extensions (such as GPS units, weather sensors, cameras) and software libraries making it easy to prototype a wide variety of data collection applications.
I used the following kit in this example:
- Raspberry Pi 3 Model B
- 20000mAh portable power bank
- USB GPS Unit
This is a picture of my setup just prior to popping into my rucksack for testing on a short bike ride.
The source code for this project is located in my gps-logger git project where I have also included some basic setup instructions for the Raspberry Pi.
Collecting data with unreliable network connectivity
One of the challenges you may come across in any IoT data collection app is an unreliable network connection. Although the data you want to record needs to be stored on a server for viewing or analysing (in my case for this blog, a feature service hosted on the ArcGIS platform), the equipment you are using may not always have a reliable network connection to write data into the data storage service.
For example, when I turn on the Raspberry Pi outside my house it connects to the network, but as soon as I cycle down the road collecting GPS tracks that connection soon goes away. This problem is easily overcome however using the offline data capabilities of the Java Maps SDK. Basically, my application uses the offline capabilities as follows:
- Whilst connected to the network, it gets an offline geodatabase from the feature service.
- The app uses the offline geodatabase for recording the GPS tracks without the need for a network connection.
- Once I’ve got a network connection, I can sync the data I’ve collected to the feature service.
For the purposes of demonstrating this app, I have created a feature service which is used by the application. You should however be aware if you record GPS tracks in this service, they will be visible by anyone, and the data will be regularly deleted. For a production application or your own private testing, you should create your own feature service in an ArcGIS Online account. More information can be found about offline data viewing and collection workflows here.
Reading data from the Raspberry Pi
In all the IoT data collection projects I’m going to share, I will be reading data from hardware devices connected to the Raspberry Pi. As I’m using the ArcGIS Maps SDK for Java as the bases for my projects, I have been using an open-source library called Pi4J. The library provides a Java API which gives you easy access to the Raspberry Pi hardware such as the serial port, camera, GPIO and I2C interfaces.
Processing raw GPS data
The data which comes from a GPS device such as the USB GPS I’m using in this project comes in the form of NMEA (National Maritime Electronics Association) sentences. These sentences contain position, velocity and time information which can be decoded and used to show location and direction on a map application. The text below shows an example of some NMEA data from a GPS:
$GPGSV,3,3,12,09,12,255,,20,12,068,,23,08,070,,10,03,099,*71 $GPRMC,185842.918,V,,,,,,,010321,,,N*4E $GPGGA,185843.918,,,,,0,00,,,M,0.0,M,,0000*55 $GPGSA,A,1,,,,,,,,,,,,,,,*1E $GPRMC,185843.918,V,,,,,,,010321,,,N*4F $GPGGA,185844.915,,,,,0,00,,,M,0.0,M,,0000*5F $GPGSA,A,1,,,,,,,,,,,,,,,*1E $GPRMC,185844.915,V,,,,,,,010321,,,N*45
I’ve used the Pi4J library to listen to the GPS serial data and once you are listening into this stream of data coming from your GPS device, we’ve made it easy for you to parse the sentences and turn them into location updates. The Java Maps SDK has a class called the NmeaLocationDataSource which has a pushData method which you need to call every time you get new data from the GPS unit.
Now you are pushing NMEA sentences into the NmeaLocationDataSource instance, you can set up a listener on the class which will fire every time you get a new position update. In the code below, I’m creating a new feature which can be written into my offline geodatabase which is recording my GPS track:
nmeaLocationDataSource.addLocationChangedListener(listener -> { // create default attributes for the feature Map<String, Object> attributes = new HashMap<>(); attributes.put("TrackID", "GPS Test"); attributes.put("Speed", listener.getLocation().getVelocity()); attributes.put("Heading", listener.getLocation().getCourse()); Point latestPoint = new Point(listener.getLocation().getPosition().getX(), listener.getLocation().getPosition().getY(), listener.getLocation().getPosition().getSpatialReference()); // update the latest position feature latestPosition = table.createFeature(attributes, latestPoint); // set flag to say there is a position update featureUpdated = true; });
Application code overview
Although the use case I’m demonstrating here would typically be implemented as a headless application which automatically starts up when the Raspberry Pi boots up, to make things easier to understand I’ve implemented the app based on a simple JavaFX UI where you can manually trigger the following operations:
- Getting an offline geodatabase for collecting data with no network
- Opening the offline geodatabase
- Reading the serial port to collect NMEA data and process to get position data.
- Recording the GPS data to the offline geodatabase
- Syncing GPS data collected back to the feature service.
The video below shows how I use the GPS logger to record a short bike ride.
The information I’m recording in the feature service is only basic point data recorded every 10 seconds along the route, but there are lots of possibilities for processing and enhancing the data recorded. For example, I could extend this workflow to find out more information such as:
- Route length
- Elevation profile
- Min, Max and average speed
The data collected in the feature service used in this app can be viewed this webmap.
Summary
In this blog post, we’ve looked at a use of the beta release of the ArcGIS Maps SDK for Java where we’ve set up an IoT device for collecting GPS location data and written this back into a feature service on the ArcGIS platform where the data can be viewed and further analysed. We’ve also explored how to collect data in an environment where network connectivity is unreliable by using our offline data collection techniques.
In the next blog posts, which showcase ideas for IoT using a Raspberry Pi, I will be adding the following project ideas:
- GPS logger with camera upgrade
- Weather station
If you would like to try these projects out for yourself, please contact us on ARM64LinuxNative@esri.com for access to the beta release of the ArcGIS Maps SDK for Java with Arm Linux support.
Please consider following @EsriDevs on Twitter or subscribing to Esri Community for the latest updates on our products.
Note: Raspberry Pi is a trademark of Raspberry Pi Ltd.
I do wonder if we could use a smaller Raspberry Pi Zero for tracking the adventures of Sprocket, the co-author of this blog post!
Article Discussion: