sandeepzgk
sandeepzgk

Reputation: 571

Light Sleep with GPIO Wakeup in ESP8266

I have been attempting to create a light sleep for ESP8266, in which I want to make the system sleep and trigger a wakeup on a GPIO input (Like a button press).

The code for it is pretty straight forward

#include <ESP8266WiFi.h> 
#include <Wire.h> 
#define PIN 5

extern "C"
{
  #include "gpio.h"
}

extern "C"
{
  #include "user_interface.h"
}


int wifi_connection_attempts;
const char * password = "PASSWORD";
const char * ssid = "SSID";
bool isAsleep = false;
void setup()
{
  Serial.begin(115200);
  delay(100);
  Serial.println("Setup!");
  wifi_fpm_set_sleep_type(LIGHT_SLEEP_T); // set sleep type, the above         posters wifi_set_sleep_type() didnt seem to work for me although it did let me     compile and upload with no errors 
  WiFi.mode(WIFI_STA);
  connect_to_wifi();
  gpio_pin_wakeup_enable(digitalPinToInterrupt(PIN), GPIO_PIN_INTR_ANYEDGE);
  gpio_intr_handler_register(wakeup, NULL);
  delay(5000);
  Serial.println("Going to Sleep!");
  sleep();
  delay(5000);
}

void connect_to_wifi()
{
  WiFi.begin(ssid, password);
  Serial.println("Connecting to WiFi..");
  while (WiFi.status() != WL_CONNECTED)
  {
    delay(500);
    Serial.print(".");
  }
  if (WiFi.status() == WL_CONNECTED)
  {
    Serial.println("Connected to the WiFi network");
  }
  wifi_fpm_set_sleep_type(LIGHT_SLEEP_T);
}

void sleep()
{
  Serial.println("Going to sleep");
  delay(1000);
  wifi_station_disconnect();
  Serial.println("WifiDisconnected");
  bool stopped;
  do {
    stopped = wifi_station_get_connect_status() == DHCP_STOPPED;
    if (!stopped)
    {
      Serial.println("dhcp not stopped?");
      delay(100);
    }
  } while (!stopped);
  Serial.println("---off...");
  wifi_set_opmode(NULL_MODE);
  wifi_set_sleep_type(MODEM_SLEEP_T);
  wifi_fpm_open();
  wifi_fpm_do_sleep(0xFFFFFFF);
}

void wakeup(uint32 interruptMask, void * arg)
{
  os_printf("Interrupted: %x\n", interruptMask);
  Serial.print("lastIntr:");
  Serial.println(system_get_time());
  gpio_intr_ack(interruptMask);
  Serial.println("Waking Up");
  wifi_fpm_do_wakeup();
  wifi_fpm_close();
  wifi_set_opmode(STATION_MODE);
  wifi_station_connect();
  Serial.println("Woke up!");
  delay(10000);
}

void loop()
{
  /* do whatever you want */
  Serial.println("Loop!");
  delay(5000);
}

Trust me when I say this, I have tried to read everything about how light sleep works, My references include https://blog.creations.de/?p=149 and https://github.com/esp8266/Arduino/issues/1381 none of the code seems to work for me. This piece of code I have written here is the nearest where I could get the power draw to a low of 8mA. I have been unsuccessful to get to Auto Light sleep as well with this code, which according to the documentation it should.

wifi_fpm_close(); 

This line strangely increases the power usage from 8mA to ~20mA (which is again by the documentation).

Questions

  1. How do I get to the elusive 1mA forced Light sleep
  2. No matter what I do to PIN 5, my system refuses to wake up. How would I write a callback handler for wakeup? or at least get the loop to run on GPIO 5 interrupt. (Awake interrupts work well, but when "sleeping" it doesn't.)

Am i doing something completely stupid in here?

Upvotes: 0

Views: 8309

Answers (1)

vaibhav sharma
vaibhav sharma

Reputation: 172

Your sleep code should be in loop() function. You can do it like this

#define WAKE_UP_PIN 4

void light_sleep(){
    wifi_fpm_set_sleep_type(LIGHT_SLEEP_T);
    wifi_fpm_open();
    gpio_pin_wakeup_enable(GPIO_ID_PIN(LIGHT_WAKE_PIN), GPIO_PIN_INTR_HILEVEL);
    wifi_fpm_do_sleep(0xFFFFFFF);
}

 void loop(){
   delay(200);
   light_sleep();
   delay(200);
   Serial.println("Wake Up Sid");
 }

I did it like this, I referred to the same github issue as mentioned by you and it worked for me

ThankYou

Upvotes: 1

Related Questions