System.sleep() not working on 0.7.0-rc.6 with photon

Having had a major diversion with hardware issues on a PCB (manufactured with 10 ohm instead of 10k ohm - causing the SPI to not work) I have now got back to test the functionality related to power saving if the AC supply is removed and resuming when the supply is restored. The supply to the photon is battery backed up but to ensure recovery after long potential periods of outage. A lot of power management is employed with the peripheral devices including turning off SPI bus and setting all SPI related pins to INPUT using pinMode().

When the AC power is restored a 50 mS pulse HIGH is made on the wake pin.

What I have now found is that when I call System.sleep(wake, CHANGE, sleepPeriod); The photon LED is left breathing cyan - in other words it is not turning off the network and sleeping. Then after a period my application watchdog kicks in and does a system resume. Any one else had this issue with System.sleep() on 0.7.0-rc.6?

Edit: I have noticed that after calling the System.sleep() - approximately 2 minutes the photon LED does a red flash SOS followed by 10 flashes (Assertion Failure?).

How is your wake pin wired? Have you got external pull-resistors in place?

About your SOS+10 panic, we’d need to know more about your code - maybe even see a video since SOS+10 is not seen very often.

BTW, mS is the unit for conductance (milli Siemens)

1 Like

@ScruffR, wake pin is connected to the output of an OR gate which logically ORs 1 input from capacitive touch button 1 and the other is an output from a specialist IC that generates a timed pulse high. This goes in D4.

I will try and do a video - ’ Assertion Failure’ what does it mean - I did a search and there is very little as to what is the cause.

I think you may be on the right lines with the hardware and the pin. There is a 3.3V bus to all peripheral devices (capacitive touch buttons) and this is turned off before the System.sleep() is called. So what might be happening is that the output/signal from cap touch button 1 is floating high and triggering a false ‘wake’.

mS rather than milli Seconds - yes that’s me rushing.

Further thought: I checked and button1 controller is not unpowered like the other peripherals and neither is the OR gate. Also, the wake pinMode is pinMode(button1, INPUT_PULLDOWN); //unpressed = LOW, pressed = HIGH I am rather wishing this isn’t a hardware issue as that means another hardware change cycle - 4 weeks!

I’m not 100% certain how things behave with a CHANGE wake, but for FALLING and RISING, a previously set pinMode() won’t help there since the System.sleep() statement overrides the pinMode() according to the selected wake edgh. So if it is the same with CHANGE - as I’d assume - the INPUT_PULLDOWN won’t have any effect for the sleep periode.
But as long your OR-gate is never floating you should be find - but just double check.

About Assertion Failures these seem to be a rather non-descript errors which may require some hardware debugging to really track down where they happen.
But as said, since we see them rather rarely in the wild, I’d like to confirm it wasn’t a miscounted SOS+10 - hence the video.

@armor, you may also want to put a pull-down one the CapTouch1 input of the OR if you expect it to float.

1 Like

I am not expecting the button1 pin to float. The power return signal generator and the button 1 controller both remain connected to 5V through the battery backup. To test this theory I have just soldered a 10K resistor from the button1 pin (D4) to ground. The result - no difference!

I thought I would take the wake pin out of the equation and have tried just System.sleep(sleepPeriod); This does not work either! I must assume there is something in the activities before calling System.sleep() that is disabling it.

gotosleep steps are as follows: PCB_REV5 is defined as true

screenOff();
tft.enterSleep();                   //put screen into low power mode whilst sleeping
delay(100);                         //ensure power settled V090C
#if PCB_REV5
SPI.end();                          //Disable SPI bus and pin use V091Q
pinMode(tftcs,  INPUT);             //to avoid push/pull turn all OUTPUTS to INPUTS V091Q
pinMode(A3,     INPUT);             //to avoid push/pull turn all OUTPUTS to INPUTS V091Q
pinMode(A4,     INPUT);             //to avoid push/pull turn all OUTPUTS to INPUTS V091Q
pinMode(A5,     INPUT);             //to avoid push/pull turn all OUTPUTS to INPUTS V091Q
pinMode(dcrs,   INPUT);             //to avoid push/pull turn all OUTPUTS to INPUTS V091Q
pinMode(rst,    INPUT);             //to avoid push/pull turn all OUTPUTS to INPUTS V091Q
pinMode(sdcs,   INPUT);             //to avoid push/pull turn all OUTPUTS to INPUTS V091Q
//Determined that the power control pin must be set LOW/off after everything else
digitalWrite(pwrPin, LOW);          //turn off switched power to peripherals V091E
delay(500);
#endif

