From 63fe1387fa99fc610349ad6b91d26b09dd86b8ad Mon Sep 17 00:00:00 2001 From: marko Date: Tue, 15 Sep 2020 15:07:44 -0400 Subject: [PATCH 1/3] Reconnect on disconnect, properly save on exit and reset, better time handling --- apps/cscsensor/cscsensor.app.js | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/apps/cscsensor/cscsensor.app.js b/apps/cscsensor/cscsensor.app.js index 3e6e54404..bf534e734 100644 --- a/apps/cscsensor/cscsensor.app.js +++ b/apps/cscsensor/cscsensor.app.js @@ -15,7 +15,7 @@ class CSCSensor { this.settings = storage.readJSON(SETTINGS_FILE, 1) || {}; this.settings.totaldist = this.settings.totaldist || 0; this.totaldist = this.settings.totaldist; - this.wheelCirc = (this.settings.wheelcirc || 2230)/25.4; + this.wheelCirc = (this.settings.wheelcirc || 2165)/25.4; this.speedFailed = 0; this.speed = 0; this.maxSpeed = 0; @@ -28,6 +28,8 @@ class CSCSensor { this.distFactor = this.qMetric ? 1.609344 : 1; } reset() { + this.settings.totaldist = this.totaldist; + storage.writeJSON(SETTINGS_FILE, this.settings); this.maxSpeed = 0; this.movingTime = 0; this.lastRevsStart = this.lastRevs; @@ -79,12 +81,13 @@ class CSCSensor { var dBT = (Date.now()-this.lastBangleTime)/1000; this.lastBangleTime = Date.now(); if (dT<0) dT+=64; + if (Math.abs(dT-dBT)>2) dT = dBT; this.lastTime = wheelTime; this.speed = this.lastSpeed; if (dRevs>0 && dT>0) { this.speed = (dRevs*this.wheelCirc/63360.0)*3600/dT; this.speedFailed = 0; - this.movingTime += dBT; + this.movingTime += dT; } else { this.speedFailed++; @@ -125,13 +128,16 @@ function parseDevice(d) { g.clearRect(0, 60, 239, 239).setColor(1, 0, 0).setFontAlign(0, 0, 0).drawString("ERROR"+e, 120, 120).flip(); })} -NRF.setScan(parseDevice, { filters: [{services:["1816"]}], timeout: 2000}); -g.clearRect(0, 60, 239, 239).setFontVector(18).setFontAlign(0, 0, 0).setColor(0, 1, 0); -g.drawString("Scanning for CSC sensor...", 120, 120); +function connection_setup() { + NRF.setScan(parseDevice, { filters: [{services:["1816"]}], timeout: 2000}); + g.clearRect(0, 60, 239, 239).setFontVector(18).setFontAlign(0, 0, 0).setColor(0, 1, 0); + g.drawString("Scanning for CSC sensor...", 120, 120); +} +connection_setup(); setWatch(function() { mySensor.reset(); g.clearRect(0, 60, 239, 239); mySensor.updateScreen(); }, BTN1, {repeat:true, debounce:20}); - -Bangle.on('kill',()=>{ if (gatt!=undefined) gatt.disconnect(); mySensor.settings.totaldist = mySensor.totaldist; storage.writeJSON(SETTINGS_FILE, mySensor.settings); }); +E.on('kill',()=>{ if (gatt!=undefined) gatt.disconnect(); mySensor.settings.totaldist = mySensor.totaldist; storage.writeJSON(SETTINGS_FILE, mySensor.settings); }); +NRF.on('disconnect', connection_setup); Bangle.loadWidgets(); Bangle.drawWidgets(); From c22254a591eaf0c84b8cfadfa42ffe694bbc71a5 Mon Sep 17 00:00:00 2001 From: marko Date: Tue, 15 Sep 2020 17:48:41 -0400 Subject: [PATCH 2/3] Add sensor battery indicator --- apps.json | 2 +- apps/cscsensor/ChangeLog | 1 + apps/cscsensor/cscsensor.app.js | 27 ++++++++++++++++++++++++++- 3 files changed, 28 insertions(+), 2 deletions(-) diff --git a/apps.json b/apps.json index 917096897..cadc76ba5 100644 --- a/apps.json +++ b/apps.json @@ -2176,7 +2176,7 @@ "name": "Cycling speed sensor", "shortName":"CSCSensor", "icon": "icons8-cycling-48.png", - "version":"0.03", + "version":"0.04", "description": "Read BLE enabled cycling speed and cadence sensor and display readings on watch", "tags": "outdoors,exercise,ble,bluetooth", "readme": "README.md", diff --git a/apps/cscsensor/ChangeLog b/apps/cscsensor/ChangeLog index ae99905a6..7be2ed3e2 100644 --- a/apps/cscsensor/ChangeLog +++ b/apps/cscsensor/ChangeLog @@ -1,4 +1,5 @@ 0.01: New app! 0.02: Add wheel circumference settings dialog 0.03: Save total distance traveled +0.04: Add sensor battery level indicator diff --git a/apps/cscsensor/cscsensor.app.js b/apps/cscsensor/cscsensor.app.js index bf534e734..915cb52fc 100644 --- a/apps/cscsensor/cscsensor.app.js +++ b/apps/cscsensor/cscsensor.app.js @@ -15,7 +15,7 @@ class CSCSensor { this.settings = storage.readJSON(SETTINGS_FILE, 1) || {}; this.settings.totaldist = this.settings.totaldist || 0; this.totaldist = this.settings.totaldist; - this.wheelCirc = (this.settings.wheelcirc || 2165)/25.4; + this.wheelCirc = (this.settings.wheelcirc || 2230)/25.4; this.speedFailed = 0; this.speed = 0; this.maxSpeed = 0; @@ -26,6 +26,7 @@ class CSCSensor { this.speedUnit = this.qMetric ? "km/h" : "mph"; this.distUnit = this.qMetric ? "km" : "mi"; this.distFactor = this.qMetric ? 1.609344 : 1; + this.batteryLevel = -1; } reset() { this.settings.totaldist = this.totaldist; @@ -35,6 +36,9 @@ class CSCSensor { this.lastRevsStart = this.lastRevs; this.maxSpeed = 0; } + setBatteryLevel(level) { + this.batteryLevel = level; + } updateScreen() { var dist = this.distFactor*(this.lastRevs-this.lastRevsStart)*this.wheelCirc/63360.0; var ddist = Math.round(100*dist)/100; @@ -60,6 +64,15 @@ class CSCSensor { g.drawString(maxspeed + " " + this.speedUnit, 92, 156); g.drawString(ddist + " " + this.distUnit, 92, 188); g.drawString(tdist + " " + this.distUnit, 92, 220); + if (this.batteryLevel!=-1) { + g.setColor(1, 1, 1).drawRect(10, 64, 20, 84).fillRect(14, 62, 16, 64); + if (this.batteryLevel<25) g.setColor(1, 0, 0); + else if (this.batteryLevel<50) g.setColor(1, 0.5, 0); + else g.setColor(0, 1, 0); + g.fillRect(11, 83-18*this.batteryLevel/100, 19, 83); + console.log(this.batteryLevel); + this.batteryLevel = -1; + } } updateSensor(event) { var qChanged = false; @@ -106,6 +119,16 @@ class CSCSensor { var mySensor = new CSCSensor(); +function getSensorBatteryLevel(gatt) { + gatt.getPrimaryService("180f").then(function(s) { + return s.getCharacteristic("2a19"); + }).then(function(c) { + return c.readValue(); + }).then(function(d) { + mySensor.setBatteryLevel(d.buffer[0]); + }); +} + function parseDevice(d) { device = d; g.clearRect(0, 60, 239, 239).setFontAlign(0, 0, 0).setColor(0, 1, 0).drawString("Found device", 120, 120).flip(); @@ -123,9 +146,11 @@ function parseDevice(d) { }).then(function() { console.log("Done!"); g.clearRect(0, 60, 239, 239).setColor(1, 1, 1).flip(); + getSensorBatteryLevel(gatt); mySensor.updateScreen(); }).catch(function(e) { g.clearRect(0, 60, 239, 239).setColor(1, 0, 0).setFontAlign(0, 0, 0).drawString("ERROR"+e, 120, 120).flip(); + console.log(e); })} function connection_setup() { From 3c0db6cd25ea980cba08616cf4932d6473360f94 Mon Sep 17 00:00:00 2001 From: marko Date: Tue, 15 Sep 2020 22:36:33 -0400 Subject: [PATCH 3/3] Make display more readable --- apps/cscsensor/cscsensor.app.js | 41 ++++++++++++++++++++------------- 1 file changed, 25 insertions(+), 16 deletions(-) diff --git a/apps/cscsensor/cscsensor.app.js b/apps/cscsensor/cscsensor.app.js index 915cb52fc..65b50dfe7 100644 --- a/apps/cscsensor/cscsensor.app.js +++ b/apps/cscsensor/cscsensor.app.js @@ -50,26 +50,35 @@ class CSCSensor { if (dsecs.length<2) dsecs = "0"+dsecs; var avespeed = (this.movingTime>2 ? Math.round(10*dist/(this.movingTime/3600))/10 : 0); var maxspeed = Math.round(10*this.distFactor*this.maxSpeed)/10; - g.setFontAlign(1, -1, 0).setFontVector(18).setColor(1, 1, 0); - g.drawString("Time:", 86, 60); - g.drawString("Speed:", 86, 92); - g.drawString("Ave spd:", 86, 124); - g.drawString("Max spd:", 86, 156); - g.drawString("Trip dist:", 86, 188); - g.drawString("Total:", 86, 220); - g.setFontAlign(-1, -1, 0).setFontVector(24).setColor(1, 1, 1).clearRect(92, 60, 239, 239); - g.drawString(dmins+":"+dsecs, 92, 60); - g.drawString(dspeed+" "+this.speedUnit, 92, 92); - g.drawString(avespeed + " " + this.speedUnit, 92, 124); - g.drawString(maxspeed + " " + this.speedUnit, 92, 156); - g.drawString(ddist + " " + this.distUnit, 92, 188); - g.drawString(tdist + " " + this.distUnit, 92, 220); + for (var i=0; i<6; ++i) { + if ((i&1)==0) g.setColor(0, 0, 0); + else g.setColor(0.2, 0.1, 0.4); + g.fillRect(0, 48+i*32, 86, 48+(i+1)*32); + if ((i&1)==1) g.setColor(0, 0, 0); + else g.setColor(0.2, 0.1, 0.4); + g.fillRect(87, 48+i*32, 239, 48+(i+1)*32); + g.setColor(0.5, 0.5, 0.5).drawRect(87, 48+i*32, 239, 48+(i+1)*32).drawLine(0, 239, 239, 239).drawRect(0, 48, 87, 239); + } + g.setFontAlign(1, 0, 0).setFontVector(19).setColor(1, 1, 0); + g.drawString("Time:", 87, 66); + g.drawString("Speed:", 87, 98); + g.drawString("Ave spd:", 87, 130); + g.drawString("Max spd:", 87, 162); + g.drawString("Trip:", 87, 194); + g.drawString("Total:", 87, 226); + g.setFontAlign(-1, 0, 0).setFontVector(26).setColor(1, 1, 1);//.clearRect(92, 60, 239, 239); + g.drawString(dmins+":"+dsecs, 92, 66); + g.drawString(dspeed+" "+this.speedUnit, 92, 98); + g.drawString(avespeed + " " + this.speedUnit, 92, 130); + g.drawString(maxspeed + " " + this.speedUnit, 92, 162); + g.drawString(ddist + " " + this.distUnit, 92, 194); + g.drawString(tdist + " " + this.distUnit, 92, 226); if (this.batteryLevel!=-1) { - g.setColor(1, 1, 1).drawRect(10, 64, 20, 84).fillRect(14, 62, 16, 64); + g.setColor(1, 1, 1).drawRect(10, 55, 20, 75).fillRect(14, 53, 16, 55); if (this.batteryLevel<25) g.setColor(1, 0, 0); else if (this.batteryLevel<50) g.setColor(1, 0.5, 0); else g.setColor(0, 1, 0); - g.fillRect(11, 83-18*this.batteryLevel/100, 19, 83); + g.fillRect(11, 74-18*this.batteryLevel/100, 19, 74); console.log(this.batteryLevel); this.batteryLevel = -1; }