Merge remote-tracking branch 'upstream/master'

master
hughbarney 2021-02-03 19:03:45 +00:00
commit 15c95bf538
9 changed files with 282 additions and 3 deletions

View File

@ -1341,7 +1341,7 @@
"name": "Active Pedometer",
"shortName":"Active Pedometer",
"icon": "app.png",
"version":"0.07",
"version":"0.08",
"description": "Pedometer that filters out arm movement and displays a step goal progress. Steps are saved to a daily file and can be viewed as graph.",
"tags": "outdoors,widget",
"readme": "README.md",
@ -2189,6 +2189,23 @@
{"wildcard":"accelrec.?.csv" }
]
},
{ "id": "accellog",
"name": "Acceleration Logger",
"shortName":"Accel Log",
"icon": "app.png",
"version":"0.01",
"interface": "interface.html",
"description": "Logs XYZ acceleration data to a CSV file that can be downloaded to your PC",
"tags": "outdoor",
"readme": "README.md",
"storage": [
{"name":"accellog.app.js","url":"app.js"},
{"name":"accellog.img","url":"app-icon.js","evaluate":true}
],
"data": [
{"wildcard":"accellog.?.csv" }
]
},
{
"id": "cprassist",
"name":"CPR Assist",

1
apps/accellog/ChangeLog Normal file
View File

@ -0,0 +1 @@
0.01: New App!

19
apps/accellog/README.md Normal file
View File

@ -0,0 +1,19 @@
# Acceleration Logger
Logs XYZ acceleration data (at the normal 12.5Hz) to a CSV file that can be downloaded to your PC.
## Usage
* Run the app 'Accel Log' from Bangle.js menu
* Optionally choose a file number if you want to record to multiple different files.
* Choose `Start`
* Acceleration data will now be recording
* When you're done, press `BTN2`
## Downloading Data
* Go to the Bangle.js App Loader
* Connect to your Bangle
* Under `My Apps` look for `Acceleration Logger`
* You'll see a download arrow next to it - click that
* You can now choose to Save or Delete each track you have recorded

View File

@ -0,0 +1 @@
require("heatshrink").decompress(atob("oFAwhC/AH4A2xAedhGIwA+dAAI+dAAJAcEAJ/fD/4f5hAJIYSo6JIihaKxBATxAACC4YnBAAQ+TD7o/CFRJfTP5a/eb6pEOD/7JFwczAA0ybgwfUkUjD4QaDD6syiMSD4ZABCIa8JD547BCIY/ZHQQ+LD6Z/cHZYf/f6E4D6uCD4gACD6wgBkQACBAYfWABYf/D/4fPwf/ABgf/D6czABBf/P/5f/P/5f/D+WIABwfuAH4A/ADo="))

132
apps/accellog/app.js Normal file
View File

@ -0,0 +1,132 @@
var fileNumber = 0;
var MAXLOGS = 9;
function getFileName(n) {
return "accellog."+n+".csv";
}
function showMenu() {
var menu = {
"" : { title : "Accel Logger" },
"File No" : {
value : fileNumber,
min : 0,
max : MAXLOGS,
onchange : v => { fileNumber=v; }
},
"Start" : function() {
E.showMenu();
startRecord();
},
"View Logs" : function() {
viewLogs();
},
"Exit" : function() {
load();
},
};
E.showMenu(menu);
}
function viewLog(n) {
E.showMessage("Loading...");
var f = require("Storage").open(getFileName(n), "r");
var records = 0, l = "", ll="";
while ((l=f.readLine())!==undefined) {records++;ll=l;}
var length = 0;
if (ll) length = (ll.split(",")[0]|0)/1000;
var menu = {
"" : { title : "Log "+n }
};
menu[records+" Records"] = "";
menu[length+" Seconds"] = "";
menu["DELETE"] = function() {
E.showPrompt("Delete Log "+n).then(ok=>{
if (ok) {
E.showMessage("Erasing...");
f.erase();
viewLogs();
} else viewLog(n);
});
};
menu["< Back"] = function() {
viewLogs();
};
E.showMenu(menu);
}
function viewLogs() {
var menu = {
"" : { title : "Logs" }
};
var hadLogs = false;
for (var i=0;i<=MAXLOGS;i++) {
var f = require("Storage").open(getFileName(i), "r");
if (f.readLine()!==undefined) {
(function(i) {
menu["Log "+i] = () => viewLog(i);
})(i);
hadLogs = true;
}
}
if (!hadLogs)
menu["No Logs Found"] = function(){};
menu["< Back"] = function() { showMenu(); };
E.showMenu(menu);
}
function startRecord(force) {
if (!force) {
// check for existing file
var f = require("Storage").open(getFileName(fileNumber), "r");
if (f.readLine()!==undefined)
return E.showPrompt("Overwrite Log "+fileNumber+"?").then(ok=>{
if (ok) startRecord(true); else showMenu();
});
}
// display
g.clear(1);
Bangle.drawWidgets();
var w = g.getWidth();
var h = g.getHeight();
g.setColor("#ff0000").fillRect(0,h-48,w,h);
g.setColor("#ffffff").setFont("6x8",2).setFontAlign(0,0).drawString("RECORDING", w/2,h-24);
g.setFont("6x8").drawString("Samples:",w/2,h/3 - 20);
g.setFont("6x8").drawString("Time:",w/2,h*2/3 - 20);
g.setFont("6x8",2).setFontAlign(0,0,1).drawString("STOP",w-10,h/2);
// now start writing
f = require("Storage").open(getFileName(fileNumber), "w");
f.write("Time (ms),X,Y,Z\n");
var start = getTime();
var sampleCount = 0;
function accelHandler(accel) {
var t = getTime()-start;
f.write([
t*1000,
accel.x*8192,
accel.y*8192,
accel.z*8192].map(n=>Math.round(n)).join(",")+"\n");
sampleCount++;
g.reset().setFont("6x8",2).setFontAlign(0,0);
g.drawString(" "+sampleCount+" ",w/2,h/3,true);
g.drawString(" "+Math.round(t)+"s ",w/2,h*2/3,true);
}
Bangle.setPollInterval(80); // 12.5 Hz
Bangle.on('accel', accelHandler);
setWatch(()=>{
Bangle.removeListener('accel', accelHandler);
showMenu();
}, BTN2);
}
Bangle.loadWidgets();
Bangle.drawWidgets();
showMenu();

BIN
apps/accellog/app.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

View File

@ -0,0 +1,107 @@
<html>
<head>
<link rel="stylesheet" href="../../css/spectre.min.css">
</head>
<body>
<div id="data"></div>
<script src="../../core/lib/interface.js"></script>
<script>
var dataElement = document.getElementById("data");
function getData() {
// show loading window
Util.showModal("Loading...");
// get the data
dataElement.innerHTML = "";
var promise = Promise.resolve();
Puck.eval('require("Storage").list(/accellog\\..\\.csv\\x01/)',files=>{
if (files.length==0) {
dataElement.innerHTML = "<p>No saved data</p>";
} else {
files.forEach(fn => {
fn = fn.slice(0,-1);
dataElement.innerHTML += `
<div class="card">
<div class="card-header">
<div class="card-title h5">${fn}</div>
</div>
<div class="card-footer">
<button class="btn btn-primary" fn="${fn}" act="save">Save</button>
<button class="btn" fn="${fn}" act="delete">Delete</button>
</div>
</div>`;
promise = promise.then(function() {
document.querySelector(`.btn[fn='${fn}'][act='save']`).addEventListener("click", function() {
Util.readStorageFile(fn, function(data) {
Util.saveCSV(fn.slice(0,-4), data);
});
});
document.querySelector(`.btn[fn='${fn}'][act='delete']`).addEventListener("click", function() {
Util.showModal("Deleting...");
Util.eraseStorageFile(fn, function() {
Util.hideModal();
getData();
});
});
return new Promise(resolve=>{
Puck.eval(`require("Storage").read(${JSON.stringify(fn)})`,csv=>{
fileData[fn] = csv.trim();
var el = document.querySelector(`.card-body[fn='${fn}']`);
el.innerHTML = '<canvas width="400" height="100"></canvas>';
var c = el.firstChild;
var ctx = c.getContext("2d");
var lines = csv.split("\n");
var y = 50, sx = 400/lines.length, sy = 50/8;
function plot(n) {
var last;
ctx.beginPath();
lines.map((l,x)=>{
l = l.split(",");
var yc = y + parseFloat(l[n])*sy;
if (!last) {
ctx.moveTo(0, yc);
} else {
ctx.lineTo(x*sx, yc);
}
last = l;
});
ctx.stroke();
};
ctx.strokeStyle = 'red';
plot(0);
ctx.strokeStyle = 'green';
plot(1);
ctx.strokeStyle = 'blue';
plot(2);
resolve();
});
});
});
});
}
// remove window
Util.hideModal();
});
}
// You can call a utility function to save the data
/*document.getElementById("btnSave").addEventListener("click", function() {
Util.saveCSV("gpsdata", csvData);
});
// Or you can also delete the file
document.getElementById("btnDelete").addEventListener("click", function() {
Util.showModal("Deleting...");
Util.eraseStorageFile("gpspoilog.csv", function() {
Util.hideModal();
getData();
});
});*/
// Called when app starts
function onInit() {
getData();
}
</script>
</body>
</html>

View File

@ -1,7 +1,8 @@
# Acceleration Recorder
This app records a short period of acceleration data from the accelerometer
and
This app records a short period of acceleration data from the accelerometer at
100Hz (starting when acceleration happens) and graphs it, working out max acceleration
and max velocity. Data can also be downloaded to your PC.
## Usage

View File

@ -5,3 +5,4 @@
0.05: Fix default step/distance display if it hasn't been set up first
0.06: Added WIDGETS.activepedom.getSteps()
0.07: Added settings to be able to hide line1 and line2 so there is no visible widget
0.08: Fixed zero steps issue caused by 0.07