Skip to content

Instantly share code, notes, and snippets.

@deltam
Last active December 15, 2020 10:12
Show Gist options
  • Save deltam/1a1d0d655794efad99f13d67d447fc6a to your computer and use it in GitHub Desktop.
Save deltam/1a1d0d655794efad99f13d67d447fc6a to your computer and use it in GitHub Desktop.
Bangle.jsで水泳の記録を取るやつ
// record accel while swimming
const WRITE_INTERVAL = 5*1000; // msec
const AVG1_MSEC = 1000; // last 1sec
const MAX_INDEX = 200;
const SCALE = 1000;
const STROKE_THRESHOLD = 1.5*SCALE;
var COLUMNS = [
'period_msec',
'accel_mag',
'mov_avg_1sec',
'grad',
'upDown',
'strokeCount',
'turn'
];
var tStart, tLast;
var allCount, lastCount;
var buf = new Int16Array(MAX_INDEX*COLUMNS.length);
var writerInterval;
var csvFile;
var writeFlag;
var strokeCount;
var isStroking;
var lastStrokeTime;
var turnCount;
function init() {
setAccelConf();
g.clear(1).setFont('Vector', 40);
E.on('kill', function() {
if (writeInterval != undefined)
recordStop();
setAccelConfDefault();
console.log('bye');
});
}
function bufOffset(i) {
return (i * COLUMNS.length) % buf.length;
}
function recordStart() {
let d = new Date();
let loc = require('locale');
let locTime = `${loc.date(d)}_${loc.time(d)}`.split(/[\/:]/).join('').trim();
csvName = `swimrec.${locTime}.csv`;
csvFile = require("Storage").open(csvName, 'w');
csvFile.write(COLUMNS.join(',')+`,${locTime}\n`);
console.log('Started ' + locTime);
setTimeout(function() {
tStart = Math.floor(Date.now());
tLast = tStart;
allCount = 0;
lastCount = 0;
strokeCount = 0;
lastStrokeTime = 0;
turnCount = 0;
Bangle.on('accel', accelHandlerRecord);
g.clear().drawString('working...', 40, 100);
setTimeout(()=>{
g.clear().drawString('...started!', 40, 100);
}, 3000);
writeInterval = setInterval(function() {
writeFlag = true;
}, WRITE_INTERVAL);
}, 200);
setWatch(recordStop, BTN2);
}
function recordStop() {
Bangle.removeListener('accel', accelHandlerRecord);
if (writeInterval != undefined) {
clearInterval(writeInterval);
writeInterval = undefined;
}
writeCSV();
csvFile.write('\n');
csvFile = undefined;
let elapse = Math.floor(Date.now()) - tStart;
console.log(`elapsed ${elapse} msec, write ${allCount} units`);
g.clear().drawString(`Finished\n${Math.floor(elapse/1000)} sec\n${strokeCount} strokes\nturn ${turnCount}`, 40, 60);
setWatch(recordStart, BTN2);
Bangle.buzz();
}
function accelHandlerRecord(a) {
let offset = bufOffset(allCount);
let t = Math.floor(Date.now());
buf[offset+0] = t - tLast;
tLast = t;
let mag = a.mag*2*SCALE; // x2 because 8g mode
buf[offset+1] = mag;
buf[offset+2] = average_msec(AVG1_MSEC, 1);
if (allCount > 14) {
let lastOffset = bufOffset(allCount-1);
let grad = buf[offset+2] - buf[lastOffset+2];
buf[offset+3] = grad;
buf[offset+4] = grad > 0 ? 1: -1;
if (buf[offset+4] != buf[lastOffset+4] && t - lastStrokeTime > 1000 && mag > STROKE_THRESHOLD) {
strokeCount++;
if (t - lastStrokeTime > 4000)
turnCount++;
lastStrokeTime = t;
Bangle.buzz();
showStatus();
}
}
buf[offset+5] = strokeCount;
buf[offset+6] = turnCount;
allCount++;
if (writeFlag) writeCSV();
}
function average_msec(ms, col) {
let a = 0, elapse = 0, cnt = 0, offset = 0;
for (var i=allCount; i>=0; i--) {
offset = bufOffset(i);
a += buf[offset+col];
cnt++;
elapse += buf[offset+0];
if (elapse >= ms) break;
}
if (cnt == 0 || elapse < ms) return 0;
return a/cnt;
}
function writeCSV() {
let csv = "";
for (var i=lastCount; i<allCount; i++) {
let offset = bufOffset(i);
csv += [
buf[offset+0],
buf[offset+1]/SCALE,
buf[offset+2]/SCALE,
buf[offset+3]/SCALE,
buf[offset+4],
buf[offset+5],
buf[offset+6]
].join(',') + '\n';
}
csvFile.write(csv);
writeFlag = false;
lastCount = allCount;
console.log('write total', allCount);
}
function showStatus() {
g.clear().drawString(`Recoding...\nstroke ${strokeCount}\nturn ${turnCount}`, 40, 80);
}
// copy from accelrec.app.js
function setAccelConf() {
Bangle.accelWr(0x18, 0b01110100); // off, +-8g
Bangle.accelWr(0x1B, 0x03 | 0x40); // 100hz output, ODR/2 filter
Bangle.accelWr(0x18, 0b11110100); // +-8g
Bangle.setPollInterval(100); // 10hz input
}
function setAccelConfDefault() {
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
}
init();
recordStart();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment