edit: OMG, there is actually a critical bug in the code (buf[bufi] = 0; when bufi == buf.length). If this turns out to be the source, please apologize the distraction!
Unfortunately I can't reliably reproduce the issue. It happened thrice in a row (2 outdoors, 1 indoors), then once at BT disconnect (Android blessed.BluetoothPeripheral.closeConnection; saw the bootloader screen) followed by 2 times without issues. My guess now is that the BT device in my phone is buggy and somehow triggers an extra hard reset on connection loss/disconnect.
I will therefore rewrite the app to recover in case of a hard reset and look for any pattern in the data.
Code:
var ACC = 1;
var MAG = 2;
var GPS = 3;
var TIM = 4;
var bufs = [];
var buf = new ArrayBuffer(1000);
var bufi = 0;
function get_dv(len) {
if (buf.length < (bufi + len)) {
buf[bufi] = 0;
bufs.push(buf);
buf = new ArrayBuffer(1000);
bufi = 0;
}
var dv = new DataView(buf, bufi);
bufi += len;
return dv;
}
function send_buf() {
if (bufs.length) {
Bluetooth.write(btoa(bufs[0]));
}
Bluetooth.write('\n');
}
function remove_buf() {
bufs.shift();
}
function on_accel(a) {
var v = get_dv(7);
v.setUint8(0, ACC);
v.setInt16(1, a.x * 8192);
v.setInt16(3, a.y * 8192);
v.setInt16(5, a.z * 8192);
}
function on_mag(m) {
var v = get_dv(7);
v.setUint8(0, MAG);
v.setInt16(1, m.x);
v.setInt16(3, m.y);
v.setInt16(5, m.z);
}
function on_gps(g) {
if (g.fix == 0) return;
var v = get_dv(26);
v.setUint8(0, GPS);
v.setInt32(1, g.lat * 11930464);
v.setInt32(5, g.lon * 11930464);
v.setUint16(9, clamp(g.alt * 16, 0, 65535));
v.setFloat64(11, g.time.getTime());
v.setUint8(19, g.fix);
v.setUint8(20, clamp(g.hdop * 12, 0, 255));
v.setUint8(21, g.satellites);
v.setUint16(22, g.course * 182);
v.setUint16(24, clamp(g.speed * 327, 0, 65535));
}
var clamp = (a, mi, ma) => a < mi ? mi : (ma < a ? ma : a);
function log(s) {
Terminal.println(s);
}
g.clear();
Bangle.loadWidgets();
Bangle.drawWidgets();
log('# Cyclometer');
log('press top button to start');
Bangle.setGPSPower(true, 'cyc');
var satc = 0;
function ready(g) {
if (g.fix) {
Bangle.removeListener('GPS', ready);
Bangle.buzz(500);
log('GPS ready');
} else if (g.satellites != satc) {
satc = g.satellites;
log('GPS satellites: ' + satc);
}
}
Bangle.on('GPS', ready);
setWatch(() => {
log('starting ...');
Bangle.setLCDTimeout(0);
Bangle.setOptions({btnLoadTimeout: 0});
Bangle.setCompassPower(true, 'cyc');
Bangle.on('accel', on_accel);
Bangle.on('mag', on_mag);
Bangle.on('GPS', on_gps);
var tim_id = setInterval(() => {
var v = get_dv(9);
v.setUint8(0, TIM);
v.setFloat64(1, getTime());
}, 60 * 1000);
var log_id = setInterval(() => {
var m = process.memory();
var p = Math.floor((m.usage / m.total) * 100);
log('queue: ' + bufs.length + ' memory: ' + p + '%');
if (67 <= p) {
Bangle.buzz(500);
setTimeout(() => Bangle.buzz(500), 1000);
}
}, 5 * 1000);
log('started');
log('hold top button for 3 seconds to stop');
var cnt;
var cnt_id;
var btn_id = setWatch((e) => {
if (e.state) {
log('stop in 3');
cnt = 3;
cnt_id = setTimeout(stop, 1000);
Bangle.buzz(300);
} else if (cnt_id) {
clearTimeout(cnt_id);
cnt_id = undefined;
}
}, BTN1, {repeat: true, edge: 'both'});
function stop() {
cnt--;
if (cnt == 0) {
log('stopping ...');
Bangle.setLCDTimeout(10);
Bangle.setOptions({btnLoadTimeout: 1500});
Bangle.setGPSPower(false, 'cyc');
Bangle.setCompassPower(false, 'cyc');
var _ = Bangle.removeListener.bind(Bangle);
_('accel', on_accel);
_('mag', on_mag);
_('GPS', on_gps);
clearInterval(tim_id);
clearInterval(log_id);
clearWatch(btn_id);
log('stopped');
} else {
log('stop in ' + cnt);
cnt_id = setTimeout(stop, 1000);
Bangle.buzz(300);
}
}
}, BTN1);
Espruino is a JavaScript interpreter for low-power Microcontrollers. This site is both a support community for Espruino and a place to share what you are working on.
edit: OMG, there is actually a critical bug in the code (
buf[bufi] = 0;
whenbufi == buf.length
). If this turns out to be the source, please apologize the distraction!Unfortunately I can't reliably reproduce the issue. It happened thrice in a row (2 outdoors, 1 indoors), then once at BT disconnect (Android
blessed.BluetoothPeripheral.closeConnection
; saw the bootloader screen) followed by 2 times without issues. My guess now is that the BT device in my phone is buggy and somehow triggers an extra hard reset on connection loss/disconnect.I will therefore rewrite the app to recover in case of a hard reset and look for any pattern in the data.
Code: