This project is not about a watch (yet), it's a watch-like wearable device for hikers, it a hiking tracker !
Hiking Tracker is a wearable device to sense the change in surrounding environment of a hiker during hiking.
The idea is to observe the change of following parameters during hiking :
- Ambient Temperature
- Atmospheric Pressure
- Relative Humidity
- Ambient Light Illuminance
- LocationAltitude
- UV Index
- Step counts
Hiking tracker will provide some interesting insights about hiking. For example: on the mountains where it is cold, dry, low density air compared to lower lands, many people find it hard to breath. Some experience dry skin irritation. This device lets people interested in hiking to know their limits and keep track of things. There is also the fun of knowing altitude when climbing high places. Knowing UV index is also necessary for skin protection.Not just the mountains but also exploring swamps, deserts, forests - each has an unique environmental profile, being able to monitor the environment on the go is a great way to understand the nature.
About 2 years ago, I made this ---> Hiking Tracker project with Arduino Uno and bunch of I2C sensor boards. But it was big, bulky and not so nice looking !
Now, I am going to remake that project with RSL10 Sensor board. This time, it will be a real wearable with metal wristband, low power BLEsolution with mobile app for live data monitoring, cloud dashboard for graphsand widgets.
Hardware BuildRSL10 board is packed with all the sensors needed to build a hiking tracker wearable solution on a small footprint.
- I had this old Seiko watch sitting around for years and guess what ? It has the perfect bore size for the RSL10 sense PCB to fit in it !
- First, I removed all the guts from a wristwatch like this -
- Then, I de-soldered the CR2032 holder from RSL10 sense board and placed it inside where the watch dial goes.
- To secure the RSL10 sense board, I applied some epoxy resin glue on the outer edge of the board like this -
Finally, a small LiPo battery is placed beneath the RSL10 sense board and connections are makd to Vcc and Gnd. 1N4148 diode is used in series to regulate the voltage and keep it under 3.6 volts. This way, fully charged battery won't cause any harm to RSL10 or the sensors onboard. TP4056 based LiPo charger will be used to charge the battery. I added an on/off jumper to connect or disconnect the battery.
Pin Mapping
All the sensors are connected to RSL10 over I2C bus and few GPIO pins are connected to RGB LEDs, user buttons and an spare GPIO pin available for interfacing with external hardware.
Following sensors on RSL10 SENSE board will be utilized to build the project :-
- BME680 environmental sensor will be used to measure Ambient Temperature, Atmospheric Pressure and Relative Humidity of the Air directly.
- NOA1305 Light sensor will be used to measure Ambient Lux level directly.
- BHI160 is a combined Accelerometer and Gyroscope which has 6 DOF. It can measure the orientation of hand and detect hand swing patterns. When people walk, their hands swing kind of like a pendulum. Hand position data (Z-axis orientation) is sampled into an array repeatedly, checked for a maximum and minumum threshold to detect and calculate Step Counts. This algorithm yields about 90% accurate step counting.
- Air density is inversely proportional to Altitude (or height). Air density changes with change in atmospheric pressure and air temperature. Altitude is calculated using following formula (see details in c code below):-
- About 5% of sunlight is UV light and the UV index is indirectly measured with some calculation based on the outdoor Lux level data measured by NOA1305. This is an approximate measurement. UV light intensity is also a function of Altitude and Humidity. UV intensity increases by 10% per 1000 meters of altitude increase.
All these sensors are low power and suitable for wearable applications.
RSL10 is an ARM Cortex M3 ultra low power microcontroller with Bluetooth support, it has maximum clock speed up to 48 MHz, 88 kB of SRAM and 384 kB of flash for firmware. It can operate over a wide voltage range of 1.1 to 3.3 volts. More details on RSL10 can be found here.
RSL10 fetches the sensor data by communicating with BME680, NOA1305 and BHI160 sensor chips over I2C bus, performs calculation and send processed data to the mobile app, which is an emulated app inside Atmosphere IoT app.
This app acts as IoTgateway and sends data to Atmosphere Cloud for viewing on dashboard over internet.
Even without the app running or no internet connection, this hiking tracker can indicate uncomfortable Temperature, Pressure and Humidity by glowing the RGB LED on RSL10 board. RGB LED can be turned off with push button PB2.
Atmosphere IoT is an all in one embedded firmware, mobile app and cloud storage & dashboard solution. RSL10 SENSE board is officially supported by Atmosphere IoT. Atmosphere Studio (browser based IDE) enables rapid prototyping of IoT projects. I will be using this platform to program this RSL10 based hiking tracker wearable device.
Setup Configuration
Before programming the RSL10-SENSE board, following setup configuration must be completed :-
- Create an account for Atmosphere IoT Platform, which will allow user to access the Atmospheter Studio, an online based firmware, mobile app and cloud dashboard development IDE.
- Download and Install Atmosphere Agent on Windows/Linux computer, which acts as an intermediary between the host computer and the browser running Atmosphere Studio for flashing firmware.
- Download and Install Atmosphere IoT App on Android or iOS device. This app acts as an internet gateway for RSL10, also enables development and testing of mobile BLE app for the solution App-> Play Store or App Store
- Download and Install JLink Software and Documentation Pack must be installed and placed in the system’s PATH to
C:\Program Files (x86)\SEGGER\JLink_V644g
). Once this has been done, restarting the Atmosphere IoT Agent is required if it’s already running for the setting to take effect. - Set Simple Add to PATH Instructions according to this tutorial. If this step is not done correctly, Atmosphere Agent will not be able to flash the RSL10 board with the help of SEGGER JLink debugger/programmer.
- Segger JLink debugger/programmer is connected to the computer via USB and the RSL10-SENSE board is connected to Segger Jlink programmer with SWD ribbon cable like this :-
- Make sure that RSL10-SENSE board is powered on with LiPo battery through Vcc pin with a diode is series (to dropout the Vbatt below 3.6v) from the 5 pin connector.
- An Internet connection is maintained during the development of firmware for compiling and programming RSL10 board with cloud based Atmosphere Studio.
- Once the setup is completed correctly, open web browser on your computer and go to https://platform.atmosphereiot.com/
- Login with user id and password to open Atmosphere Studio on the web browser
- Download the attached zip file (Firmware) in the code section below, unzip it and you will get the RSL10 Hiking Tracker.atmo project file
- Click on the second icon from the left menu on Atmosphere Studio as shows in the picture below :-
- Click on Import project to import the atmo file you just downloaded and RSL10 Hiking Tracker project will load up on Atmosphere Studio like this :-
It may seem overwhelming at first, but things are not difficult.
There are 3 main tabs for each complete project. The first tab is the embedded tab (inside the top left red box with chip/IC icon + RSL10-SENSE-GEVK in cyan color ) where you build your firmware that goes into the flash memory of RSL10 mcu.
On the right hand side there is element toolbox. Elements are these graphical icon things that can perform certain stuffs which is a visual wrapper for reusable c codes/functions/libraries.
Elements can be dragged and dropped from the element toolbox to the studio canvas. One element is connected to it's next element with using a “connector.” Each element either triggers it's next element or passes a variable to it. Each element can be configured individually by clicking on it and on the right hand side of the studio that element's properties window. Most element will work with default configuration unless you need something specific.
Check out the next video to get the gist of it :-
Following elements are used in this project's embedded tab :-
- Sensor elements (green icons) are driver/libraries for BME680, NOA1305 and BHI 160 sensors used in this project.
- Interval element is a periodic timer that will trigger it's following elements repeatedly after a certain interval to do the same thing.
- Comparison element can compare an incoming variable with a pre-defined target value.
- Operation element can perform basic mathematical add/sub/mult/div operation on an incoming variable
- GPIO Pin element can drive a GPIO pin as input/output. Useful for controlling RSL10 Push button PB1, PB2 and the RGB LEDs
- BLE Gatt element can send data (value/variables/string) from hardware (RSL10) to Application over Bluetooth. BLE Gatt is a coupled element, meaning it creates a corresponding copy of it on the application tab to receive the incoming data on the app side. Selecting the right data type (integer/float/string) is very important for BLE Gatt element. For example temperature sensor will send float data, so Read/Write/Notify of BLE element that will transfer data to the app must be float type. Otherwise, temperature sensordata will not appear on the app.
- Function element is where you can write your own c code.
More details on element can be found here :
https://developer.atmosphereiot.com/documents/studioelements/usingstudioelements.html
So what's happening in the firmware ?
Interval elements are periodically triggering BME680, NOA1305 and BHI160 elements to fetch recent Temperature, Pressure, Humidity, Lux and Z-orientation data (derived from accelerometer & gyroscope of BHI160). Sensor data passed to BLE Gatt elements to send to the mobile app over Bluetooth. UV Index, Step Counts, Altitude is calculated with function elements and similarly sent to the app with BLE Gatt elements. Some comparison elements are checking the threshold for sensor data, if exceeded then the RGB LED is illuminated to indicate the event. Pushing button 2 can turn off all the LEDs. Both LED and Push button are controlled with GPIO pin elements,
Important : Save your project frequently and keep backups !
Writing your own C codes in Atmosphere IoTWhen all the elements provided in Atmosphere Studio can't do something complicated like calculating Altitude from Pressure Sensor data, then you have to write your own C code inside a function element.
First, drag and drop an empty function element from the element toolbox, give it an appropriate name (e.g. Altitude_Fn is a function element that calculates altitude), connect it to another element which will trigger or pass a variable to it. If a preceding element of this function element is just triggering it, a global variable can also be used to pass sensor data.
Next, click on the </> icon, this will open up the code editor window, there are thousand of lines of codes here ! But, don't worry, click on the function element icon, cursor will jump to that part of the code.
Altitude_Fn element's code on the code editor would look like this :-
How function element works ?
At first element will be an empty function like this:-
ATMO_Status_t functionname_trigger (ATMO_Value_t *in, ATMO_Value_t *out) {
return ATMO_Status_Success;
}
A function element can take input variable or data from it's preceding element, do some calculation then pass the result to the following element.
Function element can directly access any global variable. Otherwise a variable coming from preceding element and going to following element of that function element like this : -
ATMO_Status_t functionname_trigger (A TMO_Value_t *in, ATMO_Value_t *out) {
int i;
ATMO_CreateValueInt(in, i); // now i has incoming integer variable
/* your c code */
float o = i*3.1414/1.4145;
/******************/
ATMO_CreateValueInt(out, i); // function outputs the result float variable
return ATMO_Status_Success; // end of function
}
Pay attention to the proper data types:
ATMO_CreateValueInt for integers
ATMO_CreateValueFloat for floats
ATMO_CreateValueUnsignedInd for unsigned integers
Altitude functioncode
Earth's atmosphere is a sea of air which is fluid/gas that's why following formula holds true for air :-
Air Pressure = Air density * g_acceleration* Altitude, //(Height is the altitude!)
When the weather is stable, dry air has a constant density at standard temperature and pressure at sea level altitude. This air density changes with pressure, temperature (and humidity) and air density is inversely proportional altitude. Once you can figure out the air density from the sensor data, you can calculate altitude.
ATMO_Status_t Altitude_Fn_trigger(ATMO_Value_t *in, ATMO_Value_t *out) {
// float p_air = 1.225 air density at stp
// float Po = 1013.25 air pressure at stp
// float To = 15.0 air temperature at stp
// float g = 9.81 average grav acceleration
// you may use accelerometer for more accurate g measurement
// % of air density change with press change
float p_1 = 1.225*(101.325-(Pressure/1000))/100;
// % of air density change with temp change
float p_2 = 1.225*(15.0-Temperature)/300;
// applicable for temperature < 40 'C
float p_air = 1.225 - p_1 - p_2;
/*
for temperature above 40, humidity impacts air density significantly
additional coding is required to correct air density according to this curve
https://www.engineeringtoolbox.com/docs/documents/680/moist_air_density_temperature_relative_humidity.png
*/
// an offset to calibrate sensor w.r.t your location's altitude
float offset = 8.5;
Altitude = 0.0 +((101325-Pressure)/(p_air*9.81));
ATMO_CreateValueFloat(out, Altitude);
return ATMO_Status_Success;
}
UV Index function code
Outdoor lux level data is converted to watt per sq-meter, then 5% of that value is considered as UV energy and scaled between 0 to 10. This is not exactly the proper way to measure UV index but it can be improved by calibrating against a real UV sensor and tweaking some of the constants in the code below.
ATMO_Status_t UV_Index_Fn_trigger(ATMO_Value_t *in, ATMO_Value_t *out) {
int UV_Index = 0;
float temp = 0.0;
// convert Lux to W/m^2
temp = Lux * 0.0079;
// separate the UV component
temp = temp * 0.05;
// UV level increases by 10% per 1000m altitude increase
// uncomment the following codes for Altitude compentation for UV calc
/*
int alt1k = Altitude/1000;
if (alt1k>=1)
{
for (int i=0;i<alt1k;i++)
{
temp = temp + (temp*0.1);
}
}
*/
// convert to UV Index scale of 0 to 10
UV_Index = (temp/5.0);
ATMO_CreateValueInt(out, UV_Index);
return ATMO_Status_Success;
/*
Note : This is a crude approximation,
proper indexing requires UV sensor + additional info
*/
}
Step Counting code
Step counting works by measuring the (left) hand's swing. While walking, hand swings back and forth like a pendulum and creates a sine wave like periodic data pattern. Using accelerometer and gyroscope, hand's z-axis orientation is logged every 10 ms in an array. Every 100 ms the array gets filled up with 10 sets of data.
If there are two peaks in that data set (every 100 ms) and a dead band in between (1 minimum or 1 backward swing + 1 maximum or 1 forward swing), then it is considered as valid movement. Any other pattern generated from hand movement is discarded. By increasing/decreasing the dead band (difference between min and max), sensitivity/accuracy can be adjusted if needed.
ATMO_Status_t BHI160_zOrientation(ATMO_Value_t *in, ATMO_Value_t *out) {
ATMO_3dFloatVector_t data;
BHI160_GetData(NULL, NULL, &data);
ATMO_CreateValueFloat(out, data.z);
/*/////////simple step counter algo /////////
////////// using orientation data ///////////
//// orient = accel.vector + gyro.vector ////
///////////////////////////////////////////*/
static int hand_swing = 0;
Hand_positions[hand_swing] = data.z;
hand_swing ++;
if (hand_swing == 10)
{
hand_swing = 0;
for (int n=0; n<10 ;n++)
{
if (Hand_positions[n]< Hand_pos_min)
{
Half_swing ++; n=10;
}
}
for (int n=0; n<10 ;n++)
{
if (Hand_positions[n] > Hand_pos_max)
{
Half_swing ++; n=10;
}
}
if (Half_swing == 2)
{
Step_Counter ++; // fw half swing = 1 step
Step_Counter ++; // bw half swing = 1 step
}
Half_swing = 0;
}
return ATMO_Status_Success;
}
Patching up the AppThe second tab on Atmosphere Studio is the Applicationtab. Here is where drag and drop elements can be used to patch up your mobile application interface. App can show live data and act as an IoT Gateway.
- BLE Gatt elements from the firmware tab will have mirror copies. These BLE Gatt elements will receive data send from the hardware side.
- Label elements can show sensor data received from the hardware through BLE Gatt elements on the app.
- Interval elements can trigger its following elements periodically, this will decide how frequent the data is refreshed.
- Image elements will show an image/icon on the app interface.
- Cloud event element will receive a variable from its preceding element, send it to the Atmosphere IoT Cloud over internet.
- App layout can be adjusted from the left side app preview interface. It's simple drag and position.
This app will appear as an emulated app inside Atmosphere IoT app. But it is possible to have standalone app (White Label) and that option is not available for
free developer account
!
The third tab is the Cloud configuration tab on Atmosphere Studio. This is where you can setup what you want to do with the sensor data pushed from the mobile app to the Atmosphere Cloud.
Cloud Event elements from the Application tab will have thier mirror copies here. Each Cloud Event element will make each parameter/sensor data available to the cloud. Atmosphere IoT has Cloud Storage element which can store/save data send from hardware through mobile to the cloud. For free developer account, this limit is 10 MB or about 11500 data sets. Data can be downloaded as CSV files or deleted for new data.
If you want to use AWS, there are elements for doing that too !
- Turn on Bluetooth on your phone
- Run Atmosphere IoT app, login with your username/password
- Follow this video for provisioning instruction:
Demonstration of sensor data changes on the app :
Dashboard ViewDashboard is where you can view latest and historical sensor data with different kinds of cool widgets like data glance, dial, chart/graph etc.
All sensor data stored to Cloud Storage element is accessible to the dashboard.
You may configure/customize your dashboard view as you wish
Additional Resources- A long video about configuring the Atmosphere IoT Dashboard :
- Getting Started with RSL10
- https://atmosphereiot.com/blog/on-rsl10-support/
- Here is the official tutorial from Atmosphere IoT teamfor RSL10 :-
I named this project 'A watch with no Face' but I wish to add a watch face, probably an OLED display and time keeping features if possible. There is room for improvement in step counting and altitude calculation algorithm. Unfortunately, standard math.h library does not recognize ln(), exp(), pow() etc functions for float/double variables, so I had to stick to basic mathematical operators for calculations. UV measurement should be done with real UV sensor for more accurate indexing. If you already have a RSL10 sense board, feel free to make some improvements by yourself ! Good luck.
Comments