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

@ScruffR,

I tried pinMode(WATER_SENSOR, INPUT_PULLUP) but it did not help. I am not sure what is causing this not to work. When I reset the device it works fine for the first time but after that it goes back again to water_alarm which is not true.

Thanks,
Satyen

Are you letting the device wake with timeout or via interrupt?
I’ll have a test.

@ScruffR – Timeout. I just put 90 seconds for testing purpose.

@ScruffR – Hi Scruff ! I even bought a new water sensor which supports 3.3 V but I got the same result. I also want to try the retained variable but I do not like the idea of saving the values here.

Thanks,
Satyen

What do you mean with that?

AND these Particle.publish() instructions are unlikely to work with your code due to SYSTEM_MODE(MANUAL) (and several other errors)


This code works however for my Photon

const char evtName[] = "scruffy_test";

//--SYSTEM_MODE(MANUAL);
#define WATER_SENSOR D0

// Spark setup
void setup()
{
  pins_init(); 
}

void loop()
{
  int water = isExposedToWater();
  Particle.publish(evtName, water ? "on" : "off", PRIVATE);
  delay(5000);
  System.sleep(WATER_SENSOR, FALLING, 30);
}

// initialize our pins
void pins_init()
{
  pinMode(WATER_SENSOR, INPUT_PULLUP);
}

// determine if we're exposed to water or not
boolean isExposedToWater()
{
  return !digitalRead(WATER_SENSOR);
}

Attention:
This code works but depending on your system firmware you might encounter this issue
https://github.com/spark/firmware/issues/1008

@ScruffR !

Thanks for reply and providing the solution. But I have an another problem when I attach the SPARK FUN BATTERY Shield.

When i attach the shield the code does not work. It always says that water alarm is On. I read that Sparkfun Battery shield is a problem here.

I need your help !

Here is the picture:

here is my code:

#include "SparkFunMAX17043/SparkFunMAX17043.h"
#include "application.h"
STARTUP(WiFi.selectAntenna(ANT_AUTO));
#define lowBattery 10       
#define WATER_SENSOR D0

double voltage = 0;
double soc = 0;
bool alert;
String data = ""; //used for all publish statements
const char evtName[] = "scruffy_test";

void setup()
{
        pins_init();
  	lipo.begin(); // Initialize the MAX17043 LiPo fuel gauge
        lipo.quickStart();
        lipo.setThreshold(10); // Set alert threshold to 10%.                                
}

void loop()
    {
             int water = isExposedToWater();
            Particle.publish(evtName, water ? "on" : "off", PRIVATE);
            delay(1000);
	    voltage = lipo.getVoltage();
	    soc = lipo.getSOC();
	    alert = lipo.getAlert()
	    lipo.begin(); 
            lipo.wake();
            lipo.quickStart();
            lipo.setThreshold(lowBattery); 
        
        if (lipo.getAlert()) Particle.publish("Low Battery", NULL, 60, PRIVATE);    

        Particle.publish("Status", data.format("Battery %1.2fV %2.1f%% Signal: %ddB" ,      lipo.getVoltage(), lipo.getSOC(), WiFi.RSSI()), 60, PRIVATE);
    
       System.sleep(WATER_SENSOR, FALLING, 30);
}

void pins_init()
{
  pinMode(WATER_SENSOR, INPUT_PULLUP);
}

// determine if we're exposed to water or not
boolean isExposedToWater()
{
  return !digitalRead(WATER_SENSOR);
}

Thanks,
Satyen

You should not use D0 since the shield uses I2C to talk to the FuelGauge and this interface occupies D0/D1 already.

I’d also not use ANT_AUTO when you know which antenna you’ll actually be using, since the searching might put extra time on connect.

@ScruffR:- Thanks ! Let me use D2 then give it a try now. Thanks for quick response.

@ScruffR, I used D2 ping but still the same result. It says , the water is “On”. I also removed the code for ANT_Auto.

WiFi.selectAntenna() is a "sticky" setting. You'd only set it once and it'll stay set even when you remove the instruction.
In order to set a specific antenna, you'd need to select that one explicitly at least once.

About your other issue, could you try calling pins_init() again after the sleep call?

@ScruffR, Thanks ! It is working now. I am also working on electron for GPS module and I would like to apply the same sleep function over there. Though electron has its own battery gauge , these fundamentals will over there too.

Thanks alot !

Satyen

Yes, this should work pretty much the same on Electron (minus any WiFi.xxxx calls of course).

Only one thing needs extra attention.
In order to safe on data usage do this

    #if (PLATFORM_ID == PLATFORM_ELECTRON_PRODUCTION)
       System.sleep(WATER_SENSOR, FALLING, 30, SLEEP_NETWORK_STANDBY);
    #else
       System.sleep(WATER_SENSOR, FALLING, 30);
    #endif

(you could forget the #if ... #endif since that extra parameter will be ignored on WiFi devices, but just to show-off :sunglasses:)
This avoids the need to always introduce yourself to the cell tower after wake-up which might use a few KB per wake.

@ScruffR, Thanks for advice. I have another question here:
Is there any way that we can find out whether the photon wakes up through button clicked or through time interval is up for sleep.

System.sleep(Button, FALLING, 30);

When i click the button (D2=HIGH, I am using D2 pin for wakeup) , it wakes up the photon but after that D2=LOW. Is there any way to capture or maintain D2=HIGH.

Thanks,
Satyen

This question has been asked before, and the usual answers are, you either need to build a sample and hold circuit to keep the button state long enough to read it via your code, or you store away the current time before you go to sleep and then check the time after wake. If you are far enough away from your timeout you know it was a button press, if not it could be either reason.

@ScruffR, Thanks !

Hah, I’m just catching up on this. In the initial question about going super deep sleep on the Button: yes, the WKP is already committed… to the interrupt pin for the accelerometer! So you can turn the micro off completely and let the crazy low power ADXL362 wake it up when it’s bumped or tapped above a threshold. I’m pretty sure it’ll actually pick up the button click but via acceleration rather than direct 'lectrons.

@ScruffR: Hi ! Thanks for helping me on this ! I have another Question regarding this topic.
I wanted to have 3 buttons in deep sleep mode for my device.

1st Button: Wake up the device which can be pressed on demand by users.

2nd Button: Device Set which can be pressed for 1st time by OR when the user will move the device to other wifi location.

3rd Button: reset the Devices

for 1) I have the solution and it is working fine.
for 2) I saw your solution in this link ( Photon won't enter listening mode while connecting to wifi (works using setup button but not using external button) )
for 3) to build a circuit to keep the button state long enough to read it via my code ( you idea above )

I wanted to check what do you think about that before I proceed for 2) and 3).

Thanks,
Satyen

I would actually use interrupts for 2 & 3.
This way your application code does not need to take any care for reading the buttons often enough in order to not miss a button press.

But both actions will not be able to wake the device or do their jobs while the device is asleep.

1 Like