When my Asset Tracker electron only sleeps for a few seconds up to 1-2 minutes, all is fine and my code below works. If it stays in sleep mode for longer than this time however, it will wake-up on move, and go back to permanent sleep within several seconds.
It used to work just fine; the only piece of code I have really changed is adding
to Reset_State, and:
to GPS_wait_state, as I was having issues with the GPS staying enabled throughout System.sleep. Any thoughts? Is this a correct way of disengaging the GPS during sleep?
Not quite sure what you want to do with these pin manipulations.
Why would you set the pin HIGH before you set the pin mode to OUTPUT?
digitalWrite() will not do any output operations on a pin when it isn’t set to
digitalWriteFast() which does assume the mode is already set correctly and hence will perform the action).
Similarly setting the pin HIGH immediately followed by setting the pin as
INPUT won’t do much either (apart from a few nano/micor seconds of HIGH level).
However, does the device start behave normal again once you remove these lines of code (e.g. one set at a time)?
Without looking into the code, my hunch would be that disabling the GPS module via D6 might mess up things a bit
I came across this topic: Is there a debugged asset tracker GPS library yet? in which someone mentioned digitalWrite() coupled with pinMode() should correctly disable the GPS module before System.sleep.
So if I understand correctly, in Reset_state I should simply use digitalWrite() to set D6 to HIGH, and then set D6 to LOW in the same fashion in GPS_Wait_state to turn on the GPS for signal collection? And leave the pinMode() to Output throughout all of the code?
I wouldn’t know why you’d need a
digitalWrite(D6, HIGH) before setting the pin to
INPUT since there is a 10k pull-up resistor on the shield that ensures a HIGH (GPS off) on GPS_PWR_EN.
But just in case this is required (for whatever reason) I’d write things like this instead
pinSetFast(D6); // will set the output register for D6 to HIGH
// performed immediateld in OUTPUT mode or
// prepare HIGH for next time pin is set to OUTPUT
pinMode(D6, INPUT); // this alone should actually be enough
pinMode(D6, OUTPUT); // set as output
digitalWrite(D6, LOW); // *now* set LOW
// alternatively you could use
pinResetFast(D6); // will set the output register for D6 to LOW (prepare for OUTPUT)
pinMode(D6, OUTPUT); // now activate OUTPUT LOW
When my sensor is in System.sleep(), while having been unable to acquire a GPS signal the last time it was awake, the SAT FIX light will continue to blink for days. So I’ve been looking for a way to shut off the GPS module completely when the sensor is in System.Sleep, to save on power consumption.
Regardless of pinMode();, would simply stating digitalWrite(D6, HIGH) before sleep, and digitalWrite(D6, LOW) after sleep work for this? My sensor currently is only able to last for about 2 to 3 days max on the battery, which is way too short for what Im trying to accomplish (it wakes up max. once a day for less than 2 minutes) and I’m assuming the GPS plays a big role in that.
One thing has to be noted here.
There are different kinds of
System.sleep() that will impact the behaviour of the pins during sleep.
The one you use here …
System.sleep(WKP, RISING, TIME_PUBLISH_BATTERY_SEC);
… is called Stop Mode Sleep and will keep the pins (apart from the wake pin - here WKP) set as they were on entry of sleep mode. So in this sleep mode, you have to deactivate the GPS module by letting D6 go HIGH via the external pull-up resistor (via
pinMode(D6, INPUT)) or explicitly set it HIGH - the code will carry on execution at the first instruction after the sleep command.
In deep sleep (in STM32 jargon Standby Sleep) all pins (apart from WKP) will be set to HIGH-Z which will implicitly let the let the pull-up take over and deactivate the GPS module - the code will start from a reset state (the beginning of your code).
Deep sleep would be the most power efficient sleep mode.
So does that mean upon wakeup from deepsleep the sensor will always start executing void setup() and then void loop() ? If so, I should build my code accordingly.
EDIT: indeed it seems to start at void setup() first. Should just be a minor adjusment in code though, but a huge profit in power management i hope!
EDIT 2: Simply used
in void setup(), and system.Sleep(DEEP_SLEEP_MODE) in void loop()…seems to work great!
When using this code: https://go.particle.io/shared_apps/5983a638cc5d512f56001b73
When the sensor is in Deep_sleep_mode for more than about 2-3 minutes, upon wake-up, it will breathe white, will not execute any code and Windows will give a USB error.
Because before sending the device to sleep you tell it to switch the radio off via
In addition to switch the radio back on, I’d also suggest you use
SYSTEM_MODE(SEMI_AUTOMATIC) to indicate the intent to manually control the radio.
I’m a bit confused here; if it’s set to Automatic mode, wouldn’t it by default already turn on the cellular connection when it wakes up? This is how I would do it before in Stop_Sleep_mode and it never had issues connecting with that.