Last active
December 15, 2020 10:12
-
-
Save deltam/1a1d0d655794efad99f13d67d447fc6a to your computer and use it in GitHub Desktop.
Bangle.jsで水泳の記録を取るやつ
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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