From 2f080d5f3a0730f29969ce32be6c06f9370960b4 Mon Sep 17 00:00:00 2001 From: Elfreda Kwawu <82907149+ekwawu@users.noreply.github.com> Date: Wed, 3 Apr 2024 11:21:54 -0400 Subject: [PATCH 01/52] Create app.js for phystrax --- apps/phystrax/app.js | 113 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 113 insertions(+) create mode 100644 apps/phystrax/app.js diff --git a/apps/phystrax/app.js b/apps/phystrax/app.js new file mode 100644 index 000000000..4576a9114 --- /dev/null +++ b/apps/phystrax/app.js @@ -0,0 +1,113 @@ +let isMeasuring = false; +let currentHeartRate = null; +let lcdTimeout; +let logData = []; + +function startMeasure() { + isMeasuring = true; + Bangle.setLCDTimeout(0); + lcdTimeout = setTimeout(() => { + Bangle.setLCDTimeout(50); + }, 50000); + + setTimeout(() => { + Bangle.setHRMPower(1); + Bangle.on('HRM', handleHeartRate); + Bangle.beep(400, 1000); // Buzz to indicate measurement start + drawScreen(); + }, 500); +} + +function stopMeasure() { + isMeasuring = false; + clearTimeout(lcdTimeout); + Bangle.setLCDTimeout(10); + Bangle.setHRMPower(0); + Bangle.removeAllListeners('HRM'); + saveDataToCSV(); // Save data to CSV when measurement stops + Bangle.beep(400, 800); // Buzz to indicate measurement stop + drawScreen(); +} + +function handleHeartRate(hrm) { + if (hrm.confidence > 90) { + currentHeartRate = hrm.bpm; + var date = new Date(); + var dateStr = require("locale").date(date); + var timeStr = require("locale").time(date, 1); + var timestamp = dateStr + " " + timeStr; // Concatenate date and time + logData.push({ timestamp: timestamp, heartRate: currentHeartRate }); + drawScreen(); + } +} + + +function drawScreen(message) { + g.clear(); // Clear the display + + // Set the background color + g.setColor('#95E7FF'); + + // Fill the entire display with the background color + g.fillRect(0, 0, g.getWidth(), g.getHeight()); + + // Set font and alignment for drawing text + g.setFontAlign(0, 0); + g.setFont('Vector', 15); + + // Draw the title + g.setColor('#000000'); // Set text color to black + g.drawString('Heart Rate Monitor', g.getWidth() / 2, 10); + + if (isMeasuring) { + // Draw measuring status + g.setFont('6x8', 2); + g.drawString('Measuring...', g.getWidth() / 2, g.getHeight() / 2 - 10); + + // Draw current heart rate if available + g.setFont('6x8', 4); + if (currentHeartRate !== null) { + g.drawString(currentHeartRate.toString(), g.getWidth() / 2, g.getHeight() / 2 + 20); + g.setFont('6x8', 1.6); + g.drawString(' BPM', g.getWidth() / 2 + 42, g.getHeight() / 2 + 20); + } + + // Draw instructions + g.setFont('6x8', 1.5); + g.drawString('Press button to stop', g.getWidth() / 2, g.getHeight() / 2 + 42); + } else { + // Draw last heart rate + g.setFont('Vector', 12); + g.drawString('Last Heart Rate:', g.getWidth() / 2, g.getHeight() / 2 - 20); + if (currentHeartRate !== null && currentHeartRate > 0) { + g.setFont('6x8', 4); + g.drawString(currentHeartRate.toString(), g.getWidth() / 2, g.getHeight() / 2 + 10); + } else { + g.setFont('6x8', 2); + g.drawString('No data', g.getWidth() / 2, g.getHeight() / 2 + 10); + g.setFont('6x8', 1); + g.drawString(message || 'Press button to start', g.getWidth() / 2, g.getHeight() / 2 + 30); + } + } + + // Update the display + g.flip(); +} + +function saveDataToCSV() { + let csvContent = "Timestamp,Heart Rate\n"; + logData.forEach(entry => { + csvContent += `${entry.timestamp},${entry.heartRate}\n`; + }); + require("Storage").write("heart_rate_data.csv", csvContent); +} + +setWatch(function() { + if (!isMeasuring) { + startMeasure(); + } else { + stopMeasure(); + } +}, BTN1, { repeat: true, edge: 'rising' }); + +drawScreen(); From 53e3fb49825b9f5625b403be94b588013616f5db Mon Sep 17 00:00:00 2001 From: Elfreda Kwawu <82907149+ekwawu@users.noreply.github.com> Date: Wed, 3 Apr 2024 11:31:10 -0400 Subject: [PATCH 02/52] Create app-icon.js --- apps/phystrax/app-icon.js | 1 + 1 file changed, 1 insertion(+) create mode 100644 apps/phystrax/app-icon.js diff --git a/apps/phystrax/app-icon.js b/apps/phystrax/app-icon.js new file mode 100644 index 000000000..46faf7ecc --- /dev/null +++ b/apps/phystrax/app-icon.js @@ -0,0 +1 @@ +require("heatshrink").decompress(atob("mUywZC/AB9JkmQA4mSpMgCAsCCIILBCIoIBoARIEwYRDAQI1FBYdIgESBAoRChIIEAQIsFIIcBCIwCIwEACJ5fCBAkgChRTGMQw4FQApQLBYtAggRJpA+MARZKLRLDdHKBUEZY4CGyEJkEQcwOQX5hKBAQI7BBw9BGoUAEYJKBAoIjHUIUggAmCTAKGDFgQOCAAMCgIgBYQIFBBYawCR4IABGoMCOIOQhEEBYaPDXIhxBiQjCOgQCBHYJTDyA1BwAmCOIwpEBwIsBEwNANARcEEAIFCKYJNBAoLsHRgxHCZAxiFBAb+JAALRFI4puDAARlFUIRuGHA+CCIy/DHAwCHCIgyIQAwADTAYRNTA6SGAAo4ICJCkMAAzdBUhIAGL4tICJSGFCJsAhLIHABQRRQwLaFABbaGAFAA==")) From 2fef0c63782a35a888e54e964c0b56ab3afbe484 Mon Sep 17 00:00:00 2001 From: Elfreda Kwawu <82907149+ekwawu@users.noreply.github.com> Date: Wed, 3 Apr 2024 11:41:36 -0400 Subject: [PATCH 03/52] Create metadata.json --- apps/phystrax/metadata.json | 15 +++++++++++++++ 1 file changed, 15 insertions(+) create mode 100644 apps/phystrax/metadata.json diff --git a/apps/phystrax/metadata.json b/apps/phystrax/metadata.json new file mode 100644 index 000000000..589da2e59 --- /dev/null +++ b/apps/phystrax/metadata.json @@ -0,0 +1,15 @@ +{ "id": "phystrax", + "name": "PhysTrax App", + "shortName":"PhysTrax", + "version":"0.01", + "description": "Tracking physiological measurements to support acticve learning in classrooms", + "icon": "app.png", + "tags": "", + "supports" : ["BANGLEJS2"], + "readme": "README.md", + "interface": "interface.html", + "storage": [ + {"name":"heartrate.app.js","url":"app.js"}, + {"name":"heartrate.img","url":"app-icon.js","evaluate":true} + ] +} From 19fa4a94b6369de282ed8460488175e9592c4049 Mon Sep 17 00:00:00 2001 From: Elfreda Kwawu <82907149+ekwawu@users.noreply.github.com> Date: Wed, 3 Apr 2024 11:45:34 -0400 Subject: [PATCH 04/52] Create interface.html --- apps/phystrax/interface.html | 65 ++++++++++++++++++++++++++++++++++++ 1 file changed, 65 insertions(+) create mode 100644 apps/phystrax/interface.html diff --git a/apps/phystrax/interface.html b/apps/phystrax/interface.html new file mode 100644 index 000000000..4e048b686 --- /dev/null +++ b/apps/phystrax/interface.html @@ -0,0 +1,65 @@ + + + + + +
+ + + + + + + From 16f3ec337fd09ac59d58ec43e6b0d8129fb3000a Mon Sep 17 00:00:00 2001 From: Elfreda Kwawu <82907149+ekwawu@users.noreply.github.com> Date: Wed, 3 Apr 2024 11:57:00 -0400 Subject: [PATCH 05/52] Update metadata.json --- apps/phystrax/metadata.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/phystrax/metadata.json b/apps/phystrax/metadata.json index 589da2e59..646d51eb8 100644 --- a/apps/phystrax/metadata.json +++ b/apps/phystrax/metadata.json @@ -10,6 +10,6 @@ "interface": "interface.html", "storage": [ {"name":"heartrate.app.js","url":"app.js"}, - {"name":"heartrate.img","url":"app-icon.js","evaluate":true} + {"name":"app.png","url":"app-icon.js","evaluate":true} ] } From 331e143e0af4f87ed6fbf1c423bf1559056f5432 Mon Sep 17 00:00:00 2001 From: Elfreda Kwawu <82907149+ekwawu@users.noreply.github.com> Date: Wed, 3 Apr 2024 11:57:17 -0400 Subject: [PATCH 06/52] Update metadata.json --- apps/phystrax/metadata.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/phystrax/metadata.json b/apps/phystrax/metadata.json index 646d51eb8..ee97cb1b0 100644 --- a/apps/phystrax/metadata.json +++ b/apps/phystrax/metadata.json @@ -2,7 +2,7 @@ "name": "PhysTrax App", "shortName":"PhysTrax", "version":"0.01", - "description": "Tracking physiological measurements to support acticve learning in classrooms", + "description": "Tracking physiological measurements to support active learning in classrooms", "icon": "app.png", "tags": "", "supports" : ["BANGLEJS2"], From 83437f6e3933a0edcd9dac4f5876ffcf145172b4 Mon Sep 17 00:00:00 2001 From: Elfreda Kwawu <82907149+ekwawu@users.noreply.github.com> Date: Wed, 3 Apr 2024 12:01:57 -0400 Subject: [PATCH 07/52] Create README.md --- apps/phystrax/README.md | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100644 apps/phystrax/README.md diff --git a/apps/phystrax/README.md b/apps/phystrax/README.md new file mode 100644 index 000000000..ca8df74b7 --- /dev/null +++ b/apps/phystrax/README.md @@ -0,0 +1,8 @@ +# CapstoneWearable +Research has shown that active learning approaches in classrooms, which emphasize the construction of knowledge and reflection on the learning process, significantly enhance the student learning experience and lead to better success in the classroom. The Active Learning Initiative at the University of Georgia focuses on instructor development, student engagement, and classroom enhancement. + +This project focuses specifically on classroom enhancement to create a device that will enhance the learning experience of students in physiology classes by allowing them to learn about and analyze their physiological patterns. The project must adhere to the constraints of a one-hundred dollar per watch budget, the ability to be scaled to a classroom of three-hundred twenty students, and provide data with at least 80% accuracy. By giving students access to their heart rate (HR) and heart rate variability (HRV) data, the goal is that students can better understand the function of the heart as well as the physiological conditions that can be affected by the heart. The original concept was to develop a wrist-wearable, screen-less device featuring sensors that detect a user’s heart rate by emitting LEDs that detect the expansion of blood vessels in the wrist and the quantity of light transmitted in the vascular bed to obtain heart rate and blood oxygen data and the heart rate variability calculated using an algorithm that takes the root-mean-square of interbeat intervals between successive heartbeats. + +After prototyping this custom device and testing its efficacy, the accuracy of the data produced by the sensor was not within the accuracy criteria, and the decision was made to pivot to an existing on-market device coupled with custom software to meet the needs of the client. The analysis software created for the device allows the students to analyze their physiological data and permits for their instructor to access their data anonymously. The data, coupled with survey data entered by the students daily, provides insight into the effect of variables such as sleep, exercise, and caffeine intake to analyze the effects that these have on their physiological measurements. To evaluate the device's efficacy in achieving the goal of 80% accuracy, the wrist wearable device was tested on several different skin tones doing various activities and measuring data over varying intervals and then compared against the data of Apple Watches. + +This project resulted in the creation of a custom data analysis software for the use of students on a Bangle.js smartwatch device that can be continually developed in the future to reach the goal of an inexpensive, easy-to-use device for students to use in active learning classrooms to enhance their understanding of physiology by analyzing their own physiological data in class. From 2f6a6dc906fcbf953a2e175d47ef97963fad8a59 Mon Sep 17 00:00:00 2001 From: Elfreda Kwawu <82907149+ekwawu@users.noreply.github.com> Date: Wed, 3 Apr 2024 12:05:27 -0400 Subject: [PATCH 08/52] Add files via upload --- apps/phystrax/app.png | Bin 0 -> 1299 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 apps/phystrax/app.png diff --git a/apps/phystrax/app.png b/apps/phystrax/app.png new file mode 100644 index 0000000000000000000000000000000000000000..5fd69c6de8f3e7b00e4eb089a4e933d80116a6bf GIT binary patch literal 1299 zcmV+u1?>8XP)YDOK64;+c;hzlVG5|xa)NkqrN3F+y3E3xEM zZnc%3p6T25NDVRviiWPLbMJS~x#ygFyFG7S=4D=TOM|@8kWXoHj{){;azc}#CjZdD zH=5iL`u^HzVBic_ozd#mXNKehntWB0qp>c=Iw$NHGFE>h2yVy?5CZoa@;gIDP8V=U zEA>be1Pf;aFu6dU@4e!4g6iSUPF$x4Ksv(&W%75Fv0^4rRmQO$~fh1x)Ds zYyR^FIhq6HA?wji6?x_BlPQtBE{~!{5Zo+!j8e<005LKLrLOl3xh1nTfTKzAi-O=> z4IHls<_RxPY-?a7z19qHpb8L8ekg;`x1Xsi$3y|F^>3y^?m@~>$+fWb(qOQaH)0t5Ugq4mDQ!*8crna?fAa~9-rt8A&g zKQirorS7oLt}4kRL!$hdPTr8BnF84$-!}l*$-Qfz+hn_h9W6Qzil^dQ<9Q1V`Ev;% z+r5yy$Hg0xnc_9Ee*O8|~#}le@6FW^8ek5KCDqjDW@Voo(_tRjXYs@5I^C_m_7Xw_d9)=>T1q zuEGt%_gC5l|E2}FptWn3MV@4_W~%}WCR<#Yyg(%DOq0*Lj9u>lVt{wj*1pX#7AGaN zn(wvrX_9`^;npBkJaO^``^?tZ0KUH_+PLu?o8`WkDYWXf+7gGegE&f>qJfW{V1NxN z1H6~MCk4@dze|%xqRpGnl2emrtpW}u3qKyy_aDx+$br4>!e_aoS3XO5WUS?WT;b(Y zyby;KsoGgkwy9FcGDDF6O!G#{!f!cP;Y3K@Dd$XW?(dF6N2y*}7gpzB%LIm^Ah@{I zn_XYP&KVb$WT9>j&e|wH5bIgD?(FyzSS*<<*M!;Dn1?%_Z;7R|Zjh2zCFSA%5+IIC zwwx6rHG#)652n8G7^turZypqvkajPQzRpH(sU+)ScwrCJ6wAH-Z!G@#W z-b)>u(Qfp<(amZ9sW2xC)@y}_M+Q$ssrr*026(ALi0!!{(ju`hTguZ2(2&aSl_8S$ zH2M2!fH>mP8Rrt&muTS2(jb75WUo`Y*hX+$ktd5**T8H)+m$9psoM?kQvo1j$-cfa ziO+n=mu)wi1!8y9({qtGS0q&G{%+35 Date: Wed, 3 Apr 2024 12:08:42 -0400 Subject: [PATCH 09/52] Update metadata.json --- apps/phystrax/metadata.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/phystrax/metadata.json b/apps/phystrax/metadata.json index ee97cb1b0..f23405aed 100644 --- a/apps/phystrax/metadata.json +++ b/apps/phystrax/metadata.json @@ -4,7 +4,7 @@ "version":"0.01", "description": "Tracking physiological measurements to support active learning in classrooms", "icon": "app.png", - "tags": "", + "tags": "health", "supports" : ["BANGLEJS2"], "readme": "README.md", "interface": "interface.html", From 7b9e4b7f29c127bd0504095e173f4c7c54b7a19e Mon Sep 17 00:00:00 2001 From: Elfreda Kwawu <82907149+ekwawu@users.noreply.github.com> Date: Wed, 3 Apr 2024 12:42:13 -0400 Subject: [PATCH 10/52] Update metadata.json --- apps/phystrax/metadata.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/phystrax/metadata.json b/apps/phystrax/metadata.json index f23405aed..04585e0d1 100644 --- a/apps/phystrax/metadata.json +++ b/apps/phystrax/metadata.json @@ -9,7 +9,7 @@ "readme": "README.md", "interface": "interface.html", "storage": [ - {"name":"heartrate.app.js","url":"app.js"}, + {"name":"phystrax.app.js","url":"app.js"}, {"name":"app.png","url":"app-icon.js","evaluate":true} ] } From 780b95306a92630ee5b24ec07c0b5f4419717e8a Mon Sep 17 00:00:00 2001 From: Elfreda Kwawu <82907149+ekwawu@users.noreply.github.com> Date: Wed, 3 Apr 2024 12:50:28 -0400 Subject: [PATCH 11/52] Update metadata.json --- apps/phystrax/metadata.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/phystrax/metadata.json b/apps/phystrax/metadata.json index 04585e0d1..a71fc8aa0 100644 --- a/apps/phystrax/metadata.json +++ b/apps/phystrax/metadata.json @@ -10,6 +10,6 @@ "interface": "interface.html", "storage": [ {"name":"phystrax.app.js","url":"app.js"}, - {"name":"app.png","url":"app-icon.js","evaluate":true} + {"name":"app.img","url":"app-icon.js","evaluate":true} ] } From 50bdb6fe5557aceb2306fb0ffbaaa132f2a59c5e Mon Sep 17 00:00:00 2001 From: Elfreda Kwawu <82907149+ekwawu@users.noreply.github.com> Date: Thu, 4 Apr 2024 14:52:53 -0400 Subject: [PATCH 12/52] Update metadata.json for icon --- apps/phystrax/metadata.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/phystrax/metadata.json b/apps/phystrax/metadata.json index a71fc8aa0..4feeb6f16 100644 --- a/apps/phystrax/metadata.json +++ b/apps/phystrax/metadata.json @@ -10,6 +10,6 @@ "interface": "interface.html", "storage": [ {"name":"phystrax.app.js","url":"app.js"}, - {"name":"app.img","url":"app-icon.js","evaluate":true} + {"name":"app-icon.js","url":"app-icon.js","evaluate":true} ] } From d68efc5287748b049b6a2b678c73b7e3a6aa533c Mon Sep 17 00:00:00 2001 From: Elfreda Kwawu <82907149+ekwawu@users.noreply.github.com> Date: Thu, 4 Apr 2024 15:29:31 -0400 Subject: [PATCH 14/52] Update app.js --- apps/phystrax/app.js | 1 - 1 file changed, 1 deletion(-) diff --git a/apps/phystrax/app.js b/apps/phystrax/app.js index 4576a9114..e6566aa26 100644 --- a/apps/phystrax/app.js +++ b/apps/phystrax/app.js @@ -71,7 +71,6 @@ function drawScreen(message) { g.setFont('6x8', 1.6); g.drawString(' BPM', g.getWidth() / 2 + 42, g.getHeight() / 2 + 20); } - // Draw instructions g.setFont('6x8', 1.5); g.drawString('Press button to stop', g.getWidth() / 2, g.getHeight() / 2 + 42); From 409fa3abceb16813adef4980be9e0d4ecdf89245 Mon Sep 17 00:00:00 2001 From: Elfreda Kwawu <82907149+ekwawu@users.noreply.github.com> Date: Thu, 4 Apr 2024 15:32:44 -0400 Subject: [PATCH 15/52] Update metadata.json --- apps/phystrax/metadata.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/phystrax/metadata.json b/apps/phystrax/metadata.json index 4feeb6f16..d5b204c69 100644 --- a/apps/phystrax/metadata.json +++ b/apps/phystrax/metadata.json @@ -3,7 +3,7 @@ "shortName":"PhysTrax", "version":"0.01", "description": "Tracking physiological measurements to support active learning in classrooms", - "icon": "app.png", + "icon": "BangleApps/apps/phystrax/app.png", "tags": "health", "supports" : ["BANGLEJS2"], "readme": "README.md", From 7f3fc665581f3d899091427ffc6a524211c39cd3 Mon Sep 17 00:00:00 2001 From: Elfreda Kwawu <82907149+ekwawu@users.noreply.github.com> Date: Thu, 4 Apr 2024 15:37:21 -0400 Subject: [PATCH 16/52] Update metadata.json --- apps/phystrax/metadata.json | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/apps/phystrax/metadata.json b/apps/phystrax/metadata.json index d5b204c69..6ef02ec1a 100644 --- a/apps/phystrax/metadata.json +++ b/apps/phystrax/metadata.json @@ -1,9 +1,10 @@ { "id": "phystrax", - "name": "PhysTrax App", + "name": "PhysTrax", + "entry": "app.js", "shortName":"PhysTrax", "version":"0.01", "description": "Tracking physiological measurements to support active learning in classrooms", - "icon": "BangleApps/apps/phystrax/app.png", + "icon": "app.png", "tags": "health", "supports" : ["BANGLEJS2"], "readme": "README.md", From 6785717aa8c93e3c74cb8b5907038cfab4b0cd03 Mon Sep 17 00:00:00 2001 From: Elfreda Kwawu <82907149+ekwawu@users.noreply.github.com> Date: Thu, 4 Apr 2024 15:43:11 -0400 Subject: [PATCH 17/52] Update metadata.json --- apps/phystrax/metadata.json | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/apps/phystrax/metadata.json b/apps/phystrax/metadata.json index 6ef02ec1a..6117b74f6 100644 --- a/apps/phystrax/metadata.json +++ b/apps/phystrax/metadata.json @@ -1,6 +1,5 @@ { "id": "phystrax", "name": "PhysTrax", - "entry": "app.js", "shortName":"PhysTrax", "version":"0.01", "description": "Tracking physiological measurements to support active learning in classrooms", @@ -11,6 +10,6 @@ "interface": "interface.html", "storage": [ {"name":"phystrax.app.js","url":"app.js"}, - {"name":"app-icon.js","url":"app-icon.js","evaluate":true} + {"name":"app-icon.img","url":"app-icon.js","evaluate":true} ] } From e411db0eec9f5fc8994ab1028d6dc0ac954ba804 Mon Sep 17 00:00:00 2001 From: Elfreda Kwawu Date: Thu, 4 Apr 2024 16:25:02 -0400 Subject: [PATCH 18/52] added seconds --- apps/phystrax/app.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/phystrax/app.js b/apps/phystrax/app.js index e6566aa26..d5c8f4e8c 100644 --- a/apps/phystrax/app.js +++ b/apps/phystrax/app.js @@ -35,13 +35,13 @@ function handleHeartRate(hrm) { var date = new Date(); var dateStr = require("locale").date(date); var timeStr = require("locale").time(date, 1); - var timestamp = dateStr + " " + timeStr; // Concatenate date and time + var seconds = ('0' + date.getSeconds()).slice(-2); // Get seconds and pad with leading zero if necessary + var timestamp = dateStr + " " + timeStr + ":" + seconds; // Concatenate date, time, and seconds logData.push({ timestamp: timestamp, heartRate: currentHeartRate }); drawScreen(); } } - function drawScreen(message) { g.clear(); // Clear the display From b36fba55f11c18c0191c893e162d52bcbcca5e46 Mon Sep 17 00:00:00 2001 From: Elfreda Kwawu <82907149+ekwawu@users.noreply.github.com> Date: Thu, 4 Apr 2024 17:06:34 -0400 Subject: [PATCH 19/52] Update interface.html --- apps/phystrax/interface.html | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/phystrax/interface.html b/apps/phystrax/interface.html index 4e048b686..d1191ef8d 100644 --- a/apps/phystrax/interface.html +++ b/apps/phystrax/interface.html @@ -41,12 +41,12 @@ function getData() { }); } -// You can call a utility function to save the data +// Call a utility function to save the data document.getElementById("btnSave").addEventListener("click", function() { Util.saveCSV("heart_rate_data", csvData); }); -// Or you can also delete the file +// Or delete the file document.getElementById("btnDelete").addEventListener("click", function() { Util.showModal("Deleting..."); Util.eraseStorageFile("heart_rate_data.csv", function() { From fdbe704d898cc04a5dd58716ba114762acbfefef Mon Sep 17 00:00:00 2001 From: Elfreda Kwawu <82907149+ekwawu@users.noreply.github.com> Date: Thu, 4 Apr 2024 17:12:55 -0400 Subject: [PATCH 20/52] Update interface.html for testing purposes --- apps/phystrax/interface.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/phystrax/interface.html b/apps/phystrax/interface.html index d1191ef8d..56f091744 100644 --- a/apps/phystrax/interface.html +++ b/apps/phystrax/interface.html @@ -23,7 +23,7 @@ function getData() { Util.hideModal(); // If no data, report it and exit if (data.length === 0) { - dataElement.innerHTML = "No data found"; + dataElement.innerHTML = "There is no data"; return; } // Otherwise parse the data and output it as a table From b7e40d446fdd01a7d1ce3fe0b6ded4be90146479 Mon Sep 17 00:00:00 2001 From: Elfreda Kwawu <82907149+ekwawu@users.noreply.github.com> Date: Fri, 5 Apr 2024 22:02:47 -0400 Subject: [PATCH 21/52] testing for app loader integration --- apps/phystrax/app.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/phystrax/app.js b/apps/phystrax/app.js index d5c8f4e8c..e5a7c9da7 100644 --- a/apps/phystrax/app.js +++ b/apps/phystrax/app.js @@ -62,7 +62,7 @@ function drawScreen(message) { if (isMeasuring) { // Draw measuring status g.setFont('6x8', 2); - g.drawString('Measuring...', g.getWidth() / 2, g.getHeight() / 2 - 10); + g.drawString('Measuring..', g.getWidth() / 2, g.getHeight() / 2 - 10); // Draw current heart rate if available g.setFont('6x8', 4); From 6d5bcd72a01530f1d5b465e6d0f2841037183d1d Mon Sep 17 00:00:00 2001 From: Elfreda Kwawu <82907149+ekwawu@users.noreply.github.com> Date: Fri, 5 Apr 2024 22:30:36 -0400 Subject: [PATCH 22/52] Delete apps/phystrax directory --- apps/phystrax/README.md | 8 --- apps/phystrax/app-icon.js | 1 - apps/phystrax/app.js | 112 ----------------------------------- apps/phystrax/app.png | Bin 1299 -> 0 bytes apps/phystrax/interface.html | 65 -------------------- apps/phystrax/metadata.json | 15 ----- 6 files changed, 201 deletions(-) delete mode 100644 apps/phystrax/README.md delete mode 100644 apps/phystrax/app-icon.js delete mode 100644 apps/phystrax/app.js delete mode 100644 apps/phystrax/app.png delete mode 100644 apps/phystrax/interface.html delete mode 100644 apps/phystrax/metadata.json diff --git a/apps/phystrax/README.md b/apps/phystrax/README.md deleted file mode 100644 index ca8df74b7..000000000 --- a/apps/phystrax/README.md +++ /dev/null @@ -1,8 +0,0 @@ -# CapstoneWearable -Research has shown that active learning approaches in classrooms, which emphasize the construction of knowledge and reflection on the learning process, significantly enhance the student learning experience and lead to better success in the classroom. The Active Learning Initiative at the University of Georgia focuses on instructor development, student engagement, and classroom enhancement. - -This project focuses specifically on classroom enhancement to create a device that will enhance the learning experience of students in physiology classes by allowing them to learn about and analyze their physiological patterns. The project must adhere to the constraints of a one-hundred dollar per watch budget, the ability to be scaled to a classroom of three-hundred twenty students, and provide data with at least 80% accuracy. By giving students access to their heart rate (HR) and heart rate variability (HRV) data, the goal is that students can better understand the function of the heart as well as the physiological conditions that can be affected by the heart. The original concept was to develop a wrist-wearable, screen-less device featuring sensors that detect a user’s heart rate by emitting LEDs that detect the expansion of blood vessels in the wrist and the quantity of light transmitted in the vascular bed to obtain heart rate and blood oxygen data and the heart rate variability calculated using an algorithm that takes the root-mean-square of interbeat intervals between successive heartbeats. - -After prototyping this custom device and testing its efficacy, the accuracy of the data produced by the sensor was not within the accuracy criteria, and the decision was made to pivot to an existing on-market device coupled with custom software to meet the needs of the client. The analysis software created for the device allows the students to analyze their physiological data and permits for their instructor to access their data anonymously. The data, coupled with survey data entered by the students daily, provides insight into the effect of variables such as sleep, exercise, and caffeine intake to analyze the effects that these have on their physiological measurements. To evaluate the device's efficacy in achieving the goal of 80% accuracy, the wrist wearable device was tested on several different skin tones doing various activities and measuring data over varying intervals and then compared against the data of Apple Watches. - -This project resulted in the creation of a custom data analysis software for the use of students on a Bangle.js smartwatch device that can be continually developed in the future to reach the goal of an inexpensive, easy-to-use device for students to use in active learning classrooms to enhance their understanding of physiology by analyzing their own physiological data in class. diff --git a/apps/phystrax/app-icon.js b/apps/phystrax/app-icon.js deleted file mode 100644 index 46faf7ecc..000000000 --- a/apps/phystrax/app-icon.js +++ /dev/null @@ -1 +0,0 @@ -require("heatshrink").decompress(atob("mUywZC/AB9JkmQA4mSpMgCAsCCIILBCIoIBoARIEwYRDAQI1FBYdIgESBAoRChIIEAQIsFIIcBCIwCIwEACJ5fCBAkgChRTGMQw4FQApQLBYtAggRJpA+MARZKLRLDdHKBUEZY4CGyEJkEQcwOQX5hKBAQI7BBw9BGoUAEYJKBAoIjHUIUggAmCTAKGDFgQOCAAMCgIgBYQIFBBYawCR4IABGoMCOIOQhEEBYaPDXIhxBiQjCOgQCBHYJTDyA1BwAmCOIwpEBwIsBEwNANARcEEAIFCKYJNBAoLsHRgxHCZAxiFBAb+JAALRFI4puDAARlFUIRuGHA+CCIy/DHAwCHCIgyIQAwADTAYRNTA6SGAAo4ICJCkMAAzdBUhIAGL4tICJSGFCJsAhLIHABQRRQwLaFABbaGAFAA==")) diff --git a/apps/phystrax/app.js b/apps/phystrax/app.js deleted file mode 100644 index e5a7c9da7..000000000 --- a/apps/phystrax/app.js +++ /dev/null @@ -1,112 +0,0 @@ -let isMeasuring = false; -let currentHeartRate = null; -let lcdTimeout; -let logData = []; - -function startMeasure() { - isMeasuring = true; - Bangle.setLCDTimeout(0); - lcdTimeout = setTimeout(() => { - Bangle.setLCDTimeout(50); - }, 50000); - - setTimeout(() => { - Bangle.setHRMPower(1); - Bangle.on('HRM', handleHeartRate); - Bangle.beep(400, 1000); // Buzz to indicate measurement start - drawScreen(); - }, 500); -} - -function stopMeasure() { - isMeasuring = false; - clearTimeout(lcdTimeout); - Bangle.setLCDTimeout(10); - Bangle.setHRMPower(0); - Bangle.removeAllListeners('HRM'); - saveDataToCSV(); // Save data to CSV when measurement stops - Bangle.beep(400, 800); // Buzz to indicate measurement stop - drawScreen(); -} - -function handleHeartRate(hrm) { - if (hrm.confidence > 90) { - currentHeartRate = hrm.bpm; - var date = new Date(); - var dateStr = require("locale").date(date); - var timeStr = require("locale").time(date, 1); - var seconds = ('0' + date.getSeconds()).slice(-2); // Get seconds and pad with leading zero if necessary - var timestamp = dateStr + " " + timeStr + ":" + seconds; // Concatenate date, time, and seconds - logData.push({ timestamp: timestamp, heartRate: currentHeartRate }); - drawScreen(); - } -} - -function drawScreen(message) { - g.clear(); // Clear the display - - // Set the background color - g.setColor('#95E7FF'); - - // Fill the entire display with the background color - g.fillRect(0, 0, g.getWidth(), g.getHeight()); - - // Set font and alignment for drawing text - g.setFontAlign(0, 0); - g.setFont('Vector', 15); - - // Draw the title - g.setColor('#000000'); // Set text color to black - g.drawString('Heart Rate Monitor', g.getWidth() / 2, 10); - - if (isMeasuring) { - // Draw measuring status - g.setFont('6x8', 2); - g.drawString('Measuring..', g.getWidth() / 2, g.getHeight() / 2 - 10); - - // Draw current heart rate if available - g.setFont('6x8', 4); - if (currentHeartRate !== null) { - g.drawString(currentHeartRate.toString(), g.getWidth() / 2, g.getHeight() / 2 + 20); - g.setFont('6x8', 1.6); - g.drawString(' BPM', g.getWidth() / 2 + 42, g.getHeight() / 2 + 20); - } - // Draw instructions - g.setFont('6x8', 1.5); - g.drawString('Press button to stop', g.getWidth() / 2, g.getHeight() / 2 + 42); - } else { - // Draw last heart rate - g.setFont('Vector', 12); - g.drawString('Last Heart Rate:', g.getWidth() / 2, g.getHeight() / 2 - 20); - if (currentHeartRate !== null && currentHeartRate > 0) { - g.setFont('6x8', 4); - g.drawString(currentHeartRate.toString(), g.getWidth() / 2, g.getHeight() / 2 + 10); - } else { - g.setFont('6x8', 2); - g.drawString('No data', g.getWidth() / 2, g.getHeight() / 2 + 10); - g.setFont('6x8', 1); - g.drawString(message || 'Press button to start', g.getWidth() / 2, g.getHeight() / 2 + 30); - } - } - - // Update the display - g.flip(); -} - -function saveDataToCSV() { - let csvContent = "Timestamp,Heart Rate\n"; - logData.forEach(entry => { - csvContent += `${entry.timestamp},${entry.heartRate}\n`; - }); - require("Storage").write("heart_rate_data.csv", csvContent); -} - -setWatch(function() { - if (!isMeasuring) { - startMeasure(); - } else { - stopMeasure(); - } -}, BTN1, { repeat: true, edge: 'rising' }); - -drawScreen(); diff --git a/apps/phystrax/app.png b/apps/phystrax/app.png deleted file mode 100644 index 5fd69c6de8f3e7b00e4eb089a4e933d80116a6bf..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1299 zcmV+u1?>8XP)YDOK64;+c;hzlVG5|xa)NkqrN3F+y3E3xEM zZnc%3p6T25NDVRviiWPLbMJS~x#ygFyFG7S=4D=TOM|@8kWXoHj{){;azc}#CjZdD zH=5iL`u^HzVBic_ozd#mXNKehntWB0qp>c=Iw$NHGFE>h2yVy?5CZoa@;gIDP8V=U zEA>be1Pf;aFu6dU@4e!4g6iSUPF$x4Ksv(&W%75Fv0^4rRmQO$~fh1x)Ds zYyR^FIhq6HA?wji6?x_BlPQtBE{~!{5Zo+!j8e<005LKLrLOl3xh1nTfTKzAi-O=> z4IHls<_RxPY-?a7z19qHpb8L8ekg;`x1Xsi$3y|F^>3y^?m@~>$+fWb(qOQaH)0t5Ugq4mDQ!*8crna?fAa~9-rt8A&g zKQirorS7oLt}4kRL!$hdPTr8BnF84$-!}l*$-Qfz+hn_h9W6Qzil^dQ<9Q1V`Ev;% z+r5yy$Hg0xnc_9Ee*O8|~#}le@6FW^8ek5KCDqjDW@Voo(_tRjXYs@5I^C_m_7Xw_d9)=>T1q zuEGt%_gC5l|E2}FptWn3MV@4_W~%}WCR<#Yyg(%DOq0*Lj9u>lVt{wj*1pX#7AGaN zn(wvrX_9`^;npBkJaO^``^?tZ0KUH_+PLu?o8`WkDYWXf+7gGegE&f>qJfW{V1NxN z1H6~MCk4@dze|%xqRpGnl2emrtpW}u3qKyy_aDx+$br4>!e_aoS3XO5WUS?WT;b(Y zyby;KsoGgkwy9FcGDDF6O!G#{!f!cP;Y3K@Dd$XW?(dF6N2y*}7gpzB%LIm^Ah@{I zn_XYP&KVb$WT9>j&e|wH5bIgD?(FyzSS*<<*M!;Dn1?%_Z;7R|Zjh2zCFSA%5+IIC zwwx6rHG#)652n8G7^turZypqvkajPQzRpH(sU+)ScwrCJ6wAH-Z!G@#W z-b)>u(Qfp<(amZ9sW2xC)@y}_M+Q$ssrr*026(ALi0!!{(ju`hTguZ2(2&aSl_8S$ zH2M2!fH>mP8Rrt&muTS2(jb75WUo`Y*hX+$ktd5**T8H)+m$9psoM?kQvo1j$-cfa ziO+n=mu)wi1!8y9({qtGS0q&G{%+35 - - - - -
- - - - - - - diff --git a/apps/phystrax/metadata.json b/apps/phystrax/metadata.json deleted file mode 100644 index 6117b74f6..000000000 --- a/apps/phystrax/metadata.json +++ /dev/null @@ -1,15 +0,0 @@ -{ "id": "phystrax", - "name": "PhysTrax", - "shortName":"PhysTrax", - "version":"0.01", - "description": "Tracking physiological measurements to support active learning in classrooms", - "icon": "app.png", - "tags": "health", - "supports" : ["BANGLEJS2"], - "readme": "README.md", - "interface": "interface.html", - "storage": [ - {"name":"phystrax.app.js","url":"app.js"}, - {"name":"app-icon.img","url":"app-icon.js","evaluate":true} - ] -} From d49809920a322af8e21638d38380a85e9453b124 Mon Sep 17 00:00:00 2001 From: Elfreda Kwawu Date: Fri, 5 Apr 2024 22:57:04 -0400 Subject: [PATCH 23/52] adding files to phystrax --- apps/phystrax/app-icon.js | 1 + apps/phystrax/app.js | 114 +++++++++++++++++++++++++++++++++++ apps/phystrax/app.png | Bin 0 -> 1950 bytes apps/phystrax/interface.html | 64 ++++++++++++++++++++ apps/phystrax/metadata.json | 14 +++++ 5 files changed, 193 insertions(+) create mode 100644 apps/phystrax/app-icon.js create mode 100644 apps/phystrax/app.js create mode 100644 apps/phystrax/app.png create mode 100644 apps/phystrax/interface.html create mode 100644 apps/phystrax/metadata.json diff --git a/apps/phystrax/app-icon.js b/apps/phystrax/app-icon.js new file mode 100644 index 000000000..a535bf5e3 --- /dev/null +++ b/apps/phystrax/app-icon.js @@ -0,0 +1 @@ +require("heatshrink").decompress(atob("mEwwZC/AH4ABgVJkmAA4cEyVJCIwIBkmSAwUBAoIIBCAgaCBYNIA4IFCFgwIDF4Q7CBAWQFg4CBkESCIg+DhIRFAQ9ACKYOLMRWf5IRQ/IRP/4RlzwRKyf5k4RC/xcFCISPBKwMn+YRB/4RFUImf/4RCEwIRIa4P/AAPz/YRDHwLXEgP//1P/+T/8vJQIZCCIkAn/yCIOSv8/2YQCCIOQCIY+CCIYmB8g1CCIkECIM8CII4CLIeACIcAMQd//mSvYRDCAkAiQRFWYcgCIsCCJIQFbQl/8jCGAAq2ByVPCIiwCAAq2BCILCECA6SEAQaMEAAqSCRhIAFCIoQKSQiMHQBJ6IQBB6IQBAQNNwRoLAH4AoA=")) \ No newline at end of file diff --git a/apps/phystrax/app.js b/apps/phystrax/app.js new file mode 100644 index 000000000..663652c14 --- /dev/null +++ b/apps/phystrax/app.js @@ -0,0 +1,114 @@ +let isMeasuring = false; +let currentHeartRate = null; +let lcdTimeout; +let logData = []; + +function startMeasure() { + isMeasuring = true; + Bangle.setLCDTimeout(0); + lcdTimeout = setTimeout(() => { + Bangle.setLCDTimeout(50); + }, 50000); + + setTimeout(() => { + Bangle.setHRMPower(1); + Bangle.on('HRM', handleHeartRate); + Bangle.beep(400, 1000); // Buzz to indicate measurement start + drawScreen(); + }, 500); +} + +function stopMeasure() { + isMeasuring = false; + clearTimeout(lcdTimeout); + Bangle.setLCDTimeout(10); + Bangle.setHRMPower(0); + Bangle.removeAllListeners('HRM'); + saveDataToCSV(); // Save data to CSV when measurement stops + Bangle.beep(400, 800); // Buzz to indicate measurement stop + drawScreen(); +} + +function handleHeartRate(hrm) { + if (hrm.confidence > 90) { + currentHeartRate = hrm.bpm; + let date = new Date(); + let dateStr = require("locale").date(date); + let timeStr = require("locale").time(date, 1); + let seconds = date.getSeconds(); + let timestamp = `${dateStr} ${timeStr}:${seconds}`; // Concatenate date, time, and seconds + logData.push({ timestamp: timestamp, heartRate: currentHeartRate }); + drawScreen(); + } +} + + +function drawScreen(message) { + g.clear(); // Clear the display + + // Set the background color + g.setColor('#95E7FF'); + + // Fill the entire display with the background color + g.fillRect(0, 0, g.getWidth(), g.getHeight()); + + // Set font and alignment for drawing text + g.setFontAlign(0, 0); + g.setFont('Vector', 15); + + // Draw the title + g.setColor('#000000'); // Set text color to black + g.drawString('Heart Rate Monitor', g.getWidth() / 2, 10); + + if (isMeasuring) { + // Draw measuring status + g.setFont('6x8', 2); + g.drawString('Measuring...', g.getWidth() / 2, g.getHeight() / 2 - 10); + + // Draw current heart rate if available + g.setFont('6x8', 4); + if (currentHeartRate !== null) { + g.drawString(currentHeartRate.toString(), g.getWidth() / 2, g.getHeight() / 2 + 20); + g.setFont('6x8', 1.6); + g.drawString(' BPM', g.getWidth() / 2 + 42, g.getHeight() / 2 + 20); + } + + // Draw instructions + g.setFont('6x8', 1.5); + g.drawString('Press button to stop', g.getWidth() / 2, g.getHeight() / 2 + 42); + } else { + // Draw last heart rate + g.setFont('Vector', 12); + g.drawString('Last Heart Rate:', g.getWidth() / 2, g.getHeight() / 2 - 20); + if (currentHeartRate !== null && currentHeartRate > 0) { + g.setFont('6x8', 4); + g.drawString(currentHeartRate.toString(), g.getWidth() / 2, g.getHeight() / 2 + 10); + } else { + g.setFont('6x8', 2); + g.drawString('No data', g.getWidth() / 2, g.getHeight() / 2 + 10); + g.setFont('6x8', 1); + g.drawString(message || 'Press button to start', g.getWidth() / 2, g.getHeight() / 2 + 30); + } + } + + // Update the display + g.flip(); +} + +function saveDataToCSV() { + let csvContent = "Timestamp,Heart Rate\n"; + logData.forEach(entry => { + csvContent += `${entry.timestamp},${entry.heartRate}\n`; + }); + require("Storage").write("heart_rate_data.csv", csvContent); +} + +setWatch(function() { + if (!isMeasuring) { + startMeasure(); + } else { + stopMeasure(); + } +}, BTN1, { repeat: true, edge: 'rising' }); + +drawScreen(); diff --git a/apps/phystrax/app.png b/apps/phystrax/app.png new file mode 100644 index 0000000000000000000000000000000000000000..b9c10ca4683a987b0056826fd952fd97d97d289d GIT binary patch literal 1950 zcmV;P2VwY$P)0`}qCd@3SS6deoyH^{B_?4$d*z%{iy`a4zpG z=kSu8!@I)TCrHjdd6=_r-IEv|m#+7o^q^Bl6Rt;T!g-i6I!MakSfTZHk~WOY()y7< zQaW4LMT0Y=6U_gNt;Dpo2 z5Y7)7!UYWB1lq`_189Q-XuTaJr5k~mZX`o#Z8Nmi+_)k5#ORHdgwspsz%l$}7M=&s z!?U(=lyR#k!&=7E(cG`cx=KbCNI(1dHgnsrK-2aomhX@ywd5JWYW zWK>;a5x8x#;0&td~y< zL^WoJ^q69_dZ?kgedp9`h1Ms^TelWk$KV*AF^!_62VF}v;aaNQx^)e_1!5WtMAc@9 zs!b5>F+oI09I9d3cr%r)dqk}>rY!s*pJm#mob>^lsC5M2V}ht^5F#o9!b&0&Q|db_ z6ySZd>>{mb-3{#cc1TSBJ`2BgkrrDQYZt3vJz8WP!7B-fD2zB|`rYCM*eCw85$nm1 zjsQd`;C4=L+`6W`bpc*(fUwK}VX1Cbv;cNwB2d}-nnjxJb=JEBARI#lEbe&%!y7he zy@$8XgBMvx@OlVK^$_aTk>UjmZ(R`^jpcjY1xx?@H-hJL>0bvoXx&uUF2&Xnybi+G zYa!IFT@fuHZu10dv7TR~E=V0aAr!Fs&U@>yZmwuOEME(rgCBrkSHEBU6R>$^Yq6f2 zFzhXNVfauKJ*JKxFR{)&@CYm)dJ`z4<6^8ssA~X1UHuU3>_0622@H)rUa}#X-N4;` zKV;5dfTh1ZRWM0kudozr;27@d$leGa|Ozn1ytTXfAhyg+4-0qmW-g!Wo_ z>)k5W^=Ofnv(Cc@xAZ}Z*GGj# zy0~vYq`y3cr_F&EVEL6d@b%Nrp>|oGc?-A7Bafp+N*SGy@dZ)g>62%0ad+%0Yn{36 zen|iCETm7J1$xIc2Jh?>tOqx1Q2N_?JXH&TnVBCYkDcIh=8)x6^FW(MfxC4YFW68N z^*e%^+=0w4{(V0#X#ex5*SUuu!;|U#PhsINPvQ4ooB?Wd8>G*k7w!#3nL0V22hYK` zt9kf2kVvkQ)DkPtAM)lVONIOAgnfLd%Yj%U*7|%Q}d8Ic?PJP?-HyB+W72& zK&x`ky5LbO>GeOR^}`>R+mLAYO|bCie*mSo3&(&M;mnTGAT0d#X>`r6i(IcS?tcLn z;15B}b8~)?b{6$|JGPF%H>tqisyqS;#nqCHM3fl$1vOv`)Oz?zpToVK>v3l1y~2c{ zT-zXZ{3Ngs?JXIN!7O|pJPY5VB*X2BYb6&G{I3K2_tIJpU#lO_<`@3ya}ee?r*a!o z73+ak6_Cw}xUW^U?q55~7ooB0W169*YR7=(mtPkOSa|Z;iW`!s^;RYLTNF$FR+&z6 zDI=mbIU_yhWTj(3;)y4P0{C%Rx*@H#t}e0eZ&3o-B2W1nm1CC_UMNCknu@3fSH+G2 z@wL%UfSF8cVG!foxK&l1);tVHk?DU;HV%35#DTlY6BfNYd=z9!k=_W~~z(WRA#y0yN_ zhp!6On-$=1mV>`he!+L$^_OPath)$>_S#Tq|D4$2tGsm{9JLIPjj}I%&B|X%e#n?_ zvHm2`(RZ-;@KtDCS!f->OAmebOU+LuS4xE1H8%y@)r(cFH^`RB2I+LoC(G|Md@a2) z|0dPEsPzWf8Q*o?GRc)3k+!~T$X3ORMZM0$zxs8PqU2}yD>nR1itYS_AseLM`5L6# ke`ub1)T18tkX)AdKh$!^8g*v#$^ZZW07*qoM6N<$f^2=ns{jB1 literal 0 HcmV?d00001 diff --git a/apps/phystrax/interface.html b/apps/phystrax/interface.html new file mode 100644 index 000000000..d2d3a89cc --- /dev/null +++ b/apps/phystrax/interface.html @@ -0,0 +1,64 @@ + + + + + +
+ + + + + + + diff --git a/apps/phystrax/metadata.json b/apps/phystrax/metadata.json new file mode 100644 index 000000000..e4198919b --- /dev/null +++ b/apps/phystrax/metadata.json @@ -0,0 +1,14 @@ +{ "id": "phystrax", + "name": "PhysTrax", + "shortName":"PhysTrax", + "icon": "app.png", + "version":"0.01", + "description": "Tracking physiological measurements to support active learning in classrooms", + "tags": "health", + "interface": "interface.html", + "supports": ["BANGLEJS2"], + "storage": [ + {"name":"phystrax.app.js","url":"app.js"}, + {"name":"phystrax.img","url":"app-icon.js","evaluate":true} + ] +} \ No newline at end of file From b9e11d82db012c165c46504980dae5bc3f47446f Mon Sep 17 00:00:00 2001 From: Elfreda Kwawu Date: Fri, 5 Apr 2024 22:59:32 -0400 Subject: [PATCH 24/52] adding README --- apps/phystrax/README.md | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 apps/phystrax/README.md diff --git a/apps/phystrax/README.md b/apps/phystrax/README.md new file mode 100644 index 000000000..484d09036 --- /dev/null +++ b/apps/phystrax/README.md @@ -0,0 +1,7 @@ +Research has shown that active learning approaches in classrooms, which emphasize the construction of knowledge and reflection on the learning process, significantly enhance the student learning experience and lead to better success in the classroom. The Active Learning Initiative at the University of Georgia focuses on instructor development, student engagement, and classroom enhancement. + +This project focuses specifically on classroom enhancement to create a device that will enhance the learning experience of students in physiology classes by allowing them to learn about and analyze their physiological patterns. The project must adhere to the constraints of a one-hundred dollar per watch budget, the ability to be scaled to a classroom of three-hundred twenty students, and provide data with at least 80% accuracy. By giving students access to their heart rate (HR) and heart rate variability (HRV) data, the goal is that students can better understand the function of the heart as well as the physiological conditions that can be affected by the heart. The original concept was to develop a wrist-wearable, screen-less device featuring sensors that detect a user’s heart rate by emitting LEDs that detect the expansion of blood vessels in the wrist and the quantity of light transmitted in the vascular bed to obtain heart rate and blood oxygen data and the heart rate variability calculated using an algorithm that takes the root-mean-square of interbeat intervals between successive heartbeats. + +After prototyping this custom device and testing its efficacy, the accuracy of the data produced by the sensor was not within the accuracy criteria, and the decision was made to pivot to an existing on-market device coupled with custom software to meet the needs of the client. The analysis software created for the device allows the students to analyze their physiological data and permits for their instructor to access their data anonymously. The data, coupled with survey data entered by the students daily, provides insight into the effect of variables such as sleep, exercise, and caffeine intake to analyze the effects that these have on their physiological measurements. To evaluate the device's efficacy in achieving the goal of 80% accuracy, the wrist wearable device was tested on several different skin tones doing various activities and measuring data over varying intervals and then compared against the data of Apple Watches. + +This project resulted in the creation of a custom data analysis software for the use of students on a Bangle.js smartwatch device that can be continually developed in the future to reach the goal of an inexpensive, easy-to-use device for students to use in active learning classrooms to enhance their understanding of physiology by analyzing their own physiological data in class. \ No newline at end of file From 6ac7ea178916f264b4ad6ec52db38501c23efb9e Mon Sep 17 00:00:00 2001 From: Elfreda Kwawu Date: Fri, 5 Apr 2024 23:05:41 -0400 Subject: [PATCH 25/52] added README in metadata --- apps/phystrax/README.md | 1 + apps/phystrax/metadata.json | 1 + 2 files changed, 2 insertions(+) diff --git a/apps/phystrax/README.md b/apps/phystrax/README.md index 484d09036..dbb1272ef 100644 --- a/apps/phystrax/README.md +++ b/apps/phystrax/README.md @@ -1,3 +1,4 @@ +# Capstone Wearable Research has shown that active learning approaches in classrooms, which emphasize the construction of knowledge and reflection on the learning process, significantly enhance the student learning experience and lead to better success in the classroom. The Active Learning Initiative at the University of Georgia focuses on instructor development, student engagement, and classroom enhancement. This project focuses specifically on classroom enhancement to create a device that will enhance the learning experience of students in physiology classes by allowing them to learn about and analyze their physiological patterns. The project must adhere to the constraints of a one-hundred dollar per watch budget, the ability to be scaled to a classroom of three-hundred twenty students, and provide data with at least 80% accuracy. By giving students access to their heart rate (HR) and heart rate variability (HRV) data, the goal is that students can better understand the function of the heart as well as the physiological conditions that can be affected by the heart. The original concept was to develop a wrist-wearable, screen-less device featuring sensors that detect a user’s heart rate by emitting LEDs that detect the expansion of blood vessels in the wrist and the quantity of light transmitted in the vascular bed to obtain heart rate and blood oxygen data and the heart rate variability calculated using an algorithm that takes the root-mean-square of interbeat intervals between successive heartbeats. diff --git a/apps/phystrax/metadata.json b/apps/phystrax/metadata.json index e4198919b..68a2cde56 100644 --- a/apps/phystrax/metadata.json +++ b/apps/phystrax/metadata.json @@ -6,6 +6,7 @@ "description": "Tracking physiological measurements to support active learning in classrooms", "tags": "health", "interface": "interface.html", + "readme": "README.md", "supports": ["BANGLEJS2"], "storage": [ {"name":"phystrax.app.js","url":"app.js"}, From 5448b618df4cbd19f2e171710d79ff62b874a905 Mon Sep 17 00:00:00 2001 From: Elfreda Kwawu Date: Fri, 5 Apr 2024 23:24:47 -0400 Subject: [PATCH 26/52] edited interface.html --- apps/phystrax/interface.html | 95 +++++++++++++++--------------------- 1 file changed, 38 insertions(+), 57 deletions(-) diff --git a/apps/phystrax/interface.html b/apps/phystrax/interface.html index d2d3a89cc..9d1cad8cd 100644 --- a/apps/phystrax/interface.html +++ b/apps/phystrax/interface.html @@ -1,64 +1,45 @@ - - - - -
- - + + + + +
- - + - + }); +} + +function onInit() { + downloadHeartRateData(); +} + + + From 426d830fd7c7102e2b54a4daa35b18be16d9f7a1 Mon Sep 17 00:00:00 2001 From: Elfreda Kwawu Date: Wed, 10 Apr 2024 12:11:13 -0400 Subject: [PATCH 27/52] edited app.js and interface.html --- apps/phystrax/app.js | 2 +- apps/phystrax/interface.html | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/apps/phystrax/app.js b/apps/phystrax/app.js index 663652c14..a085ce152 100644 --- a/apps/phystrax/app.js +++ b/apps/phystrax/app.js @@ -96,7 +96,7 @@ function drawScreen(message) { } function saveDataToCSV() { - let csvContent = "Timestamp,Heart Rate\n"; + let csvContent = "Date,Time,Heart Rate\n"; logData.forEach(entry => { csvContent += `${entry.timestamp},${entry.heartRate}\n`; }); diff --git a/apps/phystrax/interface.html b/apps/phystrax/interface.html index 9d1cad8cd..b76d86f74 100644 --- a/apps/phystrax/interface.html +++ b/apps/phystrax/interface.html @@ -13,7 +13,7 @@ const DB_HEADER_LEN = 1; // Adjust header length for heart rate data var domContent = document.getElementById("content"); function saveCSV(data, title) { - var csv = "Timestamp,Heart Rate\n"; // Adjust CSV header for heart rate data + var csv = "Date,Time,Heart Rate\n"; var lines = data.split("\n"); for (var i = 0; i < lines.length; i++) { var line = lines[i]; @@ -26,10 +26,10 @@ function saveCSV(data, title) { function downloadHeartRateData() { Util.showModal("Downloading Heart Rate Data..."); - Util.readStorageFile("heart_rate_data.csv", data => { + Util.readStorageFile("heart_rate_data.csv", data => { // Read data from specified file Util.hideModal(); if (data) { - saveCSV(data, "Heart Rate Data"); // Provide a title for the CSV file + saveCSV(data, "Heart Rate Data"); } else { domContent.innerHTML = "No heart rate data found"; } From 43d7d9038602810b4951bf01fd830a7431c99977 Mon Sep 17 00:00:00 2001 From: Elfreda Kwawu <82907149+ekwawu@users.noreply.github.com> Date: Wed, 10 Apr 2024 12:36:51 -0400 Subject: [PATCH 28/52] Update interface.html (debugging) --- apps/phystrax/interface.html | 3 +++ 1 file changed, 3 insertions(+) diff --git a/apps/phystrax/interface.html b/apps/phystrax/interface.html index b76d86f74..2a60748dc 100644 --- a/apps/phystrax/interface.html +++ b/apps/phystrax/interface.html @@ -25,12 +25,15 @@ function saveCSV(data, title) { } function downloadHeartRateData() { + console.log("starting download..."); Util.showModal("Downloading Heart Rate Data..."); Util.readStorageFile("heart_rate_data.csv", data => { // Read data from specified file + console.log("Data received: ", data); Util.hideModal(); if (data) { saveCSV(data, "Heart Rate Data"); } else { + console.log("no data in csv"); domContent.innerHTML = "No heart rate data found"; } }); From 3fb9e3fd50fabb9fc7c2c0e1ae93e7ecd8451060 Mon Sep 17 00:00:00 2001 From: Elfreda Kwawu Date: Wed, 10 Apr 2024 15:36:33 -0400 Subject: [PATCH 29/52] changes to app.js + interface.html --- apps/phystrax/app.js | 2 +- apps/phystrax/interface.html | 14 ++++++++------ 2 files changed, 9 insertions(+), 7 deletions(-) diff --git a/apps/phystrax/app.js b/apps/phystrax/app.js index a085ce152..663652c14 100644 --- a/apps/phystrax/app.js +++ b/apps/phystrax/app.js @@ -96,7 +96,7 @@ function drawScreen(message) { } function saveDataToCSV() { - let csvContent = "Date,Time,Heart Rate\n"; + let csvContent = "Timestamp,Heart Rate\n"; logData.forEach(entry => { csvContent += `${entry.timestamp},${entry.heartRate}\n`; }); diff --git a/apps/phystrax/interface.html b/apps/phystrax/interface.html index 2a60748dc..26e68abd6 100644 --- a/apps/phystrax/interface.html +++ b/apps/phystrax/interface.html @@ -7,13 +7,13 @@ From 6841bb2d00fbe114c9b81562e154de95aa004654 Mon Sep 17 00:00:00 2001 From: Elfreda Kwawu Date: Tue, 16 Apr 2024 15:36:36 -0400 Subject: [PATCH 35/52] testing (editing metadata) --- apps/phystrax/metadata.json | 3 +++ 1 file changed, 3 insertions(+) diff --git a/apps/phystrax/metadata.json b/apps/phystrax/metadata.json index 68a2cde56..439eaacaf 100644 --- a/apps/phystrax/metadata.json +++ b/apps/phystrax/metadata.json @@ -8,6 +8,9 @@ "interface": "interface.html", "readme": "README.md", "supports": ["BANGLEJS2"], + "permissions": { + "read": ["file"] + }, "storage": [ {"name":"phystrax.app.js","url":"app.js"}, {"name":"phystrax.img","url":"app-icon.js","evaluate":true} From 0627d757b375e57724be7d668813f16b631d2798 Mon Sep 17 00:00:00 2001 From: Elfreda Kwawu Date: Tue, 16 Apr 2024 16:48:04 -0400 Subject: [PATCH 36/52] fix file saving --- apps/phystrax/app.js | 18 ++++++++++------ apps/phystrax/interface.html | 42 +++++++++++++++++++++++++----------- apps/phystrax/metadata.json | 6 ++---- 3 files changed, 44 insertions(+), 22 deletions(-) diff --git a/apps/phystrax/app.js b/apps/phystrax/app.js index 0f403a067..15cab6b9d 100644 --- a/apps/phystrax/app.js +++ b/apps/phystrax/app.js @@ -4,6 +4,7 @@ let lcdTimeout; let logData = []; let bpmValues = []; let lastLogTime = 0; +const MAX_LOGS = 9; function startMeasure() { isMeasuring = true; @@ -58,7 +59,6 @@ function handleHeartRate(hrm) { } } - function calcSDNN() { if (bpmValues.length < 5) return 0; // No calculation if insufficient data @@ -87,14 +87,14 @@ function drawScreen(message) { g.clear(); // Clear the display // Set the background color - g.setColor('#95E7FF'); + g.setColor('#95E7FF'); // Fill the entire display with the background color g.fillRect(0, 0, g.getWidth(), g.getHeight()); // Set font and alignment for drawing text g.setFontAlign(0, 0); - g.setFont('Vector', 15); + g.setFont('Vector', 15); // Draw the title g.setColor('#000000'); // Set text color to black @@ -111,7 +111,6 @@ function drawScreen(message) { g.drawString(currentHR.toString(), g.getWidth() / 2, g.getHeight() / 2 + 20); g.setFont('6x8', 1.6); g.drawString(' BPM', g.getWidth() / 2 + 42, g.getHeight() / 2 + 20); - } // Draw instructions @@ -126,7 +125,6 @@ function drawScreen(message) { g.drawString(currentHR.toString(), g.getWidth() / 2, g.getHeight() / 2 + 10); g.setFont('6x8', 1.6); g.drawString(' BPM', g.getWidth() / 2 + 42, g.getHeight() / 2 + 12); - } else { g.setFont('6x8', 2); g.drawString('No data', g.getWidth() / 2, g.getHeight() / 2 + 10); @@ -144,7 +142,15 @@ function saveDataToCSV() { logData.forEach(entry => { csvContent += `${entry.timestamp},${entry.heartRate},${entry.hrv}\n`; }); - require("Storage").write("heart_rate_data.csv", csvContent); + + // Find an available file number + let fileNum = 0; + while (require("Storage").read(`heart_rate_data_${fileNum}.csv`) !== undefined && fileNum <= MAX_LOGS) { + fileNum++; + } + + // Write data to a CSV file + require("Storage").write(`heart_rate_data_${fileNum}.csv`, csvContent); } setWatch(function() { diff --git a/apps/phystrax/interface.html b/apps/phystrax/interface.html index bc6ef215a..d372bfd70 100644 --- a/apps/phystrax/interface.html +++ b/apps/phystrax/interface.html @@ -9,36 +9,54 @@ diff --git a/apps/phystrax/metadata.json b/apps/phystrax/metadata.json index 439eaacaf..58e0197b5 100644 --- a/apps/phystrax/metadata.json +++ b/apps/phystrax/metadata.json @@ -8,11 +8,9 @@ "interface": "interface.html", "readme": "README.md", "supports": ["BANGLEJS2"], - "permissions": { - "read": ["file"] - }, "storage": [ {"name":"phystrax.app.js","url":"app.js"}, {"name":"phystrax.img","url":"app-icon.js","evaluate":true} - ] + ], + "data": [{"wildcard":"heart_rate_data.?.csv"}] } \ No newline at end of file From c17b87ca47d6c3980f2980cf0d69a10d03aef11a Mon Sep 17 00:00:00 2001 From: Elfreda Kwawu Date: Tue, 16 Apr 2024 17:15:04 -0400 Subject: [PATCH 37/52] edited app.js --- apps/phystrax/app.js | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/apps/phystrax/app.js b/apps/phystrax/app.js index 15cab6b9d..b2eb31260 100644 --- a/apps/phystrax/app.js +++ b/apps/phystrax/app.js @@ -143,16 +143,26 @@ function saveDataToCSV() { csvContent += `${entry.timestamp},${entry.heartRate},${entry.hrv}\n`; }); - // Find an available file number + // Check if the file already exists let fileNum = 0; - while (require("Storage").read(`heart_rate_data_${fileNum}.csv`) !== undefined && fileNum <= MAX_LOGS) { + let fileName = `heart_rate_data_${fileNum}.csv`; + while (require("Storage").read(fileName) !== undefined && fileNum <= MAX_LOGS) { fileNum++; + fileName = `heart_rate_data_${fileNum}.csv`; } - // Write data to a CSV file - require("Storage").write(`heart_rate_data_${fileNum}.csv`, csvContent); + // Prompt user for confirmation before overwriting existing file + if (require("Storage").read(fileName) !== undefined) { + if (!confirm("Overwrite existing file?")) { + return; // Do not overwrite file if user cancels + } + } + + // Write data to the CSV file + require("Storage").write(fileName, csvContent); } + setWatch(function() { if (!isMeasuring) { startMeasure(); From a3561498e46ec5c0ec300924f77548c06347e27b Mon Sep 17 00:00:00 2001 From: Elfreda Kwawu Date: Tue, 16 Apr 2024 17:27:44 -0400 Subject: [PATCH 38/52] edit interface.html --- apps/phystrax/interface.html | 85 ++++++++++++++++-------------------- 1 file changed, 38 insertions(+), 47 deletions(-) diff --git a/apps/phystrax/interface.html b/apps/phystrax/interface.html index d372bfd70..cf5b9e535 100644 --- a/apps/phystrax/interface.html +++ b/apps/phystrax/interface.html @@ -7,57 +7,48 @@ From 439c3db81415d3e2c60b62b31f9784587c187e37 Mon Sep 17 00:00:00 2001 From: Elfreda Kwawu Date: Tue, 16 Apr 2024 17:34:26 -0400 Subject: [PATCH 39/52] added console logging --- apps/phystrax/interface.html | 45 ++++++++++++++++++------------------ 1 file changed, 23 insertions(+), 22 deletions(-) diff --git a/apps/phystrax/interface.html b/apps/phystrax/interface.html index cf5b9e535..d9007967f 100644 --- a/apps/phystrax/interface.html +++ b/apps/phystrax/interface.html @@ -10,32 +10,33 @@ var dataElement = document.getElementById("data"); function getHeartRateData() { - Util.showModal("Loading..."); - dataElement.innerHTML = ""; - Puck.eval('require("Storage").list(/heart_rate_data\\.csv\\x01/)', files => { - if (files.length == 0) { + Util.showModal("Loading..."); + dataElement.innerHTML = ""; + Puck.eval('require("Storage").list(/heart_rate_data\\.csv\\x01/)', files => { + console.log("Files found:", files); // Add this line to check files + if (files.length == 0) { dataElement.innerHTML = "

No heart rate data found

"; - } else { + } else { files.forEach(fn => { - fn = fn.slice(0, -1); - var link = document.createElement("a"); - link.setAttribute("href", "#"); - link.textContent = fn; - link.addEventListener("click", function() { - Util.showModal("Downloading..."); - Util.readStorageFile(fn, function(data) { - Util.saveCSV(fn.slice(0, -4), data); - console.log("Downloaded file path:", fn); // Print file path to console - Util.hideModal(); + fn = fn.slice(0, -1); + var link = document.createElement("a"); + link.setAttribute("href", "#"); + link.textContent = fn; + link.addEventListener("click", function() { + Util.showModal("Downloading..."); + Util.readStorageFile(fn, function(data) { + Util.saveCSV(fn.slice(0, -4), data); + console.log("Downloaded file path:", fn); // Print file path to console + Util.hideModal(); + }); }); - }); - dataElement.appendChild(link); - dataElement.appendChild(document.createElement("br")); + dataElement.appendChild(link); + dataElement.appendChild(document.createElement("br")); }); - } - Util.hideModal(); - }); - } + } + Util.hideModal(); + }); +} function deleteHeartRateData() { Util.showModal("Deleting..."); From f63295adb7738eae6d4ff1b28d5df88a90f7f522 Mon Sep 17 00:00:00 2001 From: Elfreda Kwawu Date: Tue, 16 Apr 2024 17:51:36 -0400 Subject: [PATCH 40/52] edit interface.html --- apps/phystrax/interface.html | 118 ++++++++++++++++++++++++----------- 1 file changed, 80 insertions(+), 38 deletions(-) diff --git a/apps/phystrax/interface.html b/apps/phystrax/interface.html index d9007967f..342d99f14 100644 --- a/apps/phystrax/interface.html +++ b/apps/phystrax/interface.html @@ -7,49 +7,91 @@ From f41e7c15edf88ada97166a9118bb79e31c6176dc Mon Sep 17 00:00:00 2001 From: Elfreda Kwawu Date: Tue, 16 Apr 2024 18:15:54 -0400 Subject: [PATCH 41/52] testing --- apps/phystrax/app.js | 24 ++------- apps/phystrax/interface.html | 101 ++++++++++------------------------- 2 files changed, 33 insertions(+), 92 deletions(-) diff --git a/apps/phystrax/app.js b/apps/phystrax/app.js index b2eb31260..9d2836d8a 100644 --- a/apps/phystrax/app.js +++ b/apps/phystrax/app.js @@ -37,9 +37,9 @@ function handleHeartRate(hrm) { currentHR = hrm.bpm; let currentTime = Date.now(); let elaspedTime = currentTime - lastLogTime; - let nextLog = 5 * 1000 - (elaspedTime % (5 * 1000)); // Calculate time to next log - if (elaspedTime >= 5 * 1000) { // Check if it's time for the next log - lastLogTime = currentTime - (elaspedTime % (5 * 1000)); // Set last log time to the previous 5-second boundary + let nextLog = 3000 - (elaspedTime % 3000); // Calculate time to next log (3 seconds) + if (elaspedTime >= 3000) { // Check if it's time for the next log + lastLogTime = currentTime - (elaspedTime % 3000); // Set last log time to the previous 3-second boundary let date = new Date(lastLogTime); let dateStr = require("locale").date(date); let timeStr = require("locale").time(date, 1); @@ -143,22 +143,8 @@ function saveDataToCSV() { csvContent += `${entry.timestamp},${entry.heartRate},${entry.hrv}\n`; }); - // Check if the file already exists - let fileNum = 0; - let fileName = `heart_rate_data_${fileNum}.csv`; - while (require("Storage").read(fileName) !== undefined && fileNum <= MAX_LOGS) { - fileNum++; - fileName = `heart_rate_data_${fileNum}.csv`; - } - - // Prompt user for confirmation before overwriting existing file - if (require("Storage").read(fileName) !== undefined) { - if (!confirm("Overwrite existing file?")) { - return; // Do not overwrite file if user cancels - } - } - // Write data to the CSV file + let fileName = "heart_rate_data.csv"; // Use consistent file name require("Storage").write(fileName, csvContent); } @@ -171,4 +157,4 @@ setWatch(function() { } }, BTN1, { repeat: true, edge: 'rising' }); -drawScreen(); +drawScreen(); \ No newline at end of file diff --git a/apps/phystrax/interface.html b/apps/phystrax/interface.html index 342d99f14..5ceb53e68 100644 --- a/apps/phystrax/interface.html +++ b/apps/phystrax/interface.html @@ -9,87 +9,42 @@ From e0efdc75eaa0939fb755f54ac65ce04dc0909385 Mon Sep 17 00:00:00 2001 From: Elfreda Kwawu Date: Tue, 16 Apr 2024 18:28:37 -0400 Subject: [PATCH 42/52] testing interface --- apps/phystrax/interface.html | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/apps/phystrax/interface.html b/apps/phystrax/interface.html index 5ceb53e68..9b2e3890b 100644 --- a/apps/phystrax/interface.html +++ b/apps/phystrax/interface.html @@ -20,10 +20,11 @@ function saveHeartRateData() { Util.saveCSV(fileName, csvContent, function(success) { if (success) { dataElement.innerHTML = "

Heart rate data saved successfully

"; + Util.hideModal(); // Move hideModal() call inside the success callback } else { dataElement.innerHTML = "

Error saving heart rate data

"; + Util.hideModal(); // Move hideModal() call inside the error callback } - Util.hideModal(); }); } @@ -36,7 +37,7 @@ function deleteHeartRateData() { } else { dataElement.innerHTML = "

Error deleting heart rate data

"; } - Util.hideModal(); + Util.hideModal(); // Always hide the modal after the operation completes }); } From 01a5d2c238b20e3f6acf24861fc13f701ca841fd Mon Sep 17 00:00:00 2001 From: Elfreda Kwawu Date: Tue, 16 Apr 2024 18:56:01 -0400 Subject: [PATCH 43/52] edit interface file --- apps/phystrax/interface.html | 51 +++++++++++++++--------------------- 1 file changed, 21 insertions(+), 30 deletions(-) diff --git a/apps/phystrax/interface.html b/apps/phystrax/interface.html index 9b2e3890b..92dad7d0b 100644 --- a/apps/phystrax/interface.html +++ b/apps/phystrax/interface.html @@ -9,43 +9,34 @@ From fdf7b1b117454e9f56ef6772eb167ff0a6c7cd0b Mon Sep 17 00:00:00 2001 From: Elfreda Kwawu Date: Wed, 17 Apr 2024 10:57:45 -0400 Subject: [PATCH 44/52] edit app + interface file --- apps/phystrax/app.js | 6 ++-- apps/phystrax/interface.html | 67 +++++++++++++++++++++++------------- 2 files changed, 47 insertions(+), 26 deletions(-) diff --git a/apps/phystrax/app.js b/apps/phystrax/app.js index 9d2836d8a..4c89f02d1 100644 --- a/apps/phystrax/app.js +++ b/apps/phystrax/app.js @@ -145,10 +145,10 @@ function saveDataToCSV() { // Write data to the CSV file let fileName = "heart_rate_data.csv"; // Use consistent file name - require("Storage").write(fileName, csvContent); + var file = require("Storage").open(fileName,"a"); // Open file in append mode + file.write(csvContent); } - setWatch(function() { if (!isMeasuring) { startMeasure(); @@ -157,4 +157,4 @@ setWatch(function() { } }, BTN1, { repeat: true, edge: 'rising' }); -drawScreen(); \ No newline at end of file +drawScreen(); diff --git a/apps/phystrax/interface.html b/apps/phystrax/interface.html index 92dad7d0b..fb550cb21 100644 --- a/apps/phystrax/interface.html +++ b/apps/phystrax/interface.html @@ -4,39 +4,60 @@
+ + From de7d6e82934571916503ea99350f53dcc58a4045 Mon Sep 17 00:00:00 2001 From: Elfreda Kwawu Date: Wed, 17 Apr 2024 12:08:50 -0400 Subject: [PATCH 45/52] updated app.js --- apps/phystrax/app.js | 23 +++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/apps/phystrax/app.js b/apps/phystrax/app.js index 4c89f02d1..3f0191797 100644 --- a/apps/phystrax/app.js +++ b/apps/phystrax/app.js @@ -4,9 +4,9 @@ let lcdTimeout; let logData = []; let bpmValues = []; let lastLogTime = 0; -const MAX_LOGS = 9; function startMeasure() { + logData = []; isMeasuring = true; Bangle.setLCDTimeout(0); lcdTimeout = setTimeout(() => { @@ -33,8 +33,7 @@ function stopMeasure() { } function handleHeartRate(hrm) { - if (hrm.confidence > 90) { - currentHR = hrm.bpm; + if (isMeasuring && hrm.confidence > 85) { let currentTime = Date.now(); let elaspedTime = currentTime - lastLogTime; let nextLog = 3000 - (elaspedTime % 3000); // Calculate time to next log (3 seconds) @@ -45,6 +44,8 @@ function handleHeartRate(hrm) { let timeStr = require("locale").time(date, 1); let seconds = date.getSeconds(); let timestamp = `${dateStr} ${timeStr}:${seconds}`; // Concatenate date, time, and seconds + currentHR = hrm.bpm; + logData.push({ timestamp: timestamp, heartRate: currentHR }); bpmValues.push(currentHR); // Store heart rate for HRV calculation if (bpmValues.length > 30) bpmValues.shift(); // Keep last 30 heart rate values @@ -118,9 +119,9 @@ function drawScreen(message) { g.drawString('Press button to stop', g.getWidth() / 2, g.getHeight() / 2 + 42); } else { // Draw last heart rate - g.setFont('Vector', 12); - g.drawString('Last Heart Rate:', g.getWidth() / 2, g.getHeight() / 2 - 20); if (currentHR !== null && currentHR > 0) { + g.setFont('Vector', 12); + g.drawString('Last Heart Rate:', g.getWidth() / 2, g.getHeight() / 2 - 20); g.setFont('6x8', 4); g.drawString(currentHR.toString(), g.getWidth() / 2, g.getHeight() / 2 + 10); g.setFont('6x8', 1.6); @@ -140,15 +141,17 @@ function drawScreen(message) { function saveDataToCSV() { let csvContent = "Timestamp,Heart Rate(bpm),HRV(ms)\n"; logData.forEach(entry => { - csvContent += `${entry.timestamp},${entry.heartRate},${entry.hrv}\n`; + // Scale HRV - placeholder + let scaledHRV = entry.hrv * 13.16; + csvContent += `${entry.timestamp},${entry.heartRate},${scaledHRV}\n`; }); - // Write data to the CSV file - let fileName = "heart_rate_data.csv"; // Use consistent file name - var file = require("Storage").open(fileName,"a"); // Open file in append mode - file.write(csvContent); + // Write data to the CSV file with the desired file name + let fileName = "heart_rate_data.csv"; + require("Storage").write(fileName, csvContent); } + setWatch(function() { if (!isMeasuring) { startMeasure(); From f6e172b616aedc5585178105222d1298136ff113 Mon Sep 17 00:00:00 2001 From: Elfreda Kwawu Date: Wed, 17 Apr 2024 12:44:47 -0400 Subject: [PATCH 46/52] edit app.js for file storage --- apps/phystrax/app.js | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/apps/phystrax/app.js b/apps/phystrax/app.js index 3f0191797..33c6f23d2 100644 --- a/apps/phystrax/app.js +++ b/apps/phystrax/app.js @@ -128,7 +128,7 @@ function drawScreen(message) { g.drawString(' BPM', g.getWidth() / 2 + 42, g.getHeight() / 2 + 12); } else { g.setFont('6x8', 2); - g.drawString('No data', g.getWidth() / 2, g.getHeight() / 2 + 10); + g.drawString('No data', g.getWidth() / 2, g.getHeight() / 2 + 5); g.setFont('6x8', 1); g.drawString(message || 'Press button to start', g.getWidth() / 2, g.getHeight() / 2 + 30); } @@ -139,19 +139,22 @@ function drawScreen(message) { } function saveDataToCSV() { - let csvContent = "Timestamp,Heart Rate(bpm),HRV(ms)\n"; + let fileName = "heart_rate_data.csv"; + let file = require("Storage").open(fileName, "a"); // Open the file for appending + + // Check if the file is empty (i.e., newly created) + if (file.getLength() === 0) { + // Write the header if the file is empty + file.write("Timestamp,Heart Rate(bpm),HRV(ms)\n"); + } + + // Append the data logData.forEach(entry => { - // Scale HRV - placeholder - let scaledHRV = entry.hrv * 13.16; - csvContent += `${entry.timestamp},${entry.heartRate},${scaledHRV}\n`; + file.write(`${entry.timestamp},${entry.heartRate},${entry.hrv}\n`); }); - // Write data to the CSV file with the desired file name - let fileName = "heart_rate_data.csv"; - require("Storage").write(fileName, csvContent); } - setWatch(function() { if (!isMeasuring) { startMeasure(); From 56ac7aa297dfd7a794409a583cbbfc4bdc6d988e Mon Sep 17 00:00:00 2001 From: Elfreda Kwawu Date: Wed, 17 Apr 2024 12:53:29 -0400 Subject: [PATCH 47/52] slight app.js tweaking --- apps/phystrax/app.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/apps/phystrax/app.js b/apps/phystrax/app.js index 33c6f23d2..56ab61cd0 100644 --- a/apps/phystrax/app.js +++ b/apps/phystrax/app.js @@ -150,7 +150,8 @@ function saveDataToCSV() { // Append the data logData.forEach(entry => { - file.write(`${entry.timestamp},${entry.heartRate},${entry.hrv}\n`); + let scaledHRV = entry.hrv * 13.61; + file.write(`${entry.timestamp},${entry.heartRate},${scaledHRV}\n`); }); } From 2b8471cc3607e8cc8760fb6d358796ac6e61e1fb Mon Sep 17 00:00:00 2001 From: Elfreda Kwawu Date: Thu, 18 Apr 2024 14:28:40 -0400 Subject: [PATCH 48/52] increased confidence interval --- apps/phystrax/app.js | 37 ++++++++++++++----------------------- 1 file changed, 14 insertions(+), 23 deletions(-) diff --git a/apps/phystrax/app.js b/apps/phystrax/app.js index 56ab61cd0..d2ba21ee6 100644 --- a/apps/phystrax/app.js +++ b/apps/phystrax/app.js @@ -33,30 +33,21 @@ function stopMeasure() { } function handleHeartRate(hrm) { - if (isMeasuring && hrm.confidence > 85) { - let currentTime = Date.now(); - let elaspedTime = currentTime - lastLogTime; - let nextLog = 3000 - (elaspedTime % 3000); // Calculate time to next log (3 seconds) - if (elaspedTime >= 3000) { // Check if it's time for the next log - lastLogTime = currentTime - (elaspedTime % 3000); // Set last log time to the previous 3-second boundary - let date = new Date(lastLogTime); - let dateStr = require("locale").date(date); - let timeStr = require("locale").time(date, 1); - let seconds = date.getSeconds(); - let timestamp = `${dateStr} ${timeStr}:${seconds}`; // Concatenate date, time, and seconds - currentHR = hrm.bpm; + if (isMeasuring && hrm.confidence > 90) { + let date = new Date(); + let dateStr = require("locale").date(date); + let timeStr = require("locale").time(date, 1); + let seconds = date.getSeconds(); + let timestamp = `${dateStr} ${timeStr}:${seconds}`; // Concatenate date, time, and seconds + currentHR = hrm.bpm; - logData.push({ timestamp: timestamp, heartRate: currentHR }); - bpmValues.push(currentHR); // Store heart rate for HRV calculation - if (bpmValues.length > 30) bpmValues.shift(); // Keep last 30 heart rate values - // Calculate and add SDNN (standard deviation of NN intervals) to the last log entry - logData[logData.length - 1].hrv = calcSDNN(); - drawScreen(); - } - // Schedule next measurement - setTimeout(() => { - handleHeartRate(hrm); - }, nextLog); + logData.push({ timestamp: timestamp, heartRate: currentHR }); + bpmValues.push(currentHR); // Store heart rate for HRV calculation + if (bpmValues.length > 30) bpmValues.shift(); // Keep last 30 heart rate values + // Calculate and add SDNN (standard deviation of NN intervals) to the last log entry + logData[logData.length - 1].hrv = calcSDNN(); + drawScreen(); + } } From 47ed20f7fbf083ff62e29bf1e1ca512d86e17609 Mon Sep 17 00:00:00 2001 From: Elfreda Kwawu Date: Sun, 21 Apr 2024 14:56:50 -0400 Subject: [PATCH 49/52] made final changes --- apps/phystrax/ChangeLog | 1 + apps/phystrax/app.js | 1 - 2 files changed, 1 insertion(+), 1 deletion(-) create mode 100644 apps/phystrax/ChangeLog diff --git a/apps/phystrax/ChangeLog b/apps/phystrax/ChangeLog new file mode 100644 index 000000000..3bc4ef732 --- /dev/null +++ b/apps/phystrax/ChangeLog @@ -0,0 +1 @@ +0.01: New App. \ No newline at end of file diff --git a/apps/phystrax/app.js b/apps/phystrax/app.js index d2ba21ee6..e51d0ab7f 100644 --- a/apps/phystrax/app.js +++ b/apps/phystrax/app.js @@ -3,7 +3,6 @@ let currentHR = null; let lcdTimeout; let logData = []; let bpmValues = []; -let lastLogTime = 0; function startMeasure() { logData = []; From fe4939cbb7092ff0a08b304f2cd0d6ab6735fc9c Mon Sep 17 00:00:00 2001 From: Elfreda Kwawu Date: Mon, 22 Apr 2024 10:40:24 -0400 Subject: [PATCH 50/52] does not need to specify wildcard pattern --- apps/phystrax/metadata.json | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/apps/phystrax/metadata.json b/apps/phystrax/metadata.json index 58e0197b5..68a2cde56 100644 --- a/apps/phystrax/metadata.json +++ b/apps/phystrax/metadata.json @@ -11,6 +11,5 @@ "storage": [ {"name":"phystrax.app.js","url":"app.js"}, {"name":"phystrax.img","url":"app-icon.js","evaluate":true} - ], - "data": [{"wildcard":"heart_rate_data.?.csv"}] + ] } \ No newline at end of file From d9e51ddbde0fc6dffa70e6a1855c7d118f608892 Mon Sep 17 00:00:00 2001 From: Elfreda Kwawu Date: Mon, 22 Apr 2024 15:44:38 -0400 Subject: [PATCH 51/52] Added data entry --- apps/phystrax/metadata.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/apps/phystrax/metadata.json b/apps/phystrax/metadata.json index 68a2cde56..c9e41b1db 100644 --- a/apps/phystrax/metadata.json +++ b/apps/phystrax/metadata.json @@ -11,5 +11,6 @@ "storage": [ {"name":"phystrax.app.js","url":"app.js"}, {"name":"phystrax.img","url":"app-icon.js","evaluate":true} - ] + ], + "data": [{"wildcard":"phystrax_hrm.?.csv"}] } \ No newline at end of file From 261776b3cb4a99c713852343f00fd2a6031d8006 Mon Sep 17 00:00:00 2001 From: Rob Pilling Date: Mon, 22 Apr 2024 20:48:43 +0100 Subject: [PATCH 52/52] phystrax: rename CSV, heart_rate_data -> phystrax_hrm --- apps/phystrax/app.js | 4 ++-- apps/phystrax/interface.html | 6 +++--- apps/phystrax/metadata.json | 4 ++-- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/apps/phystrax/app.js b/apps/phystrax/app.js index e51d0ab7f..3ecb5d04e 100644 --- a/apps/phystrax/app.js +++ b/apps/phystrax/app.js @@ -46,7 +46,7 @@ function handleHeartRate(hrm) { // Calculate and add SDNN (standard deviation of NN intervals) to the last log entry logData[logData.length - 1].hrv = calcSDNN(); drawScreen(); - + } } @@ -129,7 +129,7 @@ function drawScreen(message) { } function saveDataToCSV() { - let fileName = "heart_rate_data.csv"; + let fileName = "phystrax_hrm.csv"; let file = require("Storage").open(fileName, "a"); // Open the file for appending // Check if the file is empty (i.e., newly created) diff --git a/apps/phystrax/interface.html b/apps/phystrax/interface.html index fb550cb21..4d1933df6 100644 --- a/apps/phystrax/interface.html +++ b/apps/phystrax/interface.html @@ -17,7 +17,7 @@ function getData() { Util.showModal("Loading..."); // get the data dataElement.innerHTML = ""; - Util.readStorageFile(`heart_rate_data.csv`,data=>{ + Util.readStorageFile(`phystrax_hrm.csv`,data=>{ csvData = data.trim(); // remove window Util.hideModal(); @@ -45,12 +45,12 @@ function getData() { // You can call a utility function to save the data document.getElementById("btnSave").addEventListener("click", function() { - Util.saveCSV("heart_rate_data.csv", csvData); + Util.saveCSV("phystrax_hrm.csv", csvData); }); // Or you can also delete the file document.getElementById("btnDelete").addEventListener("click", function() { Util.showModal("Deleting..."); - Util.eraseStorageFile("heart_rate_data.csv", function() { + Util.eraseStorageFile("phystrax_hrm.csv", function() { Util.hideModal(); getData(); }); diff --git a/apps/phystrax/metadata.json b/apps/phystrax/metadata.json index c9e41b1db..bcc0be70d 100644 --- a/apps/phystrax/metadata.json +++ b/apps/phystrax/metadata.json @@ -12,5 +12,5 @@ {"name":"phystrax.app.js","url":"app.js"}, {"name":"phystrax.img","url":"app-icon.js","evaluate":true} ], - "data": [{"wildcard":"phystrax_hrm.?.csv"}] -} \ No newline at end of file + "data": [{"name":"phystrax_hrm.csv"}] +}