Merge pull request #3049 from jabituyaben/master

added support for hr raw exporter and astral clock to bangle.js 2
pull/3064/head
Gordon Williams 2023-10-27 10:09:10 +01:00 committed by GitHub
commit fbfb087e07
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 742 additions and 624 deletions

View File

@ -4,3 +4,4 @@
0.04: Tell clock widgets to hide.
0.05: Added adjustment for Bangle.js magnetometer heading fix
0.06: optimized to update much faster
0.07: added support for bangle.js 2

View File

@ -1,29 +1,29 @@
Astral Clock
============
NOTE FOR THE BANGLE 2 THIS APP ONLY SUPPORTS USING THE BLACK BACKGROUND CURRENTLY
Clock that calculates and displays Alt Az positions of all planets, Sun as well as several other astronomy targets (customizable) and current Moon phase. Coordinates are calculated by GPS & time and onscreen compass assists orienting.
![screenshot](./Example.PNG)
<sup>(The clock does have Pluto now - felt bad for leaving it out)</sup>
Functions
---------
**BTN1**: Refreshes Alt/Az readings. The coordinates are NOT continually updated, this is to save resources and battery usage plus it avoids you having to wait for calculations to finish before you can do anything else on the watch - it doesn't take long but it could still be annoying.
**BTN2**: Load side-menu as standard for clocks.
**BTN3**: Changes between planet mode and extra/other targets - discussed below (will still need to press button 1 after switching to update calcs).
**BTN4**: This is the left touchscreen, and when the LCD is on you can use this to change the font between red/white. This will only work after the GPS location has been set initially.
---------
**BTN2**: Load side-menu as standard for clocks.
Swiping left or right will alternate between planets and other astronomy targets, see below for how to change these addtional ones.
The text will turn blue during calculation and then back again once complete.
The data is refreshed automatically every 2 minutes. You can force a refresh as well by swiping up or, on Bangle 1, pressing Button 3.
When you first install it, all positions will be estimated from UK as the default location and all the text will be white; from the moment you get your first GPS lock with the clock, it will save your location, recalculate accordingly and change the text to red, ideal for maintaining night vision, the calculations will also now be relevant to your location and time. If you have not used the GPS yet, I suggest using it outside briefly to get your first fix as the initial one can take a bit longer, although it should still just be a minute or 2 max normally.
Swiping down will disable/enable the compass and GPS.
When you first install it, all positions will be estimated from UK as the default location and all the text will be white; from the moment you get your first GPS lock with the clock, it will save your location, recalculate accordingly and change the text to red, ideal for maintaining night vision. One the Bangle.JS 2, the colour will be a light blue rather than red because the colours are not as vibrant. The calculations will also now be relevant to your location and time. If you have not used the GPS yet, I suggest using it outside briefly to get your first fix as the initial one can take a bit longer, although it should still just be a minute or 2 max normally.
Lat and Lon are saved in a file called **astral.config**. You can review this file if you want to confirm current coordinates or even hard set different values \- although be careful doing the latter as there is no error handling to manage bad values here so you would have to delete the file and have the app generate a new one if that happens, also the GPS functionality will overwrite anything you put in here once it picks up your location.
There can currently be a slight error mainly to the Az at times due to a firmware issue for acos (arccosine) that affect spherical calculations but I have used an estimator function that gives a good enough accuracy for general observation so shouldn't noticeably be too far off. I\'ll be implementing acos for better accuracy when the fix is in a standard release and the update will still include the current estimate function to support a level of backward compatibility.
The moon phases are split into the 8 phases with an image for each - new moon would show no image.
The compass is displayed above the minute digits, if you get strange values or dashes the compass needs calibration but you just need to move the watch around a bit for this each time - ideally 360 degrees around itself, which involves taking the watch off. If you don't want to do that you can also just wave your hand around for a few seconds like you're at a rave or doing Wing Chun Kuen.
The compass is displayed on the left.
Also the compass isn\t tilt compensated so try and keep the face parallel when taking a reading.
Also the compass isn\t tilt compensated so try and keep the face parallel when taking a reading. It's more of an indicator, for a more accurate compass reading, you can use one of the many great apps in the apploader that compensated for movement and angles of the watch etc.
Additional Astronomy Targets
----------------------------
@ -37,7 +37,7 @@ The type property is not utilised as yet but relates to whether the object is (i
Updates & Feedback
------------------
Put together, initially at least, by \"Ben Jabituya\", https://jabituyaben.wixsite.com/majorinput, jabituyaben@gmail.com. Feel free to get in touch for any feature request. Also I\'m not precious at all - if you know of efficiencies or improvements you could make, just put the changes in. One thing that would probably be ideal is to change some of the functions to inline C to make it faster.
Put together, initially at least, by \"Ben Jabituya\", https://majorinput.co.uk, jabituyaben@gmail.com.
Credit to various sources from which I have literally taken source code and shoehorned to fit on the Bangle:

File diff suppressed because it is too large Load Diff

View File

@ -1,13 +1,13 @@
{
"id": "astral",
"name": "Astral Clock",
"version": "0.06",
"version": "0.07",
"description": "Clock that calculates and displays Alt Az positions of all planets, Sun as well as several other astronomy targets (customizable) and current Moon phase. Coordinates are calculated by GPS & time and onscreen compass assists orienting. See Readme before using.",
"icon": "app-icon.png",
"type": "clock",
"tags": "clock",
"supports": ["BANGLEJS"],
"readme": "README.md",
"supports": ["BANGLEJS","BANGLEJS2"],
"storage": [
{"name":"astral.app.js","url":"app.js"},
{"name":"astral.img","url":"app-icon.js","evaluate":true}

View File

@ -1,3 +1,4 @@
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
0.04: added support for bangle.js 2

View File

@ -1,13 +1,20 @@
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 and record data to a csv file.
Updated to work with new API. Additional capability includes:
Updated to work with new API and includes support for Bangle.js 2. Additional capability includes:
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:
-The hrm sensor is sampled @50Hz on the Bangle.JS 1 and 25Hz on the Bangle 2 by default. At least on the Bangle 2 you can change the sample rate by using the 'custom boot code' app and running this line:
Bangle.setOptions({hrmPollInterval:20});­
the 20 in the boot code means the hrm will poll every 20ms (50Hz) instead of the default 40.
4. On the bangle.JS 2 you can swipe up to begin recording, and on the Bangle.JS 1 you just use the top button.
For Bangle 1, 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. I will be working on a method for Bangle 2 because the data seems more noisy so will need a different processing method:
https://github.com/jabituyaben/BangleJS-HRM-Signal-Processing

View File

@ -8,6 +8,9 @@ var fileClosed = 0;
var Storage = require("Storage");
var file;
var screenSize = g.getHeight();
function exists(name){
s = require('Storage');
var fileList = s.list();
@ -23,28 +26,27 @@ function exists(name){
function update_timer() {
g.clear();
g.setColor("#00ff7f");
g.setColor("#CC00CC");
g.setFont("6x8", 4);
g.setFontAlign(0, 0); // center font
g.drawString(counter, 120, 120);
g.drawString(counter, screenSize/2, screenSize/2);
g.setFont("6x8", 2);
g.setFontAlign(-1, -1);
g.drawString("-", 220, 200);
g.drawString("+", 220, 40);
g.drawString("GO", 210, 120);
g.setColor("#ffffff");
g.setFontAlign(0, 0); // center font
g.drawString("Timer (minutes)", 120, 90);
g.setFont("6x8", 4); // bitmap font, 8x magnified
//g.setFontAlign(-1, -1);
g.drawString("+", screenSize-10, screenSize/2);
g.drawString("-", 10, screenSize/2);
g.drawString("GO",screenSize/2 , (screenSize/2)+(screenSize/5));
//g.setColor("#ffffff");
//g.setFontAlign(0, 0); // center font
g.drawString("Timer(minutes)", screenSize/2+5,screenSize/4 );
g.setFont("6x8", 4);
g.drawString("^",screenSize/2 , 150);
if (!logging_started)
g.flip();
}
function btn1Pressed() {
function btn2Pressed() {
if (!logging_started) {
if (counter < 120)
counter += 15;
@ -64,7 +66,7 @@ function btn3Pressed() {
}
}
function btn2Pressed() {
function btn1Pressed() {
if (!logging_started) {
var filename = "";
var fileset = false;
@ -112,7 +114,7 @@ function countDown() {
if (counter <= 0 && fileClosed == 0) {
Bangle.setHRMPower(0);
clearInterval(interval);
g.drawString("Finished", g.getWidth() / 2, g.getHeight() / 2);
g.drawString("Done", g.getWidth() / 2, g.getHeight() / 2);
Bangle.buzz(500, 1);
fileClosed = 1;
}
@ -120,14 +122,36 @@ function countDown() {
g.drawString(fmtMSS(counter), g.getWidth() / 2, g.getHeight() / 2);
}
var HRVal = 0;
var HRConfidence = 0;
update_timer();
setWatch(btn1Pressed, BTN1, { repeat: true });
setWatch(btn2Pressed, BTN2, { repeat: true });
setWatch(btn3Pressed, BTN3, { repeat: true });
//setWatch(btn2Pressed, BTN2, { repeat: true });
//setWatch(btn3Pressed, BTN3, { repeat: true });
Bangle.on("swipe",function(directionLR, directionUD){
if (1==directionLR){
btn1Pressed();
}
else if (-1==directionUD || directionUD==1){
btn2Pressed();
}
else if(directionLR == -1){
btn3Pressed();
}
});
Bangle.on('HRM-raw', function (hrm) {
value = hrm.raw;
filt = hrm.filt;
file.write(value + "," + filt + "," + "\n");
//var dataArray = [value,filt,HRVal,HRConfidence];
file.write(value + "," + filt + "\n");
});
/*
Bangle.on('HRM', function (hrmB) {
HRVal = hrmB.bpm;
HRConfidence = hrmB.confidence;
});
*/

View File

@ -2,13 +2,13 @@
"id": "hrrawexp",
"name": "HRM Data Exporter",
"shortName": "HRM Data Exporter",
"version": "0.03",
"version": "0.04",
"description": "export raw hrm signal data to a csv file",
"icon": "app-icon.png",
"tags": "",
"supports": ["BANGLEJS"],
"readme": "README.md",
"interface": "interface.html",
"supports": ["BANGLEJS","BANGLEJS2"],
"storage": [
{"name":"hrrawexp.app.js","url":"app.js"},
{"name":"hrrawexp.img","url":"app-icon.js","evaluate":true}