added gpssetup app

pull/666/head
hughbarney 2021-02-09 12:52:44 +00:00
parent 754826a3a3
commit 68252a0c5e
5 changed files with 330 additions and 0 deletions

1
apps/gpssetup/ChangeLog Normal file
View File

@ -0,0 +1 @@
0.01: First version of GPS Setup app

64
apps/gpssetup/README.md Normal file
View File

@ -0,0 +1,64 @@
# GPS Setup
An App to enable the GPS to be configured into low power mode.
## Goals
To develop app that sets the GPS up to run with the lowest possible
power consumption.
* An app that turns on the GPS and constantly displays the screen
will use around 75mA, the battery will last between 3-4 hours.
* Using the GPS in a Widget in Super-E Power Saving Mode (PSM) with
the screen off most of the time, will consume around 35mA and you
might get 10hrs before a recharge.
* Using the GPS in Power Saving Mode On/Off (PSMOO) with suitable
settings can reduce the average consumption to around 15mA. A
simple test using a 120s update period, 6s search period was still
running with 45% battery 20 hours after it started.
## Settings
The Settings App enables you set the options below for the GPS.
Either start the App from the launcher or go to Settings, select
App/Widgets and then 'GPS Setup'.
When you exit the setup App the settings will be stored in the
gpssetup.settings.json file; the GPS will be switched on and the
necessary commands sent to the GPS to configure it. The GPS is then
powered off. The GPS configuration is stored in the GPS non-volatile
memory so that next time the GPS is powered on they are used. These
settings will remain and impact every app that uses the GPS.
- Power Mode:
- SuperE - the factory default setup for the GPS. The recommended
power saving mode.
- 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
power mode (7mA) between obtaining fixes (35mA). For walking in
open country an update once every 60 seconds is adequate to put
you within a 6 digit grid refernce sqaure.
- update - the time between two position fix attempts.
- search - the time between two acquisition attempts if the receiver
is unable to get a position fix.
## 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 Power Management App Note](https://www.u-blox.com/sites/default/files/products/documents/PowerManagement_AppNote_%28UBX-13005162%29.pdf)
* Some useful code on Github and 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)

260
apps/gpssetup/app.js Normal file
View File

@ -0,0 +1,260 @@
Bangle.loadWidgets();
Bangle.drawWidgets();
const SETTINGS_FILE = "gpssetup.settings.json";
let settings = undefined;
let settings_changed = false;
function updateSettings() {
require("Storage").write(SETTINGS_FILE, settings);
settings_changed = true;
}
function loadSettings() {
log_debug("loadSettings()");
settings = require("Storage").readJSON(SETTINGS_FILE,1)||{};
settings.update = settings.update||120;
settings.search = settings.search||5;
settings.power_mode = settings.power_mode||"SuperE";
log_debug(settings);
}
/*********** GPS Power and Setup Functions ******************/
function log_debug(o) {
//console.log(o);
}
// 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);
if (settings.power_mode === "PSMOO") {
setupPSMOO();
} else {
setupSuperE();
}
log_debug("Powering GPS Off");
Bangle.setGPSPower(0);
}
function setupPSMOO() {
log_debug("setupGPS() PSMOO");
UBX_CFG_RESET();
wait(100);
UBX_CFG_PM2(settings.update, settings.search);
wait(20);
UBX_CFG_RXM();
wait(20);
UBX_CFG_SAVE();
wait(20);
}
function setupSuperE() {
log_debug("setupGPS() Super-E");
UBX_CFG_RESET();
wait(100);
UBX_CFG_PMS();
wait(20);
UBX_CFG_SAVE();
wait(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() {
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) {
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() {
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() {
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() {
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() {
var power_options = ["SuperE","PSMOO"];
const mainmenu = {
'': { 'title': 'GPS Setup' },
'< Back': ()=>{exitSetup();},
'Power Mode': {
value: 0 | power_options.indexOf(settings.power_mode),
min: 0, max: 1,
format: v => power_options[v],
onchange: v => {
settings.power_mode = power_options[v];
updateSettings();
},
},
'Update (s)': {
value: settings.update,
min: 10,
max: 1800,
step: 10,
onchange: v => {
settings.update =v;
updateSettings();
}
},
'Search (s)': {
value: settings.search,
min: 1,
max: 65,
step: 1,
onchange: v => {
settings.search = v;
updateSettings();
}
}
};
return E.showMenu(mainmenu);
}
/*
function exitSetup() {
log_debug("exitSetup()");
if (settings_changed) {
log_debug(settings);
E.showMessage("Configuring GPS");
setupGPS();
}
load();
}
*/
function exitSetup() {
log_debug("exitSetup()");
if (settings_changed) {
log_debug(settings);
E.showMessage("Configuring GPS");
setTimeout(function() {
setupGPS();
setTimeout(function() { load() }, 750);
}, 500);
} else {
load();
};
}
/*
function exitSetup() {
log_debug("exitSetup()");
if (settings_changed) {
log_debug(settings);
g.clear();
g.setFontAlign(0,0);
g.setColor(3);
g.setFontVector(25);
g.drawString("Configuring GPS",120,120);
setTimeout(function() {
setupGPS();
setTimeout(function() { load() }, 500);
}, 500);
} else load();
}
*/
loadSettings();
showMainMenu();

View File

@ -0,0 +1,4 @@
(function(back) {
// just go right to our app
load("gpssetup.app.js");
})();

View File

@ -0,0 +1 @@
{"power_mode":"SuperE", "update":120, "search":6}