0.02: Created gppsetup module

pull/667/head
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",
"shortName":"GPS Setup",
"icon": "gpssetup.png",
"version":"0.01",
"version":"0.02",
"description": "Configure the GPS power options and store them in the GPS nvram",
"tags": "gps, tools, outdoors",
"readme": "README.md",
"storage": [
{"name":"gpssetup","url":"gpssetup.js"},
{"name":"gpssetup.settings.js","url":"settings.js"},
{"name":"gpssetup.settings.json","url":"settings.json"},
{"name":"gpssetup.app.js","url":"app.js"},

View File

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

View File

@ -1,6 +1,6 @@
# 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
@ -22,7 +22,7 @@ Example power consumption of the GPS while powered on:
running with 45% battery 20 hours after it started.
## Settings
## Settings App
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
@ -38,11 +38,11 @@ used. These settings will remain for all apps that use the GPS.
- 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
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
position update less often (say every 1 or 2 minutes). The longer
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
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
* [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)
and [here](https://github.com/thasti/utrak/blob/master/gps.c)

View File

@ -15,6 +15,11 @@
Bangle.loadWidgets();
Bangle.drawWidgets();
function log_debug(o) {
//let timestamp = new Date().getTime();
//console.log(timestamp + " : " + o);
}
const SETTINGS_FILE = "gpssetup.settings.json";
let settings = undefined;
let settings_changed = false;
@ -35,174 +40,15 @@ function loadSettings() {
/*********** GPS Power and Setup Functions ******************/
function log_debug(o) {
//let timestamp = new Date().getTime();
//console.log(timestamp + " : " + o);
}
function setupGPS() {
Bangle.setGPSPower(1);
if (settings.power_mode === "PSMOO") {
setupPSMOO();
} else {
setupSuperE();
}
setTimeout(function() {
require("gpssetup").setPowerMode().then(function() {
Bangle.setGPSPower(0);
});
}, 100);
}
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);
return delay(20);
});
}
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 *****************************/
function showMainMenu() {
@ -217,18 +63,17 @@ function showMainMenu() {
format: v => power_options[v],
onchange: v => {
settings.power_mode = power_options[v];
updateSettings();
updateSettings();
},
},
'Update (s)': {
value: settings.update,
min: 10,
max: 1800,
step: 10,
onchange: v => {
settings.update =v;
updateSettings();
settings.update = v;
updateSettings();
}
},
'Search (s)': {
@ -237,8 +82,8 @@ function showMainMenu() {
max: 65,
step: 1,
onchange: v => {
settings.search = v;
updateSettings();
settings.search = v;
updateSettings();
}
}
};
@ -262,4 +107,3 @@ function exitSetup() {
loadSettings();
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();
}
};