Adding a Heart Rate Monitor (HRM) wraps up the Mobile Weather Sensor project. To get started, a sensor selection was needed. And since I already have and use a Garmin HRM with a wireless chest sensor, using that same sensor with my setup was the logical choice.
But how to do it?
That was the challenge…
First thing was to figure out how the Garmin unit worked. What sort of RF signal was being sent to my handlebar mounted display? And what message protocol is used? What will it take to interface with my Android, wirelessly?
After some research, I found that the Garmin HRM used an Ant+ interface.
What’s that? Ant+ does look a bit intimidating at first glance. Take a look here.
Fortunately. I was able to boil things down to the bare essentials of what was needed in order for my android phone to receive heart rate data from the sensor. There were several elements needed to make things work…
- An ant+ radio was needed in the smartphone
- The ant+ API works directly with a native android app. But since the Weather Sensor App uses the Cordova web interface, a method of communication was needed between the Cordova JavaScript code and the native Java code.
- The phone app needed to automatically detect the HRM and pair with it (like bluetooth).
These modifications to the existing android app integrate the Java Ant+ API, the Heart Rate Monitor and JavaScript.
The Phone Ant+ Radio
Fortunately, my Samsung Galaxy Note 3 has a built-in ant++ radio. But in order to access this interface, an App must be installed from the Google Play Store. It is called ANT+ Plugin Service. It is really simple. There is no App icon to launch. This is how it works…
Once installed, the service is called anytime an App attempts to connect with an ant+ device. My phone is an ancient model, almost two years old now. Many of the newer phone come with this service pre-installed.
JavaScript to Java Interface
With an interest in portability between android and iOS phones, the Mobile Weather Sensor App has been built with a standard web interface. This presented a problem since the API provided by the ANT+ team supports android native Java (.java files) but not JavaScript.
Fortunately, a mechanism has been provided to “extend” the Cordova Web API to communicate with Java code. Here is the source of the information I used to implement the interface between my App and the native code needed to communicate with my heart rate monitor.
First thing to do was to add a reference to this interface code to the project’s config.xml file:
<feature name="HeartRateMonitor"> <param name="android-package" value="org.apache.cordova.antplus.heartrate.HeartRateMonitorInterface" /> <param name="onload" value="true" /> </feature>
The first parameter identifies the file containing the feature class object. In this case, the Java code is contained in the file “HeartRateMonitorInterface.java”. The second parameter makes this feature available upon loading the application’s Web view.
But how do we call the Java code from JavaScript?
Here is the Cordova mechanism used to call Java feature “actions” from JavaScript:
cordova.exec( callback-if-successful, //JavaScript Callback function if call //to Java code was successful callback-if-error, //JavaScript Callback function if call //to Java code was not successful "feature name", //Feature name from config.xml file. "feature action", //Feature action to be executed from //the .java file ["parameter array"]); //Parameter array to send to Java code
As we shall see, the Java code can return any string back to the JavaScript callback functions. That is how the heart rate received by the Java code is returned JavaScript.
Only two feature actions were implemented to support the heart rate monitor interface:
- ConnectHeartRateMonitor – This method establishes a connection between the App and the Heart Rate Monitor
- GetHeartRate – This method retrieves the newest heart rate from the Java code.
ConnectHeartRateMonitor is called once at the start of the application while GetHeartRate is called each time the app refreshes the sensor values.
The Java Code
The Java code implements the class “HeartRateMonitorInterface”. This class contains the following key methods:
- execute – This required methods is executed when JavaScript “cordova.exec(()” is called. As noted above, this method only supports two actions.
- ConnectHeartRateMonitor makes a call to the Ant+ API method “.requestAccess”. Fortunately, the API does all the hard work of connecting to the Heart Rate Monitor. The Class callback “base_IPluginAccessResultReceiver.onResultReceived” methods is invoked to report the status of the call.
- GetHeartRate simply returns the latest heart rate value back to JavaScript.
- base_IPluginAccessResultReceiver.onResultReceived is the callback invoked when the ant+ “.requestAccess” method is called. If access was successfully granted, we subscribe to the Heart Rate Monitor Events. Whenever a new event is received, the callback “HeartRateDataReceiver().onNewHeartRateData()” is invoked.
- IHeartRateDataReceiver().onNewHeartRateData() receives updates from the heart rate. Upon receipt of a new sensor value, the heart rate is saved to a class variable for retrieval, on-demand, from the JavaScript.
Conclusion
We now have a working application that supports all of the capabilities planned. The Eclipse project files for this application are on GitHub here. The data collected on this mobile application include:
- Temperature
- Barometric Pressure
- Humidity
- Speed
- Direction
- Coordinates
- Heart Rate
- Altitude
- UTC timestamp
- Internal ESP statistics
Who knows, there may be more added…
I am looking forward to the coming change of season. With this App and the ESP sensors, I expect to collect some interesting information about significant changes in micro-climate in the span of short distances along the local mountain trails. It will be great to finally quantify what is felt externally as you must peel on and off layers of clothing with changing conditions.
I hope you have found this information is useful to you in your own projects…