I needed to implement the last sensors and outputs for the Nicla Sense ME.
1) Heat Index Formula changes and improvement
![](https://static.wixstatic.com/media/4b820e_ae2edce746ab4c26b14228e8af347e3e~mv2.png/v1/fill/w_980,h_230,al_c,q_85,usm_0.66_1.00_0.01,enc_auto/4b820e_ae2edce746ab4c26b14228e8af347e3e~mv2.png)
The main documentation can be found here: https://www.wpc.ncep.noaa.gov/html/heatindex_equation.shtml
The heat index formula has specific adjustements that need to be used in specific cases, so I have implemented a decision tree containing all the different changes.
If the temperature is lower than 4 degrees Celsius, then the heat index cannot be used anymore as the temperature represents the accurate value.
2) Cloud Formulas changes:
float cloud_base_altitude_groundlevel = (temperature_regressed_fusion - air_dew_point) * 124.6;
float cloud_base_altitude_sealevel = cloud_base_altitude_groundlevel + altitude;
float cloud_base_temperature = - 0.00182 * cloud_base_altitude_groundlevel + air_dew_point;
These new formulas provide more accurate outputs. The reference is here: https://holfuy.com/en/support/cloud-base-calculations
3) Get Activity Function
The Nicla has a function that uses the IMU with a built in ML classifier to identify the type of activity that is being performed.
Here is a video demonstration:
This function will be used to check if the user is moving during the Heart Rate reading, which is the most accurate, when the person is standing still.
4) Wrist Flick Gesture
The watch will be activated with a wrist flick gesture. The Nicla Sense ME, uses a specialised ML model with the IMU to check for specific gestures.
Although there is no documentation, through testing, I have found out the actual gesture in order to activate the event, is the movement of the arm from horizontal to the body, up, and then a wrist flick. In that specific order.
Here is a demo video:
5) Heart Rate implementation of the DFRobot Gravity
And here it is implemented on the Nicla Sense ME:
We can see the heart rate is very accurate, in fact is as accurate as the finger oximeter device.
The way it works, is that it uses an Exponentially Moving Average with 10 values, and if the values do not have a big difference, then it outputs the value as the heartrate.
6) GUVA UV Index
The sensor that I am using the detect the visible light, infrared light and UV index, is the Adafruit SI1145. However, this sensor creates an estimated UV index based on the visible and infrared light.
In order to make sure that the values are correct, I have used the Guva UV Index sensor, which outputs the actual UV index as an analog.
Here is a demo tested outside:
And I have also tested the sensor while it being covered by a metal coffee filter, which is what will be around the edge of the final casing/shell.
![](https://static.wixstatic.com/media/4b820e_e45f4e833f1044ca9097f96c0ac53694~mv2.jpg/v1/fill/w_980,h_1198,al_c,q_85,usm_0.66_1.00_0.01,enc_auto/4b820e_e45f4e833f1044ca9097f96c0ac53694~mv2.jpg)
However, as expected, the holes are too small, and the sensor needs a full opening.
7) MLX Laser Skin Temperature
The watch is able to use an MLX I2C sensor to get the temperature of an object. In this case, I will be using it to measure the temperature of the skin, while the watch is on the wrist.
The laser has the most accurate reading when the object is at 5cm away (as per datasheet).
So the way to get it to be accurate, is by substracting 3.5 degrees.
float laser_skin_temp = mlx.readObjectTempC() - 3.5;
![](https://static.wixstatic.com/media/4b820e_45aacb2ffb49458f9f29bb3bfc9fa3f9~mv2.jpg/v1/fill/w_980,h_1741,al_c,q_85,usm_0.66_1.00_0.01,enc_auto/4b820e_45aacb2ffb49458f9f29bb3bfc9fa3f9~mv2.jpg)
8) Step Counter
The Nicla with the IMU can be used to count the number of steps, thanks to the implemented algorithm.
And by testing the algortihm is quite accurate.
#include "Arduino_BHY2.h"
#include "Nicla_System.h"
Sensor steps(SENSOR_ID_STC);
void setup() {
nicla::begin();
Serial.begin(9600);
BHY2.begin();
steps.begin();
}
void loop() {
unsigned long last_steps = steps.value();
while (Serial.available() > 0) {
char incomingCharacter = Serial.read();
if (incomingCharacter == '1') {
BHY2.update();
unsigned long total_steps = steps.value();
unsigned long current_steps = total_steps - last_steps;
Serial.println(String("Total Steps: ") + total_steps);
Serial.println(String("Current Run Steps: ") + String(current_steps));
delay(10);
break;
}
}
}
9) Step to Distance calculation
![](https://static.wixstatic.com/media/4b820e_ec14d2c182e44717bf4ec2bd020ea432~mv2.png/v1/fill/w_973,h_874,al_c,q_90,enc_auto/4b820e_ec14d2c182e44717bf4ec2bd020ea432~mv2.png)
![](https://static.wixstatic.com/media/4b820e_2afc8c7cde6f40dba851b6579496d6f9~mv2.png/v1/fill/w_690,h_678,al_c,q_90,enc_auto/4b820e_2afc8c7cde6f40dba851b6579496d6f9~mv2.png)
![](https://static.wixstatic.com/media/4b820e_cbb9d4a290c7438db44be95ec5b098c9~mv2.png/v1/fill/w_713,h_766,al_c,q_90,enc_auto/4b820e_cbb9d4a290c7438db44be95ec5b098c9~mv2.png)
By using the average weight and height, I can convert the steps to kilometers and meters for my system to output. An estimation.
uint32_t distance_travelled = (current_steps / 1179) * 1000;
10) Steps to Kilocalories and Kilojouls Burnt
The system uses the same average height and weight, in order to get the kilocalories burnt and kilojouls of energy.
![](https://static.wixstatic.com/media/4b820e_5b388c154c6d446bafb60319f3a26f78~mv2.png/v1/fill/w_980,h_635,al_c,q_90,usm_0.66_1.00_0.01,enc_auto/4b820e_5b388c154c6d446bafb60319f3a26f78~mv2.png)
![](https://static.wixstatic.com/media/4b820e_c425868b9b2749f3b06dd53ce2c4e61f~mv2.png/v1/fill/w_669,h_269,al_c,q_85,enc_auto/4b820e_c425868b9b2749f3b06dd53ce2c4e61f~mv2.png)
![](https://static.wixstatic.com/media/4b820e_d64184a6c5ed4b00a4d83983e4b1b049~mv2.png/v1/fill/w_449,h_777,al_c,q_85,enc_auto/4b820e_d64184a6c5ed4b00a4d83983e4b1b049~mv2.png)
Code:
unsigned long total_steps = steps.value();
unsigned long current_steps = total_steps - last_steps;
uint16_t kilocalories = current_steps * 0.03344;
uint16_t kilojouls = kilocalories * 4.184;
All the outputs from the Nicla Sense ME:
![](https://static.wixstatic.com/media/4b820e_d2d25bfce3884eacb66a72793c3dd485~mv2.png/v1/fill/w_840,h_961,al_c,q_90,enc_auto/4b820e_d2d25bfce3884eacb66a72793c3dd485~mv2.png)
Comentários