You are reading a single comment by @HughB and its replies. Click here to read the full conversation.
  • 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/mas­ter/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/0D5­2p0000925T00CAE/ublox-max-m8q-getting-st­uck-when-sleeping-with-extint-pin-contro­l
       */
      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("GBgCAAAAAAAAAAQAAAAAAD­8AAAAAAP/AAAAAAP/wAAAAAH/8C9AAAB/8L/QAAA­fwv/wAAAHS//wAAAAL//gAAAAf/+AAAAAf/4AAAA­L//gAAAAD/+DwAAAB/Uf8AAAAfA//AAAACAf/wAA­AAAH/0AAAAAB/wAAAAAAfAAAAAAAAAAAAAAAAAAA­AAAAAAAAAAAAAA"),this.x,this.y);
        if (gps_power && have_fix) {
          g.setColor("#00FF00");
          g.drawImage(fixToggle ? atob("CgoCAAAAA0AAOAAD5AAPwAAAAAAAAAAAAA­AAAA==") : atob("CgoCAAABw0AcOAHj5A8PwHwAAvgAB/wABU­AAAA=="),this.x,this.y+14);
        } else {
          g.setColor("#0000FF");
          if (fixToggle) g.setFont("6x8").drawString("?",this.x,t­his.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("m­EwghC/AH4AKg9wC6t3u4uVC6wWBI6t3uJeVuMQCq­cBLisAi4XLxAABFxAXKgc4DBAuBRhQXEDAq7MmYX­EwBHEXZYXFGAOqAAKDMmczC4mIC62CC50PC4JIBk­QABiIvRmURAAUSjQXSFwMoxGKC6CRFwUSVYgXLPI­gXXwMYegoXLJAYXCGBnzGA0hPQIwMgYwGC6gwCC4­ZIMC4gYBC604C4ZISmcRVgapQAAMhC6GIJIwXCMB­cIxGDDBAuLC4IwGAARGMAAQWGmAXPJQoWMC4pwCC­poXJAB4XXAH4A/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.

About

Avatar for HughB @HughB started