From 68252a0c5ecca0ecd328050f341c1b5d54025670 Mon Sep 17 00:00:00 2001 From: hughbarney Date: Tue, 9 Feb 2021 12:52:44 +0000 Subject: [PATCH] added gpssetup app --- apps/gpssetup/ChangeLog | 1 + apps/gpssetup/README.md | 64 +++++++++ apps/gpssetup/app.js | 260 ++++++++++++++++++++++++++++++++++++ apps/gpssetup/settings.js | 4 + apps/gpssetup/settings.json | 1 + 5 files changed, 330 insertions(+) create mode 100644 apps/gpssetup/ChangeLog create mode 100644 apps/gpssetup/README.md create mode 100644 apps/gpssetup/app.js create mode 100644 apps/gpssetup/settings.js create mode 100644 apps/gpssetup/settings.json diff --git a/apps/gpssetup/ChangeLog b/apps/gpssetup/ChangeLog new file mode 100644 index 000000000..0099beb29 --- /dev/null +++ b/apps/gpssetup/ChangeLog @@ -0,0 +1 @@ +0.01: First version of GPS Setup app diff --git a/apps/gpssetup/README.md b/apps/gpssetup/README.md new file mode 100644 index 000000000..4992a16b5 --- /dev/null +++ b/apps/gpssetup/README.md @@ -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) + diff --git a/apps/gpssetup/app.js b/apps/gpssetup/app.js new file mode 100644 index 000000000..18dc57ec5 --- /dev/null +++ b/apps/gpssetup/app.js @@ -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>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(); + diff --git a/apps/gpssetup/settings.js b/apps/gpssetup/settings.js new file mode 100644 index 000000000..0e3c621d1 --- /dev/null +++ b/apps/gpssetup/settings.js @@ -0,0 +1,4 @@ +(function(back) { + // just go right to our app + load("gpssetup.app.js"); +})(); diff --git a/apps/gpssetup/settings.json b/apps/gpssetup/settings.json new file mode 100644 index 000000000..631ececdc --- /dev/null +++ b/apps/gpssetup/settings.json @@ -0,0 +1 @@ +{"power_mode":"SuperE", "update":120, "search":6}