The use of the ESP8266 in the world of IoT

User avatar
By LordLeicester
#51599 Hey guys :-)

I'm building my first IoT Project and would like a bit of advice on the Light Sleep mode on the esp8266.

I'm trying to build a smart hamster wheel that tracks the distance the hamster is running every night. A reed switch will act as a sensor for "finished" rounds of the wheel, the esp8266 will send the data to a server. The whole system will be powered by a 2000mAh 3.7V Lipo battery and should run for several days / weeks before needing to be recharged. I'm currently programming the esp with the arduino ide.

Hamsterwheel.png


The Light Sleep mode would be perfect for the project, as the power consumption is low, but I can still store data on the board.
As it would be very inefficient to send every single round to the server, I want to accumulate rounds over a fixed period of time, say 1 minute, and then send the number of rounds over wifi.

There are now three problems with this approach:
  • Light Sleep doesn't seem to respect the duration given for sleeping
  • Is a combination of timed sleep and interrupt possible?

So, to the first problem...
I looked very thoroughly into the following post.

I made a sketch that successfully uses light sleep, registers an interrupt for the reed switch and counts the number of finished rounds.
What I was not able to do was to have the esp light sleep for a specified amount of time and then execute code.

I'm looking at this piece of code:
Code: Select allvoid loop()
{
    Serial.println("Did something, go back to sleep...");

    wifi_fpm_set_sleep_type(LIGHT_SLEEP_T);
    gpio_pin_wakeup_enable(GPIO_ID_PIN(5), GPIO_PIN_INTR_HILEVEL);
    wifi_fpm_open(); // Enables force sleep
    wifi_fpm_do_sleep(0xFFFFFFF); // Sleep for longest possible time
    delay(100);
 }


This makes the esp light sleep until the reed switch is closed, then prints the output to the console.

Now, if I alter the code to sleep for 10 seconds...

Code: Select allvoid loop()
{
    Serial.println("Did something, go back to sleep...");

    wifi_fpm_set_sleep_type(LIGHT_SLEEP_T);
    gpio_pin_wakeup_enable(GPIO_ID_PIN(5), GPIO_PIN_INTR_HILEVEL);
    wifi_fpm_open(); // Enables force sleep
    wifi_fpm_do_sleep(0x0989680); // Sleep for ~10 seconds
    delay(100);
 }


... the esp is not going into light sleep and is instead printing the output to the console every 100ms (as set by the delay). I tried other values as well, as not giving the value in hex but in dec. No given value had any effect on the time spent sleeping, except the maximum time.

What am I doing wrong here?

The second problem is as tricky as the first...
There is a way to register wake up callbacks for light sleep, see the code below from here.

Code: Select allvoid user_func(...)

   wifi_station_disconnect();
   wifi_set_opmode(NULL_MODE);         // set WiFi mode to null mode.
   wifi_fpm_set_sleep_type(LIGHT_SLEEP_T); // light sleep
   wifi_fpm_open();               // enable force sleep
   wifi_fpm_set_wakeup_cb(fpm_wakup_cb_func1); // Set wakeup callback
   wifi_fpm_do_sleep(50*1000);     
}


Now my idea is to combine a light sleep with duration and an interrupt.

Code: Select all<pseudocode>
void loop() {
  if (enough_data_available()) {
    post_data_to_server();
  }

  light_sleep_for(1 minute);
}

void light_sleep_for(duration) {
    wifi_fpm_set_sleep_type(LIGHT_SLEEP_T);
    wifi_fpm_open();
    gpio_pin_wakeup_enable(5, GPIO_PIN_INTR_HILEVEL);
    wifi_fpm_set_wakeup_cb(wakeCB);
    wifi_fpm_do_sleep(duration);
    delay(100);
    if (sleep_time_left > 0) {
      light_sleep_for(sleep_time_left);
    }
}

void wakeCB() {
  data_available ++;
  sleep_time_left = (sleep_start + sleep_duration) - millis();
}
</pseudocode>


As I wasn't able to make the esp sleep for a specified amount of time, I couldn't try out a similiar code. Trying to set a wake up callback without the timer didn't work either.

The question is: Would this be possible at all? Or just super inefficient use of processing power? What would be an alternative?


Many thanks for any help from you, I really appreciate it :)


Appendix:
  • The used esp is the Adafruit HUZZAH ESP8266
  • Deep sleep is not an option, as I then cannot keep track of the rounds finished by the wheel
  • I'm using version 1.6.9 of the Arduino IDE and version 2.3.0 of the esp8266 package
  • Making the whole setup wired to a power outlet is also not an option
You do not have the required permissions to view the files attached to this post.