Q. Power and storage consumption

Posted on
of 3
/ 3
Last Next
  • Hi, I'm trying to knock out a project with my new pico for May. I need to log GPS co-ordinates for about 9 hours for 3 days. I can charge between that. Then offload all this data to a pc.

    I've been reading some docs and I think I'll have to write this to an SD card. Would another option be to use a typed array in RAM and use save() every now and then so I don't have to panic about losing power and all the data?

    I see the sleep current draw advertised but what's the peak power so I can make a worst case estimate to size the battery I'm buying (factoring in the GPS unit naturally). I assume the pico will sleep as best it can for me? I'm used to the arduino and I'd have to program in the sleep calls.

    Is there any way to put a female USB-A on a pendrive and get the pico to write to that? Just trying to get out of doing the SD card bit of I can.

  • You'd need to give a lot of thought to periodically save();-ing... I'm not sure that's a great idea.

    The Espruino sleeps while the interpreter is idle, but you can also setDeepSleep() to make it sleep more aggressively - see the reference page.

    If it's that small an amount of information that it would fit in ram, you could save it on an EEPROM (like AT24 ) - see http://www.espruino.com/EEPROMs

    What's the issue with using a (micro)SD card?

  • No issue other than I thought avoiding it might be easier. I'm probably wrong.

  • With v77 of Espruino firmware, it should be as simple as wiring up a uSD breakout board, and making one extra function call before doing the filesystem calls (v76 for pico wasn't built with the support enabled - this omission is fixed).

    Using sd card on Espruino is simple, and you get oodles of space for cheap, and it's super easy to transfer to computer. It's great for datalogging. It's less ideal if you're storing data and then later using it on the Espruino - you can do it, but it's more awkward than an EEPROM.

    Neither EEPROM or SD card is hard to interface with on Espruino.

  • Is there any way to put a female USB-A on a pendrive and get the pico to write to that? Just trying to get out of doing the SD card bit of I can.

    Answer from @Gordon: plug-and-play for USB is not an option (yet)... may be it has changed.

    I had similar ideas when Pico was in the making and in scope definition. Because the USB infrastructure is already there, why not use it, for example also to drive any of the available communication dongles - Bluetooth, Wifi,...

  • On a different note that USB connection and storage: What kind of GPS board/provider are you thinking about?

  • There's no support for USB host (I think it requires extra hardware anyway), so you'd have to do something else. As others have said, SD card is probably easiest (in the next released version of the firmware), but then there are also several other types of EEPROM that will work and could potentially be a bit smaller/draw less power.

    Using a Typed Array and saving would work, but save() itself takes maybe a second during which the Espruino is totally unresponsive (and then everything restarts), so you may well miss some data from the GPS during that time.

    If you're confident in the battery then I guess you may not need to worry about saving at all - just let it run and pick up the data afterwards.

    Using setDeepSleep(1) will set Espruino up so it enters low power sleep modes when it can. Right now that's still around 1mA because of some issues with shutting down the USB peripheral so it can be restarted again, but that will change in the next month or so when the new USB drivers get added, and we'll hit the microamp level.

    For peak power, I can't remember the measurements but it should never go above 40mA. Potentially the SD card could add a lot of power draw though - honestly the best bet is probably just to measure it when you've got it all set up :)

  • So I went and read setDeepSleep and I'm thinking the following;

    I need 2 things;

    1. GPS coords + time periodically.
    2. GPS Coords + time on Button press, up to 30/second very briefly.

    If I log coords every 2 seconds that will let the pico sleep the most and keep a lot of tracking. Obviously up at 30 logs per second I can just cache the GPS coords and have them change as the board can send me location updates. I don't need that to exactly correlate. I assume the GPS will have a large inaccuracy anyway.

    Since time was an issue I've just bought the GPS unit in the docs so the Ublox NEO6MV2[pdf]

    I was assume worse case 250mA as that's is what the pico transformer says it maxes out. As you can imagine sizing a battery was getting concerting. 40mA is good to hear I know peripherals will add to that.

    Can the pico sleep and leave the GPS unit logging away as it is clearly not going to wake up and get a signal in the time I'm talking about. Will I need to wire power to that directly to keep it on or best just to forget about sleeping the pico?

    I'll trade you all your help for a blog post on how this goes.

  • Ahh - Yes, with setDeepSleep the Pico won't be able to receive data from the Serial port - which could make life a bit more tricky.

    I think in normal mode the GPS sends data once a second, so the easiest option might be something like:

    var gps = require("GPS").connect(Serial4, function(data) {
      // make sure we exit deep sleep a little bit before the next set of data comes in
      setTimeout(function() { setDeepSleep(0); }, 1800 /* may need tweaking */);
      // Ensure that when we exit this, we re-enter deep sleep
      // Do stuff with data
      // ...

    If you could speed up the baud rate output by the GPS then you'd also be able to limit the amount of time the Pico has to stay awake for.

    40mA is good to hear I know peripherals will add to that.

    If you mean peripherals inside the chip, I think you're fine - 40mA should include basically all of those. Looks like the GPS itself could draw ~70mA at startup though - but that's still low enough it can be run off the Pico's 3.3v regulator, so choosing a battery should be pretty easy.

    As far as logging every so often, I wonder whether you can put the GPS into a low power mode via the USART, or whether you'd have to physically switch off the power to it if you wanted to save power when idle.

    Looks like finding a battery will be easy though. It looks like without any power saving you'd be looking at under 50mA power draw total, so a single 3000mAh 18650 lithium battery would do 60 hours - which is quite close to what you need anyway. Use two of them in parallel and you should have plenty in hand.

  • I thought the data event from the GPS would wake up the pico if it was over 1.5 seconds. From what you've said I'll need to make sure the pico is awake on time. In that case and considering what you've said about power I might leave using sleep for a v2 of this. I'm not seeing how I can use a setWatch for the serial data.

    I would be worried about rounding errors in the timers, what's the resolution to the clock? I know IE was famous for only going down to 15.6ms

  • The issue is that when the Pico is properly 'deep' asleep, the high speed oscillator is off (which means there's no clock going to the Serial port either, so it can't receive any data). It's why setDeepSleep isn't just enabled by default.

    You can do setWatch on the serial signal, but by the time the Pico has woken up you'll have missed the first character or so of the data - hence why the code above...

    what's the resolution to the clock?

    It's 1/32768 of a sec when asleep, or when running it's nearer 1/1,000,000 sec - so probably not an issue :) What could be a problem is more the time it takes the JS to execute.

    So yes, it might be better to leave the real power saving for a while - I've just tested and without setDeepSleep the Pico is still only using 10mA normally, so for what you want that'll be fine.

    The F401 chip in the Pico also has much better clock control - the CPU can slow itself down from 84Mhz, saving a lot of power. That's something I plan on adding soon too - and when that happens you should be able to reduce power consumption a lot without even having to use setDeepSleep.

  • Probably not much help, but I have run the main Espruino board, single I2C board for pressure, temp and humidity and NEO6 GPS all logging every second to microSD card for 24 hours (so little sleep) from a 1000mAh 3.7v LiPo with power to spare, though not much.

    So assuming you can power down external kit while sleeping, battery requirements won't be huge I would have thought.

  • At the risk of sounding dim, require('GPS') is returning WARNING: Module "GPS" not found with the latest 1v77 pico firmware.

    The gps npm module is giving my compile error s so it can't mean to pull that one can it?

  • Are you entering that on the right side of the IDE? If you enter it on the left side, it won't be able to load the module. When you send code from the right, the IDE goes to the Espruino website, downloads the GPS module, and sends it to the Espruino, in addition to the code you're sending.

  • Ok I'm using the right side. Maybe my serial console is set up wrong, the gps is flashing merrily away but my gps.on('data'... or .connect console.logs aren't printing anything.

    If I just test Serial2 I can a pin can't RX but that's because it's not hooked up. Serial1 doesn't leave any errors. Just no output.

    // GPS Setup
    Serial1.setup(9600, {tx: B6, rx: B7});
    var gps = require('GPS').connect(Serial1, function(data){
    gps.on('data', function(data){


     _____                 _
    |   __|___ ___ ___ _ _|_|___ ___
    |   __|_ -| . |  _| | | |   | . |
    |_____|___|  _|_| |___|_|_|_|___|
              |_| http://espruino.com
     1v77 Copyright 2015 G.Williams

    Oh and I've waited a while and the GPS flashes green every second.

  • You don't need this extra gps.on("data",...) in lines 12 thru 14. You already pass the callback in anonymous form onto the connected gps (js) module in line 7 thru 10.

  • This would be your get going sequence:

    1. wire all up including pico to your pc
    2. open ide
    3. connect to espruino
    4. paste your code into the edit / right hand pane
    5. upload to the board
    6. wait
    7. wait
    8. wait
    9. watch console where the default handler's decoded line will show.

    It takes some time for the module to actually provide a line that the line handler can process...

    Before useful data shows through the default handler, the gps (hardware) module receives already lines and sends them to the (js) module, but they are not yet the lines the default handler looks for. That's why I added an enhanced handler that gives more information back then the default handler built into the Espruino module.

    When I built it, I was not familiar with the module build/update process... but now I could make a pull request and have other's benefit automatically from the get going.

  • The other gotcha is that GPS TX should be connected to Espruino RX, rather than TX to TX. Also it's possible that the Baud rate is wrong, as it looks like the same GPS can use different baud rates depending on how certain pins on the chip are connected.

  • Gordon yes I read that too I did try the 3 different baud rates but no change in output. I was staring at those RX/TX pins and thinking what you just said. I bet it's that.

    Thanks for the handler help I'll read everything today and try these changes when home from work.

  • Ok, the other option is to simply do:

    setWatch(function(e) {
    }, B7, {edge:"both", repeat:true});

    Hopefully that'll dump out a bunch of times (assuming the signal is getting through to the pin). If you take the shortest time you see appearing relatively often and then do 1/time you should get the baud rate of the signal.

  • The F401 chip in the Pico also has much better clock control - the CPU can slow itself down from 84Mhz, saving a lot of power. That's something I plan on adding soon too

    How slower can it be clocked? ...down to static? (like some CMOS uCs that were/are sent to space? ...down to single steppinh the clock? (Of course, that would disable wake ups, etc.).

    It is for sure an interesting feature...

    missing the first byte or so You can do setWatch on the serial signal, but by the time the Pico has woken up you'll have missed the first character or so of the data

    How fast is the thing moving that you track? ...and what is the resolution you expect? This may together with sending GPS to standby/sleep may give you various types of relieves:

    1. larger intervals than 2 seconds
    2. if delta from last position is less than your resolution (and of course the gps resolution), you drop / do not keep the tracking point
    3. not the gps is the clocking thing but Espruino. In other words Espruino timer wakes Espruino up, wakes up GPS and goes to sleep for the time GPS is waking up, comes out of sleep and is ready when GPS is sending data. Some GPS can send data 10 lines / s, so Espruino does not need to hangout awake too long in case it misses, it just has to stay up until it gets a complete set of data. Afer that it puts GPS to 'sleep', and goes to sleep itself as well.

  • Where is the gps module source code by the way? Or even the complete api reference for it I can't find a page. If there isn't I'll help write one.

    I've got this giving me data now. Yes I have the RX/RX pins matching not crossing silly me. Just getting lat,lon,fix,satellites and altitude now and I see the chip could give me a lot more.

    It did indeed take ages to receive a signal. There's a nice green LED on the GPS module that flashed when it ticks and has a signal fix.

  • For Espruino module, that is what you get: a

    The module is at http://www.espruino.com/modules/GPS.js .

    I list it in this thrad for discussion purpose. This source is what I cloned and enhanced for my purposes. You can to that easily for yourself as well.

    This are the steps:

    1. In Web IDE go to Setting (Cogwheel) - Projects
    2. Select a Directory (you made on your system) for Sandbox
    3. Copy the module code into the IDE editor (right side pane)
    4. Save the moduel under GPS_JB.js in the folder /modules
    5. Load your application code into the IDE editor
    6. Change the Require to to "GPS_JB.js"
    7. When you got it running to the point it runs now, you are ready to modify the moduel - either in the IDE editor - or what ever multi-document editor you are used to.
    8. Everytime you upload your application code to the board, it does not find
      the module in the official place (or you are not connected), it goes after your sandbox module folder and tries to load / loads it from there
    9. For now disable minification - because if you do iteratively - you may get flagged by the free Google closure compiler service that's invoked every time you upload and you are stuck until you change to no minification or the 'flag wears down' (may be that is not the case anymore... I do not have latest status from @Gorden about built in minifier / closure compiler / etc. But it does not hurt you yet, since you do not have much code with memory nor performance challenges).

    Now to the module code:

    /* Copyright (c) 2013 Gordon Williams, Pur3 Ltd. See the file LICENSE for copying permission. */
    Module for interfacing with serial (NMEA) GPS devices
    var gps = connect(Serial4, function(data) {
    function handleGPSLine(line, callback) {
      var tag = line.substr(3,3);
      if (tag=="GGA") {
        var d = line.split(",");
        var dlat = d[2].indexOf(".");
        var dlon = d[4].indexOf(".");
          { time: d[1].substr(0,2) + ":"+d[1].substr(2,2)+":"
                 + d[1].substr(4,2)
          , lat: (parseInt(d[2].substr(0,dlat-2),10)
                 + parseFloat(d[2].substr(dlat-2))/60)*(d[3­]=="S"?-1:1)
          , lon: (parseInt(d[4].substr(0,dlon-2),10)
                 + parseFloat(d[4].substr(dlon-2))/60)*(d[5­]=="W"?-1:1)
          , fix: parseInt(d[6],10)
          , satellites: parseInt(d[7],10)
          , altitude: parseFloat(d[9])
    exports.connect = function(serial, callback) {
      var gps = {line:""};
      serial.on('data', function(data) {
        gps.line += data;
        var idx = gps.line.indexOf("\n");
        while (idx>=0) {
          var line = gps.line.substr(0, idx);
          gps.line = gps.line.substr(idx+1);
          handleGPSLine(line, callback); 
          idx = gps.line.indexOf("\n");     
        if (gps.line.length > 80)
          gps.line = gps.line.substr(-80);
      return gps;

    When you say require("GPS") in your code, you get an object back that understands .connect(), where you pass the serial and your application function. The application function has to accept a prameter object, which is the object crated from the GPS data in the GPS module by the module only line handler in lines 18 through 26.

    Unfortunately the way the module is built and without changing it/that, it does you not give access to change this handler with something of your's that would be more powerful. The only thing accessible to you in the object reteurned from .connect() is an object with one property, and that is the data recieved but not processed yet by the handler.

    When the moudule is changed so that the module's integrated handler is put into thet returned gps object as a "handler:" property (in line 31) and then referenced in line 38, you could put just any other linehandler in there right afert connect.

    You have serveral options of remedy:

    First option:

    • in your cloned GPS_JB module:

      1. make line 31: var gps = {line:"", handle:handleGPSLine}
      2. make line 38: ```gps.handle(line,callback);

    • in your application:

      Serial1.setup(9600, {tx: B6, rx: B7});
      var gps = require('GPS_JB').connect(Serial1, function(data){
      gps.handle = function(line,callback) {
      // your line handler processing creating data object
      var data = { ... };

    Second (preferred option) {

    • in your cloned GPS_JB module:

      1. make line 30:

        2. make line 31:

        var gps = {line:"", handle:(handle) ? handle : handleGPSLine }```

      2. make line 38:

        - in your appliacation:

    Serial1.setup(9600, {tx: B6, rx: B7});
    var gps = require('GPS_JB').connect( Serial1,



    // your line handler processing creating data object
    var data = { ... };

    } );

    For the (anonymously) provided handle *function(line,callback)*  you can do something like that:


      // your line handler processing create data object
      var tag = line.substr(3,3), data;
      switch (tag) {
         case "GGA":
            data = {.... };
         case "XYZ":
            data = {.... };
      if {data) {callback(data); }


    Make sure your line handler as well as your applicaiton callback processing happens within the timeframe the next data come...

  • Re: 9 - there's now an option for offline minification in the IDE!

  • Post a reply
    • Bold
    • Italics
    • Link
    • Image
    • List
    • Quote
    • code
    • Preview

Q. Power and storage consumption

Posted by Avatar for JackBennett @JackBennett