DISCLAIMER: This application is used for demonstrative and illustrative purposes only and does not constitute an offering that has gone through regulatory review. It is not intended to serve as a medical application. There is no representation as to the accuracy of the output of this application and it is presented without warranty.
IntroductionFor this contest I decided to change the way to approach IoT. This time instead of something theoretical or unproven, the end product has to be something designed for daily use, in this case something very useful for myself. Apart from that I want something with a huge market and preferably should be trending.
One aspect of my persona that I wish to share is that I'm kind of a meathead. I like to go lift weights and there is a series of products which are trending right now that have always dissappointed me....
Be it an activity band, fitness watch or a clip-on tracker – there's no shortage to choose from. Fitbit, Garmin, Xiaomi, Misfit and Polar are the leaders in the game, with bands to suit every budget and fitness level.
BUT most of them have two main problems. The first one is that most of them do a poor job for tracking weight training, the second one has to be in relation with the heart rate monitor they have. Most of them have the heart rate sensor on the back, big mistake, that area moves around a lot and not even the best sensor will make sense of what you are doing so you get faulty readings. In this case it is much better having the sensor on the side and just take sporadic reading or if you really need continuous reading a chest sensor is much better.
The second main problem is that they are not adapted to my workload which is mainly anaerobic, or hoisting weights.
Getting back to the project, lets check on the NXP prototyping kit:
So we have most of the needed sensors for a fitness tracker in the package: Motion sensors, environmental ones, a touch interface, a couple indicators and BLE.
Let's try and build a Fitness tracker with this, mainly focused on anaerobic exercise, but with aerobic capabilities as well (sometimes you have to do that dreaded cardio).
SolutionThe solution will be a small fitness tracker that monitors several aspects such as motion and environmental ones, and on the side I probably will add some other capabilities.
By re-engineering clinically validated technologies with new and out of the box IoT technologies like the NXP kit, the device will measure temperature and motion. The wearable will be powered by its own little battery and will wirelessly transmit health data to a central monitoring application which will help the user. You don't have to have all the sensors integrated into one project. I don't need to know light intensity to do my exercise.
A second wearable will be developed via the ESP8266 Node MCU board and it will track Heart rate and blood oxygenation via the MAX30100.
And just for fun I want a web-based dashboard and to be able to consult everything with Alexa.
This should be very fun, we will build two wearables and connect them together in a single platform.
We will have to build a case to transform the IoT kit into a watch.
I got into Autocad and designed the following "case" (files at the bottom):
After that I went to my local Laser Cutting provider and the resulting pieces are these:
For the heart rate wearable I want something different from a watch, so I'll re-purpose a sports Wrist wrap with the MAX30100, a little acryllic, a Node MCU ESP8266 board, and a 500 mAH Lipo battery.
Everything will be assembled with a couple screws and some straps and velcro. And some wire.
Now that we have a base to work from it's time to program everything in the IDE.
If you need help setting up you can follow the following guides on the NXP's Rapid IoT prototyping kit:
Now we can proceed, as previously stated we want to track both Temperature/humidity and Motion in terms of steps.
As of now, there are quite a lot of guides on how to develop your Rapid application but I will include several tips in order to proceed.
The temperature is quite straight forward just allocate this sensor form the list on the right:
Get it connected to a function node, an interval node, a BLE GATT node and an Emmbeded icon display node like so:
Now click on this icon (Code Editor one):
To get the label to read something redacted instead of just the numbers it gets try the next code by allocating it on the function node:
ATMO_Status_t Function_trigger(ATMO_Value_t *in, ATMO_Value_t *out) {
float temp = 0;
ATMO_GetFloat(in, &temp);
char str[32];
sprintf(str, "%.1f C", temp);
ATMO_CreateValueString(out, str);return ATMO_Status_Success;
}
Remember that you can get to the proper function code by clicking on the node while you are in the code editor.
Thats pretty much it for temperature, lets go for the tricky part with motion and steps.
Follow suit on building the flow just as in the one above but you will have to configure certain nodes.
Notice how this time we do not set up n interval to read the sensor.
Now for the configuration (this was quite tricky):
First configure the Accelerometer to detect motion.
Then go to the code editor and all the way to the top set up a new variable, mine is called "chido" and it should be a float.
Notice how it starts with 0 as we want to start anew every time we connect the sensor. Then go to the function node of that flow.
Input the following code:
ATMO_Status_t Func_trigger(ATMO_Value_t *in, ATMO_Value_t *out) {
float temp = 0;
ATMO_GetFloat(in, &temp);
char str[32];
chido = chido + 1;
sleep(300);
sprintf(str, "%.1f Steps", chido);
ATMO_CreateValueString(out, str);
return ATMO_Status_Success;
}
As you can see what this code does is set u a counter called "chido", whenever the sensor detects movement, then it "counts" that input and stores it. It is quite sensitive so I included a little delay. Then it simply sets the information to be properly displayed.
Here is a small test of the step counter:
Now to set up the cloud.
From here on you should have something similar or exactly like the next image in terms of the NXP Atmosphere IDE:
The application view is up to you, I did a very simplistic one just with my logo a meter gauge and to showcase the number of steps. The only caveat to this is that the BLE GATT modules should be configured like in the image included as they will receive and send this kind of variable.
The important part are those two cloud events nodes that you have to set up after the BLE GATT characteristics nodes.
Now for the most important part of the module, without this everything breaks down.
Get to the cloud view and grab two AWS dynamoDB nodes and connect them to the cloud events that are already there, and in turn grab a CloudStorage node.
Before continuing get to AWS and you'll have two tasks:
- Set an IAM role with the proper policies to give access to Atmosphere IDE to DynamoDB.
- Set a DynamoDB table to use.
Follow up on: https://developer.atmosphereiot.com/documents/guides/awsintegrationsetupguide.html
And follow up on the Dynamo DB guide to get your IAM role and policy needed, but there's a caveat. If you simulate the policy when following that guide, you might find yourself denied. But, here is a working DynamoDB politics JSON on behalf of your friend Edoliver:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "VisualEditor0",
"Effect": "Allow",
"Action": [
"dynamodb:BatchGetItem",
"dynamodb:BatchWriteItem",
"dynamodb:PutItem",
"dynamodb:DeleteItem",
"dynamodb:GetItem",
"dynamodb:Scan",
"dynamodb:Query",
"dynamodb:UpdateItem",
"dynamodb:UpdateTable"
],
"Resource": [
"arn:aws:dynamodb:*:*:table/*/index/*",
"arn:aws:dynamodb:YOURTABLE'S ARN, LOOK AMAZON,NOT LEAVING CREDENTIALS"
]
},
{
"Sid": "VisualEditor1",
"Effect": "Allow",
"Action": [
"dynamodb:ListGlobalTables",
"dynamodb:ListTables",
"dynamodb:ListBackups"
],
"Resource": "*"
}
]
}
With everything set then we go back to NXP studio and set up the DynamoDB nodes:
So we will be filling the DynamoDB table with three Apends: Variable, Value and units. This way we DO NOT need to erase a table element as it will be updating as long as your key is the same every time. Here I set it up to be 1 for Steps and 2 for temperature.
Then Save, compile, download the firmware, set up the NXP to mass storage and load the.bin file to it.
- Pro tip: Push the upper left side button AND the lower right one simultaneously. Wait till the LED blinks four times in green, and you have it now in mass storage without the reseting tool and all that.
You should be looking at the data in your app after provision and getting some flows into the DynamoDB table.
Again, as you can see if you keep your key the same, the data will just update.
Heart rate wearable DevelopmentThis is quite easy once you get a hang of the MAX30100 module.
If you have the green RCWL-0530, MAX30100 module, I know your pain. But here is the best solution in the whole internet. Instead of desoldering the SMD resistors like some sources say, just set some 4.7k Ohm pull-up resistors for the SDA and SCL pins. Always use 5V for VCC and you are set.
For this project you will need these libraries installed in Arduino IDE:
- PubSubClient: https://github.com/knolleary/pubsubclient
- ArduinoJSON: https://github.com/bblanchon/ArduinoJson
Just go to the library manager at Programs->Include Library->Manager.
MQTT setup
If you need help setting up the ESP8266 go to the official resource:
https://github.com/esp8266/Arduino
Also for setting up AWS IoT core in your ESP this is the best resource in the whole internet:
https://github.com/debsahu/ESP-MQTT-AWS-IoT-Core
A couple tips:
- Don't try to do an IAM Role from the start, thats a pain, everything can be managed from IoT Core.
- Start from IoT Core, go to Security and policies and do a policy with ALL the resources and all the permissions to start with.
- IoT Core does not work without Certifications so don't skip them, security is a serious business now. You need to keep them all when filling the "secrets" tab of the sketch.
I have provided both a simple sketch for the sensor and a more robust one for connecting to AWS IoT. (Both at the bottom).
The code is well commented, but having said that there are a couple things that need to be talked about.
Perhaps the most important line of code is:
Wire.begin(D1, D2); // sda, scl
You have to set these or eslse the sensor will not send anything as the I2C pins for the Wire library are others.
I set up a counter first declaring the variable outside the setups and loops just to count.
int counter=0;
Next I used this counter in this cycle:
void onBeatDetected()
{
Serial.println("Beat!");
counter=counter+1;
Serial.println(counter);
}
And on this one:
if (counter>=16)
{
counter=0;
Serial.println("Funciona?");
lastMillis = millis();
sendData();
}
As you can see that was to choose what value goes to the thing's shadow, instead of using other type of logic that will give us countless updates to the shadow.
If you allocated your credentials and set up properly the thing and the authentication the when opening the Serial you should see something like this:
As you can see we are counting each heart beat and then when it reaches 16 (which is an average of sensible information) it just send to the thing's shadow the last number.
Then I altered the code a little bit to get also the SpO2.
In the AWS IoT, Shadow you should see something like this:
Now for the next step:
IoT action to get the data to DynamoDB
To set up the Rule follow this guide.
https://docs.aws.amazon.com/iot/latest/developerguide/iot-ddb-rule.html
Just a couple more tips:
- Your AWT IoT thing is your topic!
- Sometimes when copied, the JSON may change format.
To set up the Rule properly fill the Rule query statement like so:
And remember that the partition key of the table indicates which variable I'm looking for so when making the rule take that into consideration, also the JSON sent from the ESP8266 had to be modified to fit this statement. (last modification in the code at the bottom). And Remember to test it beforehand in the test menu of the AWS IoT console. This time to update just a single element both of your keys have to be constant.
Or video evidence if you will:
So with all that we are quickly filling the Dynamo Table like so:
Integration with Alexa
I'm amazed to say that this is the easier part, we just have to interpret the dynamoDB tables with a Python lambda and use the Alexa development service.
Help yourselves to a great start by visiting: https://www.twitch.tv/amazonalexa/videos
There you can get several videos showcasing how to get an Alexa Skill running very quickly. You just need both an Alexa developer account and an AWS one for the lambda. I'll be running my example natively on JS so if you are running Python on a lambda then my code will not work. The JSON for the skill implementation works in any setting.
I would reccomend grabbing this code snippet for lambda and trying to play with it and come up with conversations like the one in the image:
If you won't bother just create a new skill and paste the implementation's JSON and create a JS lambda, integrate ASK and dynamoDB and paste also the lambda code. Remember to counter paste both ARNs, if you have some problems refer to my last link.
There is just a couple parts that need explaining.
- Try to always start with the implementation and designing a conversation first!
- Pro tip: theres a code generator when you have all your intents set up:
https://s3.amazonaws.com/webappvui/skillcode/v2/index.html
It works well but as you are using DynamoDB you'll have to put that part of the code by hand.
Here is a little snippet of how that works:
You need to have installed Node.JS and the proper libraries such as npm, and the Alexa skills kit, trust me, it is better to learn that way.
First you configure what is needed in terms of libraries and
exports.handler = function(event, context, callback) {
var alexa = Alexa.handler(event, context);
alexa.dynamoDBTableName = 'Your Table'; // creates new table for session.attributes
alexa.registerHandlers(handlers);
alexa.execute();
And then with this logic:
'Intent1': function() {
this.attributes['Your SLOT'] = this.event.request.intent.slots.Your SLOT.value;
this.emit(':ask', "Got it");
},
'Intent2: function() {
this.emit(':tell', "I remember that your SLOT is, " + this.attributes['Your SLOT']);
}
This way you can save even in a single element a lot of events and is much more compatible this way with AWS IoT and NXP studio.
When you are set get the necessary logos and documentations and run a Beta. Remember to invite yourself to it.
ApplicationWhat I need in the gym is for a device to keep track of my vitals and to record my PR's (personal records) and performance. What I did in the past was to get my spreadsheet from my cellphone and record everything there, and I didn't record any vitals. This should be much easier and faster.
So in summary I wanted;
- To record vitals such as heart rate, Temp and O2.
- Easier set up to record my PRs.
- Record motion (steps).
Let's see if the final product does that.
Afeter packing everything together it looks like this:
Demo and Showcase
Here we have a small demo of the final product, you can expand it as much as you would like with the tools presented here.
Comments and future rollout.
The Global Fitness Trackers Market size was valued at $17, 907 million in 2016, and is expected to reach $62, 128 million by 2023, registering a CAGR of 19.6% during the forecast period. A Fitness tracker is a device used to record and monitor fitness-related body activities such as steps taken, distance walked, sleep duration, heartbeat monitoring, and others. These devices are connected to the smartphone or computers via wireless connectivity mediums.*
This is a great approach to those that want to keep track of vitals and performance which neccesities have not been met by trackers nowadays. And a solution like this is much cheaper!
I wanted to go the route this time of smart fabrics in addition to the watch as I think this will be one of the biggest trends moving forward, as soon as IoT gets inside that world it's gonna be remarkably huge.
Future rollout
As soon as they release them I will immediatelly be making my own miniboard to connect the MAX30100. I already have the parts because that was my initial approach.
Perhaps in the future I will add many more functionalities, for now I am satisfied with this version as I had the opportunity to fully explore all the platform, from the Kit to the cloud and beyond. And the development of the other wearable was quite a difficult endeavour, and this guide provides most of what you need to upload any device to the AWS IoT platform.
One last thing: I strive to make this guides better every time, so please indicate any issues you are having, or any steps where you think I didn't explain something correctly. And if you liked it, leave a respect.
Thank you for reading!
References
*https://www.alliedmarketresearch.com/fitness-tracker-market
https://developer.atmosphereiot.com/documents/guides/awsintegrationsetupguide.html
http://blog.kilomon.com/2018/02/creating-alexa-skills-for-iot-and.html
https://github.com/debsahu/ESP-MQTT-AWS-IoT-Core
https://github.com/esp8266/Arduino
https://www.teachmemicro.com/max30100-arduino-heart-rate-sensor/
https://github.com/oxullo/Arduino-MAX30100
https://developer.atmosphereiot.com/documents/elements/awsdynamodbelement.html
Comments