forked from FOSS/BangleApps
commit
d7756ee175
|
@ -0,0 +1,3 @@
|
||||||
|
0.01: New App!
|
||||||
|
0.02: Fixes
|
||||||
|
0.03: updated to work with new API and additional features added such as longer recording time and additional filtered data
|
|
@ -3,11 +3,11 @@ Extract hrm raw signal data to CSV file
|
||||||
|
|
||||||
Simple app that will run the heart rate monitor for a defined period of time you set at the start.
|
Simple app that will run the heart rate monitor for a defined period of time you set at the start.
|
||||||
|
|
||||||
-The app creates a csv file (it's actually just 1 column) and you can download this via My Apps in the App Loader.
|
Updated to work with new API. Additional capability includes:
|
||||||
|
|
||||||
-The max time value is 60 minutes.
|
1. Now also records upto 2 hours - if you cancel at any time the CSV file will still be there, the timer you set at the start is more so that you get an alert when it's complete.
|
||||||
|
2. Along with raw PPG readings, it also records bandpassed filtered data in a second column, available in the new API.
|
||||||
-The first item holds the data/time when the readings were taken and the file is reset each time the app is run.
|
3. Rather than overwriting 1 data file, the app will record upto 5 files before recording to a generic data file as a fallback if all 5 allocated files remain on the watch storage. The limit is in place to avoid going over storage limits as these files can get large over time.
|
||||||
|
|
||||||
-The hrm sensor is sampled @50Hz and this app does not do any processing on it other than clip overly high/extreme values, the array is written as-is. There is an example Python script that can process this signal, smooth it and also extract a myriad of heart rate variability metrics using the hrvanalysis library:
|
-The hrm sensor is sampled @50Hz and this app does not do any processing on it other than clip overly high/extreme values, the array is written as-is. There is an example Python script that can process this signal, smooth it and also extract a myriad of heart rate variability metrics using the hrvanalysis library:
|
||||||
https://github.com/jabituyaben/BangleJS-HRM-Signal-Processing
|
https://github.com/jabituyaben/BangleJS-HRM-Signal-Processing
|
||||||
|
|
|
@ -1,12 +1,25 @@
|
||||||
var counter = 1;
|
var counter = 15;
|
||||||
var logging_started;
|
var logging_started;
|
||||||
var interval;
|
var interval;
|
||||||
var value;
|
var value;
|
||||||
|
var filt;
|
||||||
|
|
||||||
var file = require("Storage").open("hrm_log.csv", "w");
|
var fileClosed = 0;
|
||||||
file.write("");
|
var Storage = require("Storage");
|
||||||
|
var file;
|
||||||
|
|
||||||
file = require("Storage").open("hrm_log.csv", "a");
|
function exists(name){
|
||||||
|
s = require('Storage');
|
||||||
|
var fileList = s.list();
|
||||||
|
var fileExists = false;
|
||||||
|
for (let i = 0; i < fileList.length; i++) {
|
||||||
|
fileExists = fileList[i].includes(name);
|
||||||
|
if(fileExists){
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return fileExists;
|
||||||
|
}
|
||||||
|
|
||||||
function update_timer() {
|
function update_timer() {
|
||||||
g.clear();
|
g.clear();
|
||||||
|
@ -33,47 +46,75 @@ function update_timer() {
|
||||||
|
|
||||||
function btn1Pressed() {
|
function btn1Pressed() {
|
||||||
if (!logging_started) {
|
if (!logging_started) {
|
||||||
if (counter < 60)
|
if (counter < 120)
|
||||||
counter += 1;
|
counter += 15;
|
||||||
else
|
else
|
||||||
counter = 1;
|
counter = 15;
|
||||||
update_timer();
|
update_timer();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function btn3Pressed() {
|
function btn3Pressed() {
|
||||||
if (!logging_started) {
|
if (!logging_started) {
|
||||||
if (counter > 1)
|
if (counter > 15)
|
||||||
counter -= 1;
|
counter -= 15;
|
||||||
else
|
else
|
||||||
counter = 60;
|
counter = 120;
|
||||||
update_timer();
|
update_timer();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function btn2Pressed() {
|
function btn2Pressed() {
|
||||||
launchtime = 0 | getTime();
|
if (!logging_started) {
|
||||||
file.write(launchtime + "," + "\n");
|
var filename = "";
|
||||||
|
var fileset = false;
|
||||||
|
|
||||||
|
for (let i = 0; i < 5; i++) {
|
||||||
|
filename = "HRM_data" + i.toString() + ".csv";
|
||||||
|
if(exists(filename) == 0){
|
||||||
|
file = require("Storage").open(filename,"w");
|
||||||
|
console.log("creating new file " + filename);
|
||||||
|
fileset = true;
|
||||||
|
}
|
||||||
|
if(fileset){
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!fileset){
|
||||||
|
console.log("overwiting file");
|
||||||
|
file = require("Storage").open("HRM_data.csv","w");
|
||||||
|
}
|
||||||
|
|
||||||
|
file.write("");
|
||||||
|
file = require("Storage").open(filename,"a");
|
||||||
|
|
||||||
|
//launchtime = 0 | getTime();
|
||||||
|
//file.write(launchtime + "," + "\n");
|
||||||
logging_started = true;
|
logging_started = true;
|
||||||
counter = counter * 60;
|
counter = counter * 60;
|
||||||
interval = setInterval(countDown, 1000);
|
interval = setInterval(countDown, 1000);
|
||||||
Bangle.setHRMPower(1);
|
Bangle.setHRMPower(1);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function fmtMSS(e) {
|
function fmtMSS(e) {
|
||||||
var m = Math.floor(e % 3600 / 60).toString().padStart(2, '0'),
|
h = Math.floor(e / 3600);
|
||||||
s = Math.floor(e % 60).toString().padStart(2, '0');
|
e %= 3600;
|
||||||
return m + ':' + s;
|
m = Math.floor(e / 60);
|
||||||
|
s = e % 60;
|
||||||
|
return h + ":" + m + ':' + s;
|
||||||
}
|
}
|
||||||
|
|
||||||
function countDown() {
|
function countDown() {
|
||||||
g.clear();
|
g.clear();
|
||||||
counter--;
|
counter--;
|
||||||
if (counter == 0) {
|
if (counter <= 0 && fileClosed == 0) {
|
||||||
Bangle.setHRMPower(0);
|
Bangle.setHRMPower(0);
|
||||||
clearInterval(interval);
|
clearInterval(interval);
|
||||||
g.drawString("Finished", g.getWidth() / 2, g.getHeight() / 2);
|
g.drawString("Finished", g.getWidth() / 2, g.getHeight() / 2);
|
||||||
Bangle.buzz(500, 1);
|
Bangle.buzz(500, 1);
|
||||||
|
fileClosed = 1;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
g.drawString(fmtMSS(counter), g.getWidth() / 2, g.getHeight() / 2);
|
g.drawString(fmtMSS(counter), g.getWidth() / 2, g.getHeight() / 2);
|
||||||
|
@ -85,13 +126,8 @@ setWatch(btn1Pressed, BTN1, { repeat: true });
|
||||||
setWatch(btn2Pressed, BTN2, { repeat: true });
|
setWatch(btn2Pressed, BTN2, { repeat: true });
|
||||||
setWatch(btn3Pressed, BTN3, { repeat: true });
|
setWatch(btn3Pressed, BTN3, { repeat: true });
|
||||||
|
|
||||||
Bangle.on('HRM', function (hrm) {
|
Bangle.on('HRM-raw', function (hrm) {
|
||||||
for (let i = 0; i < hrm.raw.length; i++) {
|
value = hrm.raw;
|
||||||
value = hrm.raw[i];
|
filt = hrm.filt;
|
||||||
if (value < -2)
|
file.write(value + "," + filt + "," + "\n");
|
||||||
value = -2;
|
|
||||||
if (value > 6)
|
|
||||||
value = 6;
|
|
||||||
file.write(value + "," + "\n");
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
"id": "hrrawexp",
|
"id": "hrrawexp",
|
||||||
"name": "HRM Data Exporter",
|
"name": "HRM Data Exporter",
|
||||||
"shortName": "HRM Data Exporter",
|
"shortName": "HRM Data Exporter",
|
||||||
"version": "0.01",
|
"version": "0.03",
|
||||||
"description": "export raw hrm signal data to a csv file",
|
"description": "export raw hrm signal data to a csv file",
|
||||||
"icon": "app-icon.png",
|
"icon": "app-icon.png",
|
||||||
"tags": "",
|
"tags": "",
|
||||||
|
|
Loading…
Reference in New Issue