Here is the last version of my widget. Not yet checked into git. I dont think I have low power working yet. Have been looking at other code across the web, github etc. I have added some new functions tonight but they are not tested yet. I've not yet spent the time of the settings file so to switch on and off have using command line whne connected through the IDE.
WIDGETS.gpsservice.gps_power_on();
The Widget.
(() => {
var have_fix = false;
var fixToggle = false; // toggles once for each reading
var gps_power = false;
var last_fix = {
fix: 0,
alt: 0,
lat: 0,
lon: 0,
speed: 0,
time: 0,
satellites: 0
};
function gps_get_fix() { return last_fix; }
function gps_get_status() { return gps_power;}
function gps_power_on() {
have_fix = false;
fixToggle = false;
gps_power = true;
setupGPS();
}
function gps_power_off() {
Bangle.setGPSPower(0);
gps_power = false;
have_fix = false;
fixToggle = false;
gps_power = false;
last_fix.fix = 0;
}
// quick hack
function wait(ms){
var start = new Date().getTime();
var end = start;
while(end < start + ms) {
end = new Date().getTime();
}
}
function setupGPS() {
Bangle.setGPSPower(1);
wait(20);
UBX_CFG_INTERVAL(29,5);
wait(20);
UBX_CFG_RATE(17);
wait(20);
UBX_CFG_SAVE();
wait(5);
Bangle.on('GPS', onGPS);
}
// NEW NOT TRIED YET
function setupGPS_PMS2() {
Bangle.setGPSPower(1);
wait(20);
UBX_CFG_RESET();
wait(100);//wait for effect
//Set power mode / interval mode
UBX_CFG_PM2();
wait(20);
//save
UBX_CFG_SAVE();
wait(20);
Bangle.on('GPS', onGPS);
}
function writeGPScmd(cmd) {
var d = [0xB5,0x62]; // sync chars
d = d.concat(cmd);
var a=0,b=0;
for (var i=2;i<d.length;i++) {
a += d[i];
b += a;
}
d.push(a&255,b&255);
//console.log(d);
Serial1.write(d);
}
// UBX-CFG-PMS - enable power management - Super-E
function UBX_CFG_PMS() {
writeGPScmd([0x06,0x86, // msg class + type
8,0,//length
0x00,0x03, 0,0, 0,0, 0,0]);
}
function UBX_CFG_INTERVAL(period, ontime) {
writeGPScmd([0x06,0x86, // msg class + type
8,0, //length
//v0, interval period ontime reserved
0x00, 0x02, period, 0, ontime, 0, 0, 0 ]);
// the values are little endian, least significant byte first
}
/*
* NOT TRIED, NOT TESTED YET
* https://github.com/thasti/utrak/blob/master/gps.c
*/
function UBX_CFG_PM2() {
writeGPScmd([0x06, 0x3B, /* class id */
44, 0, /* length */
0x01, 0x00, 0x00, 0x00, /* v1, reserved 1..3 */
0x00, 0x10, 0x00, 0x00, /* on/off-mode, update ephemeris */
// little endian, lsb first
0x30, 0x75, 0x00, 0x00, /* update period, ms, 120s=00 01 D4 C0, 30s= 00 00 75 30 */
0x20, 0x4E, 0x00, 0x00, /* search period, ms, 120s, 20s = 00 00 4E 20 */
0x00, 0x00, 0x00, 0x00, /* grid offset */
0x00, 0x00, /* on-time after first fix */
0x01, 0x00, /* minimum acquisition time */
0x00, 0x00, 0x00, 0x00, /* reserved 4,5 */
0x00, 0x00, 0x00, 0x00, /* reserved 6 */
0x00, 0x00, 0x00, 0x00, /* reserved 7 */
0x00, 0x00, 0x00, 0x00, /* reserved 8,9,10 */
0x00, 0x00, 0x00, 0x00]); /* reserved 11 */
};
/*
* set update baud rate
*
* the setting is in milliseconds in 2 bytes, max 65 seconds
* we are passing in a value in seconds
* we set the most significant byte only
* 8 seconds ~ 8192ms 0x2000, 0x20 = 32 = 4*8
*
*/
function UBX_CFG_RATE(rate) {
rate = (rate * 4) % 256;
//console.log("rate=" + rate);
writeGPScmd([0x06,0x08, // class, id
0x06, 0, // length
0x00, rate, // b0: 8192ms 0x2000, 0x00FF (~65sec)
0x01, 0x00, // b2:
0x01, 0x00]); // b4: timeref GPS
}
/*
* Save configuration otherwise it will reset when the GPS wakes up
*
*/
function UBX_CFG_SAVE() {
writeGPScmd([0x06, 0x09, // class id
0x0D, 0x00, // length
0x00, 0x00, 0x00, 0x00, // clear mask
0xFF, 0xFF, 0x00, 0x00, // save mask
0x00, 0x00, 0x00, 0x00, // load mask
// 0x01]); // b2=eeprom b1=flash b0=bat backed ram
0x07]); // b2=eeprom b1=flash b0=bat backed ram
// code on github had 7 - all 3 set ?
}
/*
* NOT TRIED, NOT TESTED
* Reset to factory settings using clear mask in UBX_CFG_CFG
* https://portal.u-blox.com/s/question/0D52p0000925T00CAE/ublox-max-m8q-getting-stuck-when-sleeping-with-extint-pin-control
*/
function UBX_CFG_RESET() {
writeGPScmd([0x06, 0x09, // class id
0x0D, 0x00,
0xFF, 0xFB, 0x00, 0x00, // clear mask
0x00, 0x00, 0x00, 0x00, // save mask
0xFF, 0xFF, 0x00, 0x00, // load mask
0x17]);
}
// draw the widget
function draw() {
g.reset();
g.drawImage(atob("GBgCAAAAAAAAAAQAAAAAAD8AAAAAAP/AAAAAAP/wAAAAAH/8C9AAAB/8L/QAAAfwv/wAAAHS//wAAAAL//gAAAAf/+AAAAAf/4AAAAL//gAAAAD/+DwAAAB/Uf8AAAAfA//AAAACAf/wAAAAAH/0AAAAAB/wAAAAAAfAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"),this.x,this.y);
if (gps_power && have_fix) {
g.setColor("#00FF00");
g.drawImage(fixToggle ? atob("CgoCAAAAA0AAOAAD5AAPwAAAAAAAAAAAAAAAAA==") : atob("CgoCAAABw0AcOAHj5A8PwHwAAvgAB/wABUAAAA=="),this.x,this.y+14);
} else {
g.setColor("#0000FF");
if (fixToggle) g.setFont("6x8").drawString("?",this.x,this.y+14);
}
}
function onGPS(fix) {
fixToggle = !fixToggle;
WIDGETS["gpsservice"].draw();
last_fix.satellites = fix.satellites;
/*
* If we have a fix record it, we will get another soon. Apps
* will see the timestamp of the last fix and be able to work out
* if it is stale. This means an App will always have the last
* known fix, and we avoid saying no fix all the time.
*
*/
if (fix.fix) {
last_fix.fix = fix.fix;
last_fix.alt = fix.alt;
last_fix.lat = fix.lat;
last_fix.lon = fix.lon;
last_fix.speed = fix.speed;
last_fix.time = fix.time;
}
}
// redraw when the LCD turns on
Bangle.on('lcdPower', function(on) {
if (on) WIDGETS["gpsservice"].draw();
});
// add the widget
WIDGETS["gpsservice"]={
area:"tl",
width:24,
draw:draw,
gps_power_on:gps_power_on,
gps_power_off:gps_power_off,
gps_get_status:gps_get_status,
gps_get_fix:gps_get_fix
};
})();
enter code here
As a client I have defined a watch face for multiclock.
(() => {
function getFace(){
//var img = require("heatshrink").decompress(atob("mEwghC/AH4AKg9wC6t3u4uVC6wWBI6t3uJeVuMQCqcBLisAi4XLxAABFxAXKgc4DBAuBRhQXEDAq7MmYXEwBHEXZYXFGAOqAAKDMmczC4mIC62CC50PC4JIBkQABiIvRmURAAUSjQXSFwMoxGKC6CRFwUSVYgXLPIgXXwMYegoXLJAYXCGBnzGA0hPQIwMgYwGC6gwCC4ZIMC4gYBC604C4ZISmcRVgapQAAMhC6GIJIwXCMBcIxGDDBAuLC4IwGAARGMAAQWGmAXPJQoWMC4pwCCpoXJAB4XXAH4A/ABQA="));
var nofix = 0;
function formatTime(now) {
var fd = now.toUTCString().split(" ");
return fd[4];
}
function timeSince(t) {
var hms = t.split(":");
var now = new Date();
var sn = 3600*(now.getHours()) + 60*(now.getMinutes()) + 1*(now.getSeconds());
var st = 3600*(hms[0]) + 60*(hms[1]) + 1*(hms[2]);
return (sn - st);
}
function draw() {
var gps_on = false;
var fix = {
fix: 0,
alt: 0,
lat: 0,
lon: 0,
speed: 0,
time: 0,
satellites: 0
};
var y_line = 26;
var y_start = 46;
var x_start = 10;
// only attempt to get gps fix if gpsservuce is loaded
if (WIDGETS.gpsservice !== undefined) {
fix = WIDGETS.gpsservice.gps_get_fix();
gps_on = WIDGETS.gpsservice.gps_get_status();
}
g.reset();
g.clearRect(0,24,239,239);
if (fix.fix) {
var time = formatTime(fix.time);
var age = timeSince(time);
g.setFontAlign(-1, -1);
g.setFont("6x8");
g.setFontVector(22);
g.drawString("Alt: " + fix.alt +" m", x_start, y_start, true);
g.drawString("Lat: "+ fix.lat, x_start, y_start + y_line, true);
g.drawString("Lon: " + fix.lon, x_start, y_start + 2*y_line, true);
g.drawString("Time: " + time, x_start, y_start + 3*y_line, true);
g.drawString("Age(s): " + age, x_start, y_start + 4*y_line, true);
g.drawString("Satellites: " + fix.satellites, x_start, y_start + 5*y_line, true);
} else if (gps_on) {
g.setFontAlign(0, 1);
g.setFont("6x8", 2);
g.drawString("Waiting for GPS 0.02", 120, 80);
nofix = (nofix+1) % 4;
g.drawString(".".repeat(nofix) + " ".repeat(4-nofix), 120, 120);
g.setFontAlign(0,0);
g.drawString(fix.satellites + " satellites", 120, 100);
} else if (!gps_on) {
g.setFontAlign(0, 0);
g.setFont("6x8", 3);
g.drawString("GPS is off", g.getWidth()/2, g.getWidth()/2);
}
}
function onSecond(){
var t = new Date();
if ((t.getSeconds() % 5) === 0) draw();
}
return {init:draw, tick:onSecond};
}
return getFace;
})();
I will probably have another hack-fest on Wednesday night, get the settings working.
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.
Here is the last version of my widget. Not yet checked into git. I dont think I have low power working yet. Have been looking at other code across the web, github etc. I have added some new functions tonight but they are not tested yet. I've not yet spent the time of the settings file so to switch on and off have using command line whne connected through the IDE.
The Widget.
As a client I have defined a watch face for multiclock.
I will probably have another hack-fest on Wednesday night, get the settings working.