diff --git a/apps/hrrawexp/ChangeLog b/apps/hrrawexp/ChangeLog new file mode 100644 index 000000000..0a32e06e6 --- /dev/null +++ b/apps/hrrawexp/ChangeLog @@ -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 diff --git a/apps/hrrawexp/README.md b/apps/hrrawexp/README.md index abf2d3d7c..caf7f9833 100644 --- a/apps/hrrawexp/README.md +++ b/apps/hrrawexp/README.md @@ -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. --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. - --The first item holds the data/time when the readings were taken and the file is reset each time the app is run. +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. +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: https://github.com/jabituyaben/BangleJS-HRM-Signal-Processing diff --git a/apps/hrrawexp/app.js b/apps/hrrawexp/app.js index f78d3fbf6..652feba5a 100644 --- a/apps/hrrawexp/app.js +++ b/apps/hrrawexp/app.js @@ -1,12 +1,25 @@ -var counter = 1; +var counter = 15; var logging_started; var interval; var value; +var filt; -var file = require("Storage").open("hrm_log.csv", "w"); -file.write(""); +var fileClosed = 0; +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() { g.clear(); @@ -33,47 +46,75 @@ function update_timer() { function btn1Pressed() { if (!logging_started) { - if (counter < 60) - counter += 1; + if (counter < 120) + counter += 15; else - counter = 1; + counter = 15; update_timer(); } } function btn3Pressed() { if (!logging_started) { - if (counter > 1) - counter -= 1; + if (counter > 15) + counter -= 15; else - counter = 60; + counter = 120; update_timer(); } } function btn2Pressed() { - launchtime = 0 | getTime(); - file.write(launchtime + "," + "\n"); - logging_started = true; - counter = counter * 60; - interval = setInterval(countDown, 1000); - Bangle.setHRMPower(1); + if (!logging_started) { + 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; + counter = counter * 60; + interval = setInterval(countDown, 1000); + Bangle.setHRMPower(1); + } } function fmtMSS(e) { - var m = Math.floor(e % 3600 / 60).toString().padStart(2, '0'), - s = Math.floor(e % 60).toString().padStart(2, '0'); - return m + ':' + s; + h = Math.floor(e / 3600); + e %= 3600; + m = Math.floor(e / 60); + s = e % 60; + return h + ":" + m + ':' + s; } function countDown() { g.clear(); counter--; - if (counter == 0) { + if (counter <= 0 && fileClosed == 0) { Bangle.setHRMPower(0); clearInterval(interval); g.drawString("Finished", g.getWidth() / 2, g.getHeight() / 2); Bangle.buzz(500, 1); + fileClosed = 1; } else 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(btn3Pressed, BTN3, { repeat: true }); -Bangle.on('HRM', function (hrm) { - for (let i = 0; i < hrm.raw.length; i++) { - value = hrm.raw[i]; - if (value < -2) - value = -2; - if (value > 6) - value = 6; - file.write(value + "," + "\n"); - } +Bangle.on('HRM-raw', function (hrm) { + value = hrm.raw; + filt = hrm.filt; + file.write(value + "," + filt + "," + "\n"); }); diff --git a/apps/hrrawexp/metadata.json b/apps/hrrawexp/metadata.json index 3920731aa..7df0f450b 100644 --- a/apps/hrrawexp/metadata.json +++ b/apps/hrrawexp/metadata.json @@ -2,7 +2,7 @@ "id": "hrrawexp", "name": "HRM Data Exporter", "shortName": "HRM Data Exporter", - "version": "0.01", + "version": "0.03", "description": "export raw hrm signal data to a csv file", "icon": "app-icon.png", "tags": "",