0.02: Created gppsetup module

master
Gordon Williams 2021-02-11 11:24:44 +00:00
parent b5c7ded4b5
commit b794059884
5 changed files with 235 additions and 180 deletions

View File

@ -2771,11 +2771,12 @@
"name": "GPS Setup", "name": "GPS Setup",
"shortName":"GPS Setup", "shortName":"GPS Setup",
"icon": "gpssetup.png", "icon": "gpssetup.png",
"version":"0.01", "version":"0.02",
"description": "Configure the GPS power options and store them in the GPS nvram", "description": "Configure the GPS power options and store them in the GPS nvram",
"tags": "gps, tools, outdoors", "tags": "gps, tools, outdoors",
"readme": "README.md", "readme": "README.md",
"storage": [ "storage": [
{"name":"gpssetup","url":"gpssetup.js"},
{"name":"gpssetup.settings.js","url":"settings.js"}, {"name":"gpssetup.settings.js","url":"settings.js"},
{"name":"gpssetup.settings.json","url":"settings.json"}, {"name":"gpssetup.settings.json","url":"settings.json"},
{"name":"gpssetup.app.js","url":"app.js"}, {"name":"gpssetup.app.js","url":"app.js"},

View File

@ -1 +1,2 @@
0.01: First version of GPS Setup app 0.01: First version of GPS Setup app
0.02: Created gppsetup module

View File

@ -1,6 +1,6 @@
# GPS Setup # GPS Setup
An App to enable the GPS to be configured into low power mode. An App and module to enable the GPS to be configured into low power mode.
## Goals ## Goals
@ -22,7 +22,7 @@ Example power consumption of the GPS while powered on:
running with 45% battery 20 hours after it started. running with 45% battery 20 hours after it started.
## Settings ## Settings App
The Settings App enables you set the options below. Either start the The Settings App enables you set the options below. Either start the
App from the launcher or go to Settings, select App/Widgets and then App from the launcher or go to Settings, select App/Widgets and then
@ -38,11 +38,11 @@ used. These settings will remain for all apps that use the GPS.
- Power Mode: - Power Mode:
- SuperE - the factory default setup for the GPS. The recommended - **SuperE** - the factory default setup for the GPS. The recommended
power saving mode. If you need frequent (every second) updates on power saving mode. If you need frequent (every second) updates on
position, then this is the mode for you. position, then this is the mode for you.
- PSMOO - On/Off power saving mode. Configured by interval and - **PSMOO** - On/Off power saving mode. Configured by interval and
search time. Choose this mode if you are happy to get a GPS search time. Choose this mode if you are happy to get a GPS
position update less often (say every 1 or 2 minutes). The longer position update less often (say every 1 or 2 minutes). The longer
the interval the more time the GPS will spend sleeping in low the interval the more time the GPS will spend sleeping in low
@ -55,6 +55,37 @@ used. These settings will remain for all apps that use the GPS.
- search - the time between two acquisition attempts if the receiver - search - the time between two acquisition attempts if the receiver
is unable to get a position fix. is unable to get a position fix.
## Module
A module is provided that'll allow you to set GPS configuration from your own
app. To use it:
```
// This will set up the GPS to current saved defaults. It's not normally
// needed unless the watch's battery has run down
require("gpssetup").setPowerMode();
// This sets up the PSMOO mode. update/search are optional in seconds
require("gpssetup").setPowerMode({
power_mode:"PSMOO",
update:optional (default 120),
search:optional (default 5)})
// This sets up SuperE
require("gpssetup").setPowerMode({power_mode:"SuperE"})
```
`setPowerMode` returns a promise, which is completed when the GPS is set up.
So you can for instance do the following to turn the GPS off once it
has been configured:
```
require("gpssetup").setPowerMode().then(function() {
Bangle.setGPSPower(0);
});
```
## References ## References
* [UBLOX M8 Receiver Data Sheet](https://www.u-blox.com/sites/default/files/products/documents/u-blox8-M8_ReceiverDescrProtSpec_%28UBX-13003221%29.pdf) * [UBLOX M8 Receiver Data Sheet](https://www.u-blox.com/sites/default/files/products/documents/u-blox8-M8_ReceiverDescrProtSpec_%28UBX-13003221%29.pdf)
@ -63,4 +94,3 @@ used. These settings will remain for all apps that use the GPS.
* Some useful code on Github can be found [here](https://portal.u-blox.com/s/question/0D52p0000925T00CAE/ublox-max-m8q-getting-stuck-when-sleeping-with-extint-pin-control) * Some useful code on Github can be found [here](https://portal.u-blox.com/s/question/0D52p0000925T00CAE/ublox-max-m8q-getting-stuck-when-sleeping-with-extint-pin-control)
and [here](https://github.com/thasti/utrak/blob/master/gps.c) and [here](https://github.com/thasti/utrak/blob/master/gps.c)

View File

@ -15,6 +15,11 @@
Bangle.loadWidgets(); Bangle.loadWidgets();
Bangle.drawWidgets(); Bangle.drawWidgets();
function log_debug(o) {
//let timestamp = new Date().getTime();
//console.log(timestamp + " : " + o);
}
const SETTINGS_FILE = "gpssetup.settings.json"; const SETTINGS_FILE = "gpssetup.settings.json";
let settings = undefined; let settings = undefined;
let settings_changed = false; let settings_changed = false;
@ -35,174 +40,15 @@ function loadSettings() {
/*********** GPS Power and Setup Functions ******************/ /*********** GPS Power and Setup Functions ******************/
function log_debug(o) {
//let timestamp = new Date().getTime();
//console.log(timestamp + " : " + o);
}
function setupGPS() { function setupGPS() {
Bangle.setGPSPower(1); Bangle.setGPSPower(1);
if (settings.power_mode === "PSMOO") { setTimeout(function() {
setupPSMOO(); require("gpssetup").setPowerMode().then(function() {
} else {
setupSuperE();
}
}
function delay(ms) {
return new Promise(resolve => setTimeout(resolve, ms));
}
function setupSuperE() {
log_debug("setupGPS() Super-E");
Promise.resolve().then(function() {
UBX_CFG_RESET();
return delay(100);
}).then(function() {
UBX_CFG_PMS();
return delay(20);
}).then(function() {
UBX_CFG_SAVE();
return delay(20);
}).then(function() {
log_debug("Powering GPS Off");
/*
* must be part of the promise chain to ensure that
* setup does not return and powerOff before config functions
* have run
*
*/
Bangle.setGPSPower(0); Bangle.setGPSPower(0);
return delay(20);
}); });
}, 100);
} }
function setupPSMOO() {
log_debug("setupGPS() PSMOO");
Promise.resolve().then(function() {
UBX_CFG_RESET();
return delay(100);
}).then(function() {
UBX_CFG_PM2(settings.update, settings.search);
return delay(20);
}).then(function() {
UBX_CFG_RXM();
return delay(20);
}).then(function() {
UBX_CFG_SAVE();
return delay(20);
}).then(function() {
log_debug("Powering GPS Off");
/*
* must be part of the promise chain to ensure that
* setup does not return and powerOff before config functions
* have run
*
*/
Bangle.setGPSPower(0);
return delay(20);
});
}
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);
Serial1.write(d);
}
// UBX-CFG-PMS - enable power management - Super-E
function UBX_CFG_PMS() {
log_debug("UBX_CFG_PMS()");
writeGPScmd([0x06,0x86, // msg class + type
8,0,//length
0x00,0x03, 0,0, 0,0, 0,0]);
}
// convert an integer to an array of bytes
function int_2_bytes( x ){
var bytes = [];
var i = 4;
do {
bytes[--i] = x & (255);
x = x>>8;
} while (i);
return bytes;
}
/*
* Extended Power Management
* update and search are in milli seconds
* settings are loaded little endian, lsb first
*
* https://github.com/thasti/utrak/blob/master/gps.c
*/
function UBX_CFG_PM2(update,search) {
log_debug("UBX_CFG_PM2()");
var u = int_2_bytes(update*1000);
var s = int_2_bytes(search*1000);
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 */
u[3], u[2], u[1], u[0], /* update period, ms, 120s=00 01 D4 C0, 30s= 00 00 75 30 */
s[3], s[2], s[1], s[0], /* search period, ms, 120s, 20s = 00 00 4E 20, 5s = 13 88 */
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 */
}
// enable power saving mode, after configured with PM2
function UBX_CFG_RXM() {
log_debug("UBX_CFG_RXM()");
writeGPScmd([0x06, 0x11, /* UBX-CFG-RXM */
2, 0, /* length */
0x08, 0x01]); /* reserved, enable power save mode */
}
/*
* Save configuration otherwise it will reset when the GPS wakes up
*
*/
function UBX_CFG_SAVE() {
log_debug("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
0x07]); // b2=eeprom b1=flash b0=bat backed ram
}
/*
* 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() {
log_debug("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]);
}
/*********** GPS Setup Menu App *****************************/ /*********** GPS Setup Menu App *****************************/
function showMainMenu() { function showMainMenu() {
@ -220,14 +66,13 @@ function showMainMenu() {
updateSettings(); updateSettings();
}, },
}, },
'Update (s)': { 'Update (s)': {
value: settings.update, value: settings.update,
min: 10, min: 10,
max: 1800, max: 1800,
step: 10, step: 10,
onchange: v => { onchange: v => {
settings.update =v; settings.update = v;
updateSettings(); updateSettings();
} }
}, },
@ -262,4 +107,3 @@ function exitSetup() {
loadSettings(); loadSettings();
showMainMenu(); showMainMenu();

179
apps/gpssetup/gpssetup.js Normal file
View File

@ -0,0 +1,179 @@
const SETTINGS_FILE = "gpssetup.settings.json";
function log_debug(o) {
//let timestamp = new Date().getTime();
//console.log(timestamp + " : " + o);
}
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);
Serial1.write(d);
}
// UBX-CFG-PMS - enable power management - Super-E
function UBX_CFG_PMS() {
log_debug("UBX_CFG_PMS()");
writeGPScmd([0x06,0x86, // msg class + type
8,0,//length
0x00,0x03, 0,0, 0,0, 0,0]);
}
/*
* Extended Power Management
* update and search are in milli seconds
* settings are loaded little endian, lsb first
*
* https://github.com/thasti/utrak/blob/master/gps.c
*/
function UBX_CFG_PM2(update,search) {
log_debug("UBX_CFG_PM2()");
// convert an integer to an array of bytes
function int_2_bytes( x ){
var bytes = [];
var i = 4;
do {
bytes[--i] = x & (255);
x = x>>8;
} while (i);
return bytes;
}
var u = int_2_bytes(update*1000);
var s = int_2_bytes(search*1000);
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 */
u[3], u[2], u[1], u[0], /* update period, ms, 120s=00 01 D4 C0, 30s= 00 00 75 30 */
s[3], s[2], s[1], s[0], /* search period, ms, 120s, 20s = 00 00 4E 20, 5s = 13 88 */
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 */
}
// enable power saving mode, after configured with PM2
function UBX_CFG_RXM() {
log_debug("UBX_CFG_RXM()");
writeGPScmd([0x06, 0x11, /* UBX-CFG-RXM */
2, 0, /* length */
0x08, 0x01]); /* reserved, enable power save mode */
}
/*
* Save configuration otherwise it will reset when the GPS wakes up
*/
function UBX_CFG_SAVE() {
log_debug("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
0x07]); // b2=eeprom b1=flash b0=bat backed ram
}
/*
* 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() {
log_debug("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]);
}
function delay(ms) {
return new Promise(resolve => setTimeout(resolve, ms));
}
function setupSuperE() {
log_debug("setupGPS() Super-E");
return Promise.resolve().then(function() {
UBX_CFG_RESET();
return delay(100);
}).then(function() {
UBX_CFG_PMS();
return delay(20);
}).then(function() {
UBX_CFG_SAVE();
return delay(20);
}).then(function() {
log_debug("Powering GPS Off");
/*
* must be part of the promise chain to ensure that
* setup does not return and powerOff before config functions
* have run
*/
return delay(20);
});
}
function setupPSMOO(settings) {
log_debug("setupGPS() PSMOO");
return Promise.resolve().then(function() {
UBX_CFG_RESET();
return delay(100);
}).then(function() {
UBX_CFG_PM2(settings.update, settings.search);
return delay(20);
}).then(function() {
UBX_CFG_RXM();
return delay(20);
}).then(function() {
UBX_CFG_SAVE();
return delay(20);
}).then(function() {
log_debug("Powering GPS Off");
/*
* must be part of the promise chain to ensure that
* setup does not return and powerOff before config functions
* have run
*/
return delay(20);
});
}
/** Set GPS power mode (assumes GPS on), returns a promise.
Either:
require("gpssetup").setPowerMode() // <-- set up GPS to current saved defaults
require("gpssetup").setPowerMode({power_mode:"PSMOO", update:optional, search:optional}) // <-- PSMOO mode
require("gpssetup").setPowerMode({power_mode:"SuperE"}) // <-- Super E mode
See the README for more information
*/
exports.setPowerMode = function(options) {
settings = require("Storage").readJSON(SETTINGS_FILE,1)||{};
if (options) {
if (options.update) settings.update = options.update;
if (options.search) settings.search = options.search;
if (options.power_mode) settings.power_mode = options.power_mode;
}
settings.update = settings.update||120;
settings.search = settings.search||5;
settings.power_mode = settings.power_mode||"SuperE";
if (options) require("Storage").write(SETTINGS_FILE, settings);
if (settings.power_mode === "PSMOO") {
return setupPSMOO(settings);
} else {
return setupSuperE();
}
};