2024-03-04 20:34:50 +00:00
|
|
|
//var acc;
|
2024-04-26 07:27:07 +00:00
|
|
|
var HZ = 100;
|
2024-07-02 18:35:55 +00:00
|
|
|
var SAMPLES = 5 * HZ; // 5 seconds
|
2024-04-29 16:24:44 +00:00
|
|
|
var SCALE = 2000;
|
|
|
|
var THRESH = 1.4;
|
2020-07-09 10:27:44 +00:00
|
|
|
var accelx = new Int16Array(SAMPLES);
|
|
|
|
var accely = new Int16Array(SAMPLES); // North
|
|
|
|
var accelz = new Int16Array(SAMPLES); // Into clock face
|
2024-04-20 22:22:43 +00:00
|
|
|
var timestep = new Int16Array(SAMPLES); // Into clock face
|
2020-07-09 10:27:44 +00:00
|
|
|
var accelIdx = 0;
|
2020-10-21 08:09:51 +00:00
|
|
|
var lastAccel;
|
2024-07-05 20:30:45 +00:00
|
|
|
var timestep_start = 0;
|
2024-07-02 18:35:55 +00:00
|
|
|
|
|
|
|
function accelHandlerTrigger(a) {
|
|
|
|
"ram"
|
|
|
|
if (a.mag * 2 > THRESH) { // *2 because 8g mode
|
2024-07-05 20:30:45 +00:00
|
|
|
timestep_start = getTime();
|
2024-07-02 18:35:55 +00:00
|
|
|
g.drawString("Recording", g.getWidth() / 2, g.getHeight() / 2, 1);
|
|
|
|
Bangle.removeListener('accel', accelHandlerTrigger);
|
|
|
|
Bangle.on('accel', accelHandlerRecord);
|
|
|
|
lastAccel.forEach(accelHandlerRecord);
|
|
|
|
accelHandlerRecord(a);
|
|
|
|
} else {
|
|
|
|
if (lastAccel.length > 10) lastAccel.shift();
|
|
|
|
lastAccel.push(a);
|
|
|
|
}
|
2020-07-09 10:27:44 +00:00
|
|
|
}
|
2024-07-02 18:35:55 +00:00
|
|
|
|
|
|
|
function accelHandlerRecord(a) {
|
|
|
|
"ram"
|
|
|
|
var i = accelIdx++;
|
|
|
|
accelx[i] = a.x * SCALE * 2; // *2 because of 8g mode
|
|
|
|
accely[i] = -a.y * SCALE * 2;
|
|
|
|
accelz[i] = a.z * SCALE * 2;
|
2024-07-05 20:30:45 +00:00
|
|
|
timestep[i] = (getTime() - timestep_start) * 1000;
|
2024-07-02 18:35:55 +00:00
|
|
|
if (accelIdx >= SAMPLES) recordStop();
|
2020-07-09 10:27:44 +00:00
|
|
|
}
|
2024-07-02 18:35:55 +00:00
|
|
|
|
|
|
|
function recordStart() {
|
|
|
|
"ram"
|
|
|
|
Bangle.setLCDTimeout(0); // force LCD on
|
|
|
|
accelIdx = 0;
|
|
|
|
lastAccel = [];
|
|
|
|
Bangle.accelWr(0x18, 0b01110100); // off, +-8g
|
|
|
|
Bangle.accelWr(0x1B, 0x03 | 0x40); // 100hz output, ODR/2 filter
|
|
|
|
Bangle.accelWr(0x18, 0b11110100); // +-8g
|
|
|
|
Bangle.setPollInterval(10); // 100hz input
|
|
|
|
setTimeout(function() {
|
|
|
|
Bangle.on('accel', accelHandlerTrigger);
|
|
|
|
g.clear(1).setFont("6x8", 2).setFontAlign(0, 0);
|
|
|
|
g.drawString("Waiting", g.getWidth() / 2, g.getHeight() / 2);
|
|
|
|
}, 200);
|
2020-07-09 10:27:44 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2024-07-02 18:35:55 +00:00
|
|
|
function recordStop() {
|
|
|
|
"ram"
|
|
|
|
//console.log("Length:",getTime()-tStart);
|
|
|
|
Bangle.setPollInterval(80); // default poll interval
|
|
|
|
Bangle.accelWr(0x18, 0b01101100); // off, +-4g
|
|
|
|
Bangle.accelWr(0x1B, 0x0); // default 12.5hz output
|
|
|
|
Bangle.accelWr(0x18, 0b11101100); // +-4g
|
|
|
|
Bangle.removeListener('accel', accelHandlerRecord);
|
|
|
|
E.showMessage("Finished");
|
|
|
|
showData();
|
2020-07-09 10:27:44 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
function showData() {
|
2024-07-02 18:35:55 +00:00
|
|
|
g.clear(1);
|
|
|
|
let csv_files_N = require("Storage").list(/^acc.*.csv$/).length;
|
|
|
|
let w_full = g.getWidth();
|
|
|
|
let h = g.getHeight();
|
|
|
|
var w = g.getWidth() - 20; // width
|
|
|
|
var m = g.getHeight() / 2; // middle
|
|
|
|
var s = 12; // how many pixels per G
|
|
|
|
g.fillRect(9, 0, 9, g.getHeight());
|
|
|
|
g.setFontAlign(0, 0);
|
|
|
|
for (var l = -8; l <= 8; l++)
|
|
|
|
g.drawString(l, 5, m - l * s);
|
|
|
|
|
|
|
|
function plot(a) {
|
|
|
|
g.moveTo(10, m - a[0] * s / SCALE);
|
|
|
|
for (var i = 0; i < SAMPLES; i++)
|
|
|
|
g.lineTo(10 + i * w / SAMPLES, m - a[i] * s / SCALE);
|
2020-10-21 08:09:51 +00:00
|
|
|
}
|
2024-07-02 18:35:55 +00:00
|
|
|
g.setColor("#FFFA5F");
|
|
|
|
plot(accelz);
|
|
|
|
g.setColor("#ff0000");
|
|
|
|
plot(accelx);
|
|
|
|
g.setColor("#00ff00");
|
|
|
|
plot(accely);
|
|
|
|
|
|
|
|
// work out stats
|
|
|
|
var maxAccel = 0;
|
|
|
|
var tStart = SAMPLES,
|
|
|
|
tEnd = 0;
|
2024-07-05 20:30:45 +00:00
|
|
|
var maxVel = 0;
|
2024-07-02 18:35:55 +00:00
|
|
|
for (var i = 0; i < SAMPLES; i++) {
|
|
|
|
var a = Math.abs(accely[i] / SCALE);
|
|
|
|
let a_yz = Math.sqrt(Math.pow(accely[i] / SCALE, 2) + Math.pow(accelz[i] / SCALE, 2));
|
|
|
|
if (a > 0.1) {
|
|
|
|
if (i < tStart) tStart = i;
|
|
|
|
if (i > tEnd) tEnd = i;
|
|
|
|
}
|
|
|
|
if (a > maxAccel) maxAccel = a;
|
|
|
|
if (a_yz > maxVel) maxVel = a_yz;
|
|
|
|
}
|
|
|
|
g.reset();
|
|
|
|
g.setFont("6x8").setFontAlign(1, 0);
|
|
|
|
g.drawString("Max X Accel: " + maxAccel.toFixed(2) + " g", g.getWidth() - 14, g.getHeight() - 50);
|
|
|
|
g.drawString("Max YZ Accel: " + maxVel.toFixed(2) + " g", g.getWidth() - 14, g.getHeight() - 40);
|
|
|
|
g.drawString("Time moving: " + (tEnd - tStart) / HZ + " s", g.getWidth() - 14, g.getHeight() - 30);
|
|
|
|
g.setFont("6x8", 2).setFontAlign(0, 0);
|
|
|
|
g.drawString("File num: " + (csv_files_N + 1), w_full / 2, h - 20);
|
|
|
|
g.setFont("6x8").setFontAlign(0, 0, 1);
|
|
|
|
g.drawString("FINISH", g.getWidth() - 4, g.getHeight() / 2);
|
|
|
|
setWatch(function() {
|
2024-07-05 20:30:45 +00:00
|
|
|
showSaveMenu();
|
2024-07-02 18:35:55 +00:00
|
|
|
}, global.BTN2 ? BTN2 : BTN);
|
2020-07-09 10:27:44 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
function showBig(txt) {
|
2024-07-02 18:35:55 +00:00
|
|
|
g.clear(1);
|
|
|
|
g.setFontVector(80).setFontAlign(0, 0);
|
|
|
|
g.drawString(txt, g.getWidth() / 2, g.getHeight() / 2);
|
|
|
|
g.flip();
|
2020-07-09 10:27:44 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
function countDown() {
|
2024-07-02 18:35:55 +00:00
|
|
|
showBig(3);
|
2020-07-09 10:27:44 +00:00
|
|
|
setTimeout(function() {
|
2024-07-02 18:35:55 +00:00
|
|
|
showBig(2);
|
|
|
|
setTimeout(function() {
|
|
|
|
showBig(1);
|
|
|
|
setTimeout(function() {
|
|
|
|
recordStart();
|
|
|
|
}, 800);
|
|
|
|
}, 1000);
|
2020-07-09 10:27:44 +00:00
|
|
|
}, 1000);
|
|
|
|
}
|
|
|
|
|
|
|
|
function showMenu() {
|
2024-07-02 18:35:55 +00:00
|
|
|
Bangle.setLCDTimeout(10); // set timeout for LCD in menu
|
|
|
|
var menu = {
|
|
|
|
"": { title: "Acceleration Rec" },
|
|
|
|
"Start": function() {
|
|
|
|
E.showMenu();
|
|
|
|
if (accelIdx == 0) countDown();
|
|
|
|
else E.showPrompt("Overwrite Recording?").then(ok => {
|
|
|
|
if (ok) countDown();
|
|
|
|
else showMenu();
|
|
|
|
});
|
|
|
|
},
|
|
|
|
"Plot": function() {
|
|
|
|
E.showMenu();
|
|
|
|
if (accelIdx) showData();
|
|
|
|
else E.showAlert("No Data").then(() => {
|
|
|
|
showMenu();
|
|
|
|
});
|
|
|
|
},
|
|
|
|
"Storage": function() {
|
|
|
|
E.showMenu();
|
|
|
|
if (require("Storage").list(/^acc.*.csv$/).length)
|
|
|
|
StorageMenu();
|
|
|
|
else
|
|
|
|
E.showAlert("No Data").then(() => {
|
|
|
|
showMenu();
|
|
|
|
});
|
|
|
|
},
|
|
|
|
"Exit": function() {
|
|
|
|
load();
|
|
|
|
},
|
|
|
|
};
|
|
|
|
E.showMenu(menu);
|
2020-07-09 10:27:44 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
function showSaveMenu() {
|
2024-07-02 18:35:55 +00:00
|
|
|
E.showPrompt("Save recording?").then(ok => {
|
|
|
|
if (ok)
|
|
|
|
SaveFile();
|
|
|
|
else
|
|
|
|
showMenu();
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
function SaveFile() {
|
|
|
|
let csv_files_N = require("Storage").list(/^acc.*.csv$/).length;
|
|
|
|
//if (csv_files_N > 20)
|
|
|
|
// E.showMessage("Storage is full");
|
|
|
|
// showMenu();
|
|
|
|
let csv = "";
|
|
|
|
let date = new Date();
|
|
|
|
let fn = "accelrec_" + date.getHours() + ":" + date.getMinutes() + ":" + date.getSeconds() + "_" + (csv_files_N + 1) + ".csv";
|
|
|
|
E.showMessage("Saveing to file \n" + fn);
|
|
|
|
for (var i = 0; i < SAMPLES; i++)
|
2024-04-21 07:33:32 +00:00
|
|
|
csv += `${timestep[i]},${accelx[i]/SCALE},${accely[i]/SCALE},${accelz[i]/SCALE}\n`;
|
2024-07-02 18:35:55 +00:00
|
|
|
require("Storage").write(fn, csv);
|
|
|
|
showMenu();
|
|
|
|
}
|
|
|
|
|
|
|
|
function StorageMenu() {
|
|
|
|
var menu = {
|
|
|
|
"": {
|
|
|
|
title: "Storage"
|
|
|
|
}
|
2020-07-09 10:27:44 +00:00
|
|
|
};
|
2024-07-02 18:35:55 +00:00
|
|
|
let csv_files = require("Storage").list(/^acc.*.csv$/);
|
|
|
|
var inx = 0;
|
|
|
|
csv_files.forEach(fn => {
|
|
|
|
inx++;
|
|
|
|
menu[inx + ". " + fn] = function() {
|
|
|
|
StorageOptions(fn);
|
|
|
|
};
|
|
|
|
});
|
|
|
|
menu["< Back"] = function() {
|
|
|
|
showMenu();
|
|
|
|
};
|
|
|
|
E.showMenu(menu);
|
|
|
|
}
|
|
|
|
|
|
|
|
function StorageOptions(file) {
|
|
|
|
let menu = {
|
|
|
|
"": {
|
|
|
|
title: "Options"
|
|
|
|
},
|
|
|
|
"Plot": function() {
|
|
|
|
showMenu();
|
|
|
|
},
|
|
|
|
"Delete": function() {
|
|
|
|
E.showMenu();
|
|
|
|
E.showPrompt("Delete recording?").then(ok => {
|
|
|
|
if (ok)
|
|
|
|
DeleteRecord(file);
|
|
|
|
else
|
|
|
|
StorageMenu();
|
|
|
|
});
|
|
|
|
},
|
|
|
|
"< Back": function() {
|
|
|
|
StorageMenu();
|
|
|
|
},
|
|
|
|
};
|
|
|
|
E.showMenu(menu);
|
2020-07-09 10:27:44 +00:00
|
|
|
}
|
|
|
|
|
2024-07-02 18:35:55 +00:00
|
|
|
function DeleteRecord(file) {
|
|
|
|
E.showMessage("Deleteing file \n" + file);
|
|
|
|
require("Storage").erase(file);
|
|
|
|
StorageMenu();
|
|
|
|
}
|
|
|
|
showMenu();
|