How can I keep a circuit maintain its state when the arduino goes to sleep?

I’m using sleep to improve battery life. It does it’s business in setup() and then sleeps for 10 seconds. My project opens/closes a circuit when it is awake. It queries a page for a value and depending upon that value. However when the arduino goes to sleep, the circuit will open. I want the circuit to maintain its state, be it open or closed when the sleep occurs.

Note, the sleep basically shuts down the arduino for 10 seconds and when it starts it runs through setup() again.

From browsing I think I need a latching switch. Is that correct? Can you suggest one or a different solution?

With 59 posts I would have expected that you knew to include more detail for a good answer. What is this circuit you want holding?

Yes a mechanical relay latch would work, but the extra current it takes might not end up saving you anything over the sleep system, especially with such a short sleep time.

From your post, I assume that your circuit is somehow powering the Arduino off? You say the work is done in Setup and that Setup runs again after waking up. That is unusual. If this is what is Happening, the Arduino is not going to "sleep" it is being completely powered off! If that is the case, the only way to save state would be to write it to nonvolatile Memory before turning the chip off and reading the nonvolatile Memory on wakeup.

Grump is of course right, all we're doing is guessing without at least Basic details.

Most of the various sleep states will leave the digital outputs in the state you assigned them. You can shut down the analog subsystem, various timers and other elements but the digital outputs are usually the very last to change.

How do you sleep for 10 seconds? Show your code. Usually the deepest sleep requires the watchdog timer to wake it up and 8 seconds is the longest period possible with the watchdog.

Grumpy_Mike:
With 59 posts I would have expected that you knew to include more detail for a good answer.
What is this circuit you want holding?

Yes a mechanical relay latch would work, but the extra current it takes might not end up saving you anything over the sleep system, especially with such a short sleep time.

Grumpy_Mike:
With 59 posts I would have expected that you knew to include more detail for a good answer.
What is this circuit you want holding?

Yes a mechanical relay latch would work, but the extra current it takes might not end up saving you anything over the sleep system, especially with such a short sleep time.

Fair point. Here’s a sketch. Note that I’m using a nodemcu.

I timed this running. From setup to sleep it takes 1.38 seconds to run. So that makes the time the ESP is running (and using power) to be about 12% of the time. Should be a significant increase in battery life. When executeRequest(1) is called, the switch is supposed to be closed, and stay closed until executeRequest(2) is called. How much power does a latching switch require?

//using a nodemcu and based on https://openhomeautomation.net/esp8266-battery/

//#define DEBUG

// Library
#include <Arduino.h>
#include <ESP8266WiFi.h>
#include <ESP8266WiFiMulti.h>
#include <ESP8266HTTPClient.h>
#include <Regexp.h>

//------------------------------------- user specific configuration -------------------------------------
// WiFi settings
const char* ssid = "XXX";
const char* wifiPassword = "XXX";

// ISY settings
const char* rest_user = "XXX";
const char* rest_password = "XXX";
//------------------------------------- user specific configuration -------------------------------------

// Time to sleep (in seconds):
const int sleepTimeS = 10;

ESP8266WiFiMulti WiFiMulti;


bool executeRequest(int command) {
  Serial.print("Command:");
  if (command == 1) {
    Serial.println("on not yet implemented");
  }
  else if (command == 2) {
    Serial.println("off not yet implemented");
  }
  else {
    Serial.println("invalid command");
  }
}

// RestAPI commands
const char* rest_getStatus = "http://172.16.0.40/rest/vars/get/1/12";
const char* rest_clearStatus = "http://172.16.0.40/rest/vars/set/1/12/0";
String callRest(String restCmd) {

  String payload = "";

  if ((WiFiMulti.run() == WL_CONNECTED)) {
    HTTPClient http;
    http.begin(restCmd);
    http.addHeader("Content-Type", "application/json");
    http.setAuthorization(rest_user, rest_password);
    int httpCode = http.GET();

    // httpCode will be negative on error
    if (httpCode > 0) {
      // HTTP header has been send and Server response header has been handled
      if (httpCode == HTTP_CODE_OK) {
        payload = http.getString();
      }
    }
    http.end();
    return payload;
  }
}

int find_text(String needle, String haystack) {
  int foundpos = -1;
  for (int i = 0; i <= haystack.length() - needle.length(); i++) {
    if (haystack.substring(i, needle.length() + i) == needle) {
      foundpos = i;
    }
  }
  return foundpos;
}

int getValue(String str) {
  int valOpen = find_text("<val>", str);
  str = str.substring(valOpen + 5);
  int valClose = find_text("</val>", str);
  str = str.substring(0, valClose);
  int cmd = str.toInt();
  return cmd;
}

unsigned long setupStart = 0;
unsigned long setupEnd = 0;

void setup()
{

  Serial.println();
  Serial.println();
  Serial.println();
#ifdef DEBUG
  setupStart = 0;
#endif

  // Serial
  Serial.begin(115200);

  // Connect to WiFi
  WiFi.begin(ssid, wifiPassword);
  while (WiFi.status() != WL_CONNECTED) {
    delay(100);
  }
  //Serial.println(WiFi.localIP());

  WiFiMulti.addAP(ssid, wifiPassword);

#ifdef DEBUG
  Serial.println("Setup time:" + String(millis() - setupStart));
#endif
}

void loop()
{
#ifdef DEBUG
  unsigned long loopStart = millis();
#endif
  int cmd = getValue(callRest(rest_getStatus));
  callRest(rest_clearStatus);
  if (cmd >= 1 and cmd <= 2)
    executeRequest(cmd);

#ifdef DEBUG
  Serial.println("Loop time:" + String(millis() - loopStart));
#endif

  Serial.println();
  Serial.println();
  Serial.println();
  Serial.println("Total:" + String(millis() / 1000.0f));

  // Sleep
#ifdef DEBUG
  Serial.println("ESP8266 in sleep mode");
#endif
  Serial.println();
  Serial.println();
  Serial.println();
  ESP.deepSleep(sleepTimeS * 1000000);
}

How much power does a latching switch require?

It takes nothing to hold, it is mechanical. However it is a relay that requires a pulse of current to change, exactly how much depends on the actual device.

Note that I'm using a nodemcu.

Would have been good to know that from the start, a lot of the above answers assumed a Uno. Sorry but I don't know much about the sleep habits of that chip.

The other alternitave is you could use an external flip flop chip to hold an output during sleep.A CMOS chip would not take up much current.