You are currently viewing Automatic wakeup light with ESP 32

Automatic wakeup light with ESP 32

Send the commands

*WIRING SCHEMATIC*

NOTE:

Install the modified IRremote library when you are using an ESP32!

You will need this to be able to send IR commands (see above)

You can now try out if you commands work. In order to do this you need to hook up the LED strip with its receiver and power supply and upload something simmilar to this test code below to your ESP32. You just need to edit the Hex values in the “irsend.sendNEC(YOUR_HEX_VALUE, 32);” lines.

The code below just loops through the IR commands with a 3 second delay in between each other.

If this works as expected we could go to the last step and teach the ESP32 how to handle times.

#include <IRremote.h>

IRsend irsend;

void setup()
{
}

void loop() {
  delay(3000);
  irsend.sendNEC(0xFF6897, 32); // LED ON

  delay(3000);
  irsend.sendNEC(0xFFE817, 32); // LED 25% brightness

  delay(3000);
  irsend.sendNEC(0xFF08F7, 32); // LED 50% brightness

  delay(3000);
  irsend.sendNEC(0xFF8877, 32); // LED 75% brightness

  delay(3000);
  irsend.sendNEC(0xFF48B7, 32); // LED 100% brightness

  delay(3000);
  irsend.sendNEC(0xFFC837, 32); // LED OFF
}

Add NTP Time handling to the ESP32

For the ESP to get times we need to set up a wifi connection and let it get the current time by timezone from NTP (Network Time Protocol) servers. With that time we can determine when the LED Strip should light up in which brightness and when to switch it off again. See code below.

You need to add your Wifi SSID an Password in lines 9 & 10. Also in order to have the correc timezone you need to go to that site and get your timezone code https://remotemonitoringsystems.ca/time-zone-abbreviations.php and set the correc “TZ_INFO” in line 17.

Lines 29 – 33 are the times hours and minutes when the commands should be triggered. I set it for example to switch on at 7:00 at 25% brightness and increase the brightness every 15 minutes by 25% until it reaches the max. Then at 8:00 the lights are switched off again.

One note on the NTP times. They are a bit weird as month go from 0 to 11 and weekdays go from 0 to 6 where sunday is 0.

I know the code is far from pretty but it works ¯\_(ツ)_/¯

Things that could be added are:

  • a physical button to switch on/off the LEDs
  • better Day handling to only switch on at certain days
  • small web interface to change wakeup times
//IR
#include <IRremote.h>

//NTP https://github.com/SensorsIot/NTP-time-for-ESP8266-and-ESP32/blob/master/NTP_Example/NTP_Example.ino
#include <WiFi.h>
#include <time.h>

//Wifi
const char* ssid = "YOUR_WIFI_SSID";
const char* password = "YOUR_WIFI_PASSWORD";

//IR
IRsend irsend;

//NTP
const char* NTP_SERVER = "de.pool.ntp.org";
const char* TZ_INFO    = "CET-1CEST,M3.5.0,M10.5.0/3";  // enter your time zone (https://remotemonitoringsystems.ca/time-zone-abbreviations.php)

tm timeinfo;
time_t now;
long unsigned lastNTPtime;
unsigned long lastEntryTime;


//clock
int current_hour;
int current_minute;

int wake_hour = 7;
int off_hour = 8;
int wake_min_1 = 15;
int wake_min_2 = 30;
int wake_min_3 = 45;

bool light_on = false;
bool trigger_1 = false;
bool trigger_2 = false;
bool trigger_3 = false;

void setup() {
  Serial.begin(115200);
  WiFi.begin(ssid, password);

  int counter = 0;
  while (WiFi.status() != WL_CONNECTED) {
    delay(200);
    if (++counter > 100) ESP.restart();
    Serial.print ( "." );
  }
  Serial.println("\n\nWiFi connected\n\n");

  configTime(0, 0, NTP_SERVER);
  // See https://github.com/nayarsystems/posix_tz_db/blob/master/zones.csv for Timezone codes for your region
  setenv("TZ", TZ_INFO, 1);

  if (getNTPtime(10)) {  // wait up to 10sec to sync
  } 
  else {
    Serial.println("Time not set");
    ESP.restart();
  }
  showTime(timeinfo);
  lastNTPtime = time(&now);
  lastEntryTime = millis();
}

void loop() {

  getNTPtime(10);
//  showTime(timeinfo);

  current_hour = timeinfo.tm_hour;
  current_minute = timeinfo.tm_min;

  if (light_on == false && current_hour == wake_hour){      
      light_on_func();
      irsend.sendNEC(0xFF08F7, 32); //25
      Serial.println("25 %");
  }

  if (current_hour == off_hour){
    irsend.sendNEC(0xFF6897, 32); //Off
    Serial.println("Off");
  }
  if (trigger_1 == false && current_hour == wake_hour && current_minute == wake_min_1){
    light_on_func();
    irsend.sendNEC(0xFF8877, 32); //50
    trigger_1 = true;
    Serial.println("50 %");
  }
  else if (trigger_2 == false && current_hour == wake_hour && current_minute == wake_min_2) {
    light_on_func();
    irsend.sendNEC(0xFF48B7, 32); //75
    trigger_2 = true;
    Serial.println("75 %");
  }
  else if (trigger_3 == false && current_hour == wake_hour && current_minute == wake_min_3) {
    light_on_func();
    irsend.sendNEC(0xFFC837, 32); //100
    trigger_3 = true;
    Serial.println("100 %");
  }

  if (light_on == true && current_hour != wake_hour){

    light_on = false;
    trigger_1 = false;
    trigger_2 = false;
    trigger_3 = false;
  }
  
  delay(60000); //check every 1 Minute

}

void light_on_func(){
  irsend.sendNEC(0xFFE817, 32); //On
  Serial.println("On");
  light_on = true;
}

bool getNTPtime(int sec) {

  {
    uint32_t start = millis();
    do {
      time(&now);
      localtime_r(&now, &timeinfo);
      Serial.print(".");
      delay(10);
    } while (((millis() - start) <= (1000 * sec)) && (timeinfo.tm_year < (2016 - 1900)));
    if (timeinfo.tm_year <= (2016 - 1900)) return false;  // the NTP call was not successful
    Serial.print("now ");  Serial.println(now);
    char time_output[30];
    strftime(time_output, 30, "%a  %d-%m-%y %T", localtime(&now));
    Serial.println(time_output);
    Serial.println();
  }
  return true;
}

//this is just needed to print the times in the serial monitor
void showTime(tm localTime) {
  Serial.print(localTime.tm_mday);
  Serial.print('/');
  Serial.print(localTime.tm_mon + 1);
  Serial.print('/');
  Serial.print(localTime.tm_year - 100);
  Serial.print('-');
  Serial.print(localTime.tm_hour);
  Serial.print(':');
  Serial.print(localTime.tm_min);
  Serial.print(':');
  Serial.print(localTime.tm_sec);
  Serial.print(" Day of Week ");
  if (localTime.tm_wday == 0)   Serial.println(7);
  else Serial.println(localTime.tm_wday);
}