Asset Tracker code help needed

I have a specific use case for the Electron asset tracker I need help with.

My brother is hiking the Appalachian Trail and I was trying to setup an asset tracker which would:

  1. Wake from deep sleep every 12 hours
  2. Get GPS fix
  3. Check battery status
  4. Turn on cellular
  5. Publish GPS location, battery status, altitude, speed
  6. Go into deep sleep

I’ve been using fancy asset tracker by @dick to seed the libraries and code I need and it works well, with the exception that it is mostly based on acceleration. I’ve tried commenting out the accelerometer sections but the electron will either a) fail to publish anything or b) publish every minute and never go to sleep.

Battery life is of main concern here as I don’t want him to have to carry extra batteries or have to take apart the box in the field.

Can anyone help a newb here?

Thanks in advance!

What system version have you got on your Electron?
What version are you targeting with your app code?
What System.sleep() command are you using?
Are you allowing enough time to actually connect and publish?

  1. 0.6.0

  2. 0.6.0

  3. System.sleep(SLEEP_MODE_DEEP, HOW_LONG_SHOULD_WE_SLEEP); as defined here:

    // lets wakeup every 24 hours and check in (seconds)
    #define HOW_LONG_SHOULD_WE_SLEEP (24 * 60 * 60)

    // when we wakeup from deep-sleep not as a result of motion,
    // how long should we wait before we publish our location?
    // lets set this to less than our sleep time, so we always idle check in.
    // (seconds)
    #define MAX_IDLE_CHECKIN_DELAY (HOW_LONG_SHOULD_WE_SLEEP - 60)

Other definitions:

// Publish every 1 minute when woken up by motion
#define PUBLISH_DELAY (1 * 60 * 1000)

// if no motion for 3 minutes, sleep! (milliseconds)
#define NO_MOTION_IDLE_SLEEP_DELAY (3 * 60 * 1000)

This might not be the best codebase to modify, do you think it would be better to take a simple example app like GPS_features.cpp and add in the timer with the sleep command? Which libraries would need to be included?

/* -----------------------------------------------------------
This example shows a lot of different features. As configured here
it'll check for a good GPS fix every 10 minutes and publish that data
if there is one. If not, it'll save you data by staying quiet. It also
registers 3 Particle.functions for changing whether it publishes,
reading the battery level, and manually requesting a GPS reading.
---------------------------------------------------------------*/

// Getting the library
#include "AssetTracker.h"

STARTUP(System.enableFeature(FEATURE_RETAINED_MEMORY));

// Set whether you want the device to publish data to the internet by default here.
// 1 will Particle.publish AND Serial.print, 0 will just Serial.print
// Extremely useful for saving data while developing close enough to have a cable plugged in.
// You can also change this remotely using the Particle.function "tmode" defined in setup()
int transmittingData = 1;

// Used to keep track of the last time we published data
long lastPublish = 0;

// How many minutes between publishes? 10+ recommended for long-time continuous publishing!
int delayMinutes = 1;

// Creating an AssetTracker named 't' for us to reference
AssetTracker t = AssetTracker();

// A FuelGauge named 'fuel' for checking on the battery state
FuelGauge fuel;

// setup() and loop() are both required. setup() runs once when the device starts
// and is used for registering functions and variables and initializing things
void setup() {
    // Sets up all the necessary AssetTracker bits
    t.begin();
    
    // Enable the GPS module. Defaults to off to save power. 
    // Takes 1.5s or so because of delays.
    t.gpsOn();
    
    // Opens up a Serial port so you can listen over USB
    Serial.begin(9600);
    
    // These three functions are useful for remote diagnostics. Read more below.
    Particle.function("tmode", transmitMode);
    Particle.function("batt", batteryStatus);
    Particle.function("gps", gpsPublish);
    
    }

// loop() runs continuously
void loop() {

    
            // You'll need to run this every loop to capture the GPS output
    t.updateGPS();

    // if the current time - the last time we published is greater than your set delay...
    if(millis()-lastPublish > delayMinutes*60*1000){
        // Remember when we published
        lastPublish = millis();
        
        //String pubAccel = String::format("%d,%d,%d",t.readX(),t.readY(),t.readZ());
        //Serial.println(pubAccel);
        //Particle.publish("A", pubAccel, 60, PRIVATE);
        
        // Dumps the full NMEA sentence to serial in case you're curious
        Serial.println(t.preNMEA());
        
        // GPS requires a "fix" on the satellites to give good data,
        // so we should only publish data if there's a fix
        if(t.gpsFix()){
            // Only publish if we're in transmittingData mode 1;
            if(transmittingData){
                // Short publish names save data!
                Particle.publish("G", t.readLatLon(), 60, PRIVATE);
            }
            // but always report the data over serial for local development
            Serial.println(t.readLatLon());
        }
    }
}

// Allows you to remotely change whether a device is publishing to the cloud
// or is only reporting data over Serial. Saves data when using only Serial!
// Change the default at the top of the code.
int transmitMode(String command){
    transmittingData = atoi(command);
    return 1;
}

// Actively ask for a GPS reading if you're impatient. Only publishes if there's
// a GPS fix, otherwise returns '0'
int gpsPublish(String command){
    if(t.gpsFix()){ 
        Particle.publish("G", t.readLatLon(), 60, PRIVATE);
        
        // uncomment next line if you want a manual publish to reset delay counter
        // lastPublish = millis();
        return 1;
    }
    else { return 0; }
}

// Lets you remotely check the battery status by calling the function "batt"
// Triggers a publish with the info (so subscribe or watch the dashboard)
// and also returns a '1' if there's >10% battery left and a '0' if below
int batteryStatus(String command){
    // Publish the battery voltage and percentage of battery remaining
    // if you want to be really efficient, just report one of these
    // the String::format("%f.2") part gives us a string to publish,
    // but with only 2 decimal points to save space
    Particle.publish("B", 
          "v:" + String::format("%.2f",fuel.getVCell()) + 
          ",c:" + String::format("%.2f",fuel.getSoC()),
          60, PRIVATE
    );
    // if there's more than 10% of the battery left, then return 1
    if(fuel.getSoC()>10){ return 1;} 
    // if you're running out of battery, return 0
    else { return 0;}
    

    Particle.publish(String("_status"), "sleeping!");
    delay(1000 * 120);
    
    
        //Put system to sleep for (seconds)
    System.sleep(SLEEP_MODE_DEEP, (360));

}

I’d actually start with a simple sample from the AssetTrackerRK library.