System.sleep() and wake an Internet Button with one of the buttons

I want to make an Internet Button go into deep sleep and be able to wake it using one of the buttons (button 1 on the PCB, the one below the USB connector)

if (b.buttonOn(1)) {
    System.sleep(D4,RISING);
    // allow for the user to release the button on wake up and not enter into a loop
    delay(500);

}

This code goes to sleep, but I guess there is no current on button 1 to trigger the wake process. Is that correct? Is there a way to implement a wake up trigger without external components?

Thanks

@marianov, just to be clear, System.sleep(D4,RISING); is NOT deep sleep but instead uses the STM32 “STOP” mode which uses a little more power.

None of the Internet Button buttons (!) have onboard pull-up resistors and they connect to ground. You could physically add a pull-up resistor, say 100K ohms between D4 and the 3V3 pin. Then, you would need to change your call to System.sleep(D4, FALLING); since the button will connect D4 to GND. This will wake the Photon as expected. :grinning:

1 Like

If you want deep sleep the only way to wake the devices is via WKP/A7 and a rising edge, this would need some extra wiring.
But System.sleep(D4, RISING) should set the pinMode(D4, INPUT_PULLDOWN); while FALLING requires INPUT_PULLUP - so to make it do what you want, you’d need if the button on the shield connect to 3V3 or GND and choose the correct edge (I’ve not had a look how it does).

… nevermind … @peekay123 was quicker again :+1:

1 Like

@ScruffR, the WKP/D7 pin is already committed. Also, I believe the Photon pins go Hi-Z when in sleep mode, thus the need for an external pull-up :smirk:

@peekay123, actually NO.

If you try System.sleep(D7, FALLING); you will notice, that the blue LED will be dimmly lit - even without setting the pinMode beforehand. We had a long discussion about this back in Core times, but obviously that hasn’t changed.
For deep sleep (Standby) it’s true that pins go Hi-Z, but not for Stop Mode.

But you are unfortunately right about WKP / A7 being used on the Internet Button, but with a carefully chosen “extra wiring” (which might include a pull-up ;-)) the button release might provide the required rising edge for waking from deep sleep.


But while testing this, I got an unexpected SOS hard fault with this code after waking - if you could have a look too: Is this something for Mat?

void setup()
{
  //pinMode(D7, INPUT_PULLDOWN);
  delay(5000);
}

uint32_t ms;
void loop() 
{
  if (millis()-ms > 10000)
  {
    System.sleep(D7, FALLING);
    ms = millis();
  }
}

@ScruffR, I’ll have to look at the pin behavior during sleep then! Not sure why you would get an SOS though. I’ll have to test this weekend. :grinning:

The only thing I could imagine (since D1 works) is that the JTAG features of D7 get in the way there (which would need investigating after all).

Another interesting behaviour I found - and it gave me a deja vu - when I pull the wake pin to VBAT the Photon wakes on FALLING and on RISING edge just the same.

1 Like

@ScruffR, it may be because of bounce on the pin causing both edge types.

@peekay123 @ScruffR

I have looked around the Community posts and this one seems to be the most recent regards System.sleep().

I would like to be able to set my photon into a deep sleep (lowest power consumption) with a restart on pressing of a button connected to D1. All key data is stored in EEPROM and recovered during setup().

The button is hardware debounced and pulled down to GND with a 10K ohm resistor like this:

I have tried the following in my code and whilst all of these calls put the photon (V0.4.9 firmware) to sleep - none of them will wakeup again; timed, interrupt button push. I have tried:

    System.sleep(30);

    System.sleep(SLEEP_MODE_DEEP,30);

    System.sleep(D1, RISING);   - CHANGE, FALLING don't do anything either

What is the story with System.sleep(), am I doing something wrong or is this just plain not working as per documentation? Thanks

The only way to wake from deep sleep via button is either via pulling WKP high (recommended) or just via the RST pulling low (technically not a wake tho’)

For wake on pin (stop mode, not deep sleep aka standby) you have to consider that FALLING or RISING will auto-attache internal pull resistors (aprox. 40k) to ensure opposit level with an open button.

So is System.sleep() working correctly or not. I have tried all of the 3 options and nothing appears to run setup() after the time period or on pressing the button D1.

Also, I am short on pins for PWM output and I am using WKP to control the LED on my display - could I also connect a button to this pin to be used to wake the device?

I have just seen your EDIT - I am currently sitting the loop() into a ‘sleeping’ state with an interrupt attached to button D1. This works well but I am trying to explore what other ways I could use to reduce the power consumption down lower than 45mW it is with wifi off and screen off currently. If I used a System.sleep(SLEEP_MODE_DEEP, 10) say and checked when it woke up if the button was pressed - then to wake the device I just need to press the button for at least 10 seconds. I seem to be missing something on the wake side - should there be a special code block?