Maybe you can spot something in this.

I think the SOS + 10 flashes is coming after the application watchdog has kicked in and it tries to resume and is nothing to do with it not going to sleep.

Is that D4 on the STM32 or some other D4? The purpose of the resistor is to prevent a floating A input of the OR gate from creating oscillation at the Y output of the OR.

As for your code, we would need to see what you do before and after calling the code you posted.

The resistor is between pins 4 and 3 on U11 - thus pulling pin D4 on the photon to ground. I am not convinced this is the problem. The test proved that.

Everything I do before the System.sleep() is in the post above. The fact that System.sleep() is not working suggests to me that there is something in the power down that is stopping it working. Next step is to work through those steps to find what is causing the problem. I was hoping that someone might have known of a System.sleep() issue with 0.7.0-rc.6!

Not so. The output of the OR gate is forced and always active since you don’t remove the 5v supply. You need the pull-down between pin 1 and 3 of U11 since the potential float condition occurs on the INPUT of the OR. With pin 1 floating, the OR output could potentially oscillate.

Nonetheless, the code prior to and after your sleep needs to be reviewed as well. Is the code you post in a function you call? What do you do AFTER waking?

Just a note about this: This is not a sleep mode in regards to the µC. This will only disable the radio module for some time but has no impact on the controller or the execution of code.

BTW, I have performed several tests with System.sleep(SLEEP_MODE_DEEP) and System.sleep(pin, ...) on Photons and Electrons with 0.7.0-rc.6 due to statemens of various members who expected a problem with the system, but so far they all came down to some kind of misconception or misapplication on the user’s side.

Also, since you know your wake signal will produce both a rising as well as a falling edge, have you tried using FALLING or RISING for the wake trigger? Does this change anything?

1 Like

After the System.sleep() I read the value of the wake pin to determine whether the sleep timeout or wake pin RISING has happened. Then what happens is the power shutdown is reversed and I restore the run state from an eeprom stored variable.

@armor, can you share your “reversal” code?

@peekay123, I have done a bit more exploration of the Pre-sleep code and it appears that calling SPI.end(); is stopping the System.sleep(); from working. To repeat if I comment out SPI.end(); in the code shared above it all works perfectly. Is this an issue with 0.7.0-rc.6? I have had this working on previous releases of 0.7.0-rc, I need to revert back to one of those versions and see what the result is.

1 Like

@armor, interesting. Try regressing to an earlier release and report back. This may be an issue that needs to be posted on the firmware repo.

1 Like

I have regressed to 0.7.0-rc.4 and with SPI.end(); called again the System.sleep(pin, trigger, timeout); does NOT work.
I have then regressed to 0.7.0-rc.2 and that does NOT work either. So possible that it has never worked since I introduced SPI.end() to shutdown the SPI bus and the potential power drain. I will now try and see what the power consumption is without the SPI.end(); Still I guess SPI.end(); should not interfere with System.sleep(); How do I post this on the firmware repo?

@ScruffR, my aim here is to reduce the power consumption of the board to a level that will allow the backup battery (175mAh - that’s milliAmp hours) to last a reasonable period. On other products I have easily got under 2mA. When we were designing the board for this product we wanted to be able to wake when the power is restored and this has been achieved. Also, the device should wake itself after 24 hours and shout-out that it still has no power.

The simple issue is that if I include SPI.end(); before the System.sleep(pin,trigger,timeout); it does not go to sleep and shutdown the radio thus the power consumption is left too high. I did try changing the wake trigger CHANGE, RISING both work when SPI.end(); is removed. As always I really appreciate you thinking all the angles.

1 Like

@armor, looking at the SPI.end() code, I noticed that any SPI resource is protected by a mutex is system threading is enabled. A beginTransmission() locks the resource and endTransmission() unlocks it. If neither of these command is used, then no mutex is used. So, not sure how the mutex plays in to the mix. I assumed the end() code in the firmware correctly resets the SPI hardware.