I’d say for this proposed use

and if you go for WKP instead of D1 (as said in text) or D2 (as shown in image) the yes it works as intended.

SLEEP_MODE_DEEP is the only “sleep” mode that goes through setup() after wake.
And at some point this had already been documented accordingly, but there seems to be a regression in the docs about this point :flushed:.

You could multiplex the use of WKP, but in order to use it as a “good” wake-pin from deep sleep it’d be advisable to have an external pull-down, since deep sleep does not auto-attach them as stop mode would do.
So this needs to be taken in account for your LED control too.

 System.sleep(SLEEP_MODE_DEEP, 10);

Puts the device into deep sleep for up to 10 sec and then auto-wakes. To wake earlier, you pull WKP high for a split second (debounce is good but not required to wake tho’).

When it wakes, it just starts as if you pressed reset - so if you’re desperate you can scrap WKP and just use RST.

Back from lunch!

System.sleep() goes into to sleep but never comes out again. I need to press reset button to wake the device.

Sorry to labour this but I need to try and understand this better - when I call System.sleep(D2,CHANGE); say the main application thread stops there until D2 is pressed. Is that what you are saying? And the documentation is not clear on the difference between this and using SLEEP_MODE_DEEP which afterwards always starts with setup()?

I have just tried it and that works - so as I thought you had said System.sleep(D2, RISING); stops at the point the sleep call is made and waits for the interrupt signal. Another area where the documentation is not clear! I have an ammeter on the 12V power supply (I regulate this down to 5V to feed the photon) - using System.sleep() does not provide any advantage over what I was doing which is turn off the display and the wifi. Is this what you would expect?

System.sleep([timeout]) only turns WiFi off, code keeps running.
System.sleep(pin, edge [, timeout]) turns WiFi off, stops at the last instruction and continues from there after wake (should consume less current than above).
System.sleep(SLEEP_MODE_DEEP [, timeout]) puts the device in standby, deactivates internal 3.3V domain, keeps only retained RTC, SRAM and some registers powered and restarts from scratch on wake (lowest current consumption).

If the sleep modes don’t behave like that, I’m in doubt that your device has really been successfully updated to 0.4.9, or external circuitry interferes with it.

Try a simple test sketch that does nothing else and without any ext circuitry.

Then post your test code for us to test the same thing.

I tested deep sleep not long ago and it did exactly as expected, but the other sleep modes I can’t vouche for, since I’ve last tested them on 0.4.7.

System.sleep(SLEEP_MODE_DEEP, timeout) is waking after the timeout (judging by the current) but does not appear to be running setup() correctly - at least my display relies on the RST pin to start properly at power-on and that just isn’t happening. Further testing required :grin:

Thanks for the clear explanation.

1 Like

Showing your setup() and possible retained declarations might enable us to spot things, you might not be aware of (or not :blush:)

I have had a think about the System.sleep(SLEEP_MODE_DEEP) and the issue is definitely with the TFT display RESET control. Simple solution is to add a latching power on/off button. That way I can control the entry into deep sleep and getting out requires user toggling the power button. The rest is working.

Hi Team,

I am also facing a very weird behavior of System.sleep(WATER_SENSOR,FALLING ,90);

I have 2 condition

SYSTEM_MODE(MANUAL);
define WATER_SENSOR D0

// Spark setup
void setup()
{
                      pins_init(); 
                       water = 0;

}


loop()
{
     water = isExposedToWater();
     if(water) {
		Particle.publish("water_alarm", "on", 60, PRIVATE);
     } 
     else
    {
	Particle.publish("water_alarm", “off”, 60, PRIVATE);
    }
  	System.sleep(WATER_SENSOR,FALLING ,90);
}



// initialize our pins
void pins_init()
{
       // pinMode(LED, OUTPUT);
        pinMode(WATER_SENSOR, INPUT);
}


// determine if we're exposed to water or not
boolean isExposedToWater()
{
    if (digitalRead(WATER_SENSOR) == LOW) {
            return true;
    }
    else
    {
            return false;
    }
    
}

the very first time it is working and going to else condition and after that every time it is going to first condition i.e. water alarm even though the water is not touched.

We have no idea what kind of water sensor you are using, but if it is a sensor that has a floating state (when not triggered), then I’d suggest you use pinMode(WATER_SENSOR, INPUT_PULLUP)

BTW: This is simpler way to do just the same thing

boolean isExposedToWater()
{
  return !digitalRead(WATER_SENSOR);  // invert the reading while LOW == FALSE and HIGH evaluates to TRUE
}

@ScruffR, Thanks for reply. I am using the grove water sensor:
http://www.seeedstudio.com/wiki/Grove_-_Water_Sensor

It says that operating V is min 4.5 but it also work on 3.3v when the Photon is powered on all the time but in case of deep sleep it is not working correctly.

Thanks,
satyen