Browse Source

Update WIFI_NTP_CLOCK.ino

Lixie Labs 6 years ago
parent
commit
3769b29ea4
1 changed files with 183 additions and 57 deletions
  1. 183 57
      examples/ESP8266_ONLY/WIFI_NTP_CLOCK/WIFI_NTP_CLOCK.ino

+ 183 - 57
examples/ESP8266_ONLY/WIFI_NTP_CLOCK/WIFI_NTP_CLOCK.ino

@@ -11,51 +11,72 @@
 #include <ArduinoJson.h>         // https://github.com/bblanchon/ArduinoJson
 
 /*
- * Lixie II NTP Clock Example for ESP8266
- * by Connor Nishijima (November 2nd, 2019)
- * 
- * This example relies on an ESP8266/ESP32 controller,
- * which is used to pull UTC time from an NTP server over WiFi.
- * 
- * It requires two external buttons to fully function: (defined as HUE_BUTTON and HOUR_BUTTON below)
- * one for changing color/modes, and one for setting the UTC offset (timezone)
- * 
- * Upon booting, it will fail to connect to WiFi as it doesn't yet know your
- * credentials. It will then host it's own WiFi access point named "LIXIE CONFIG"
- * that you can connect your phone to.
- * 
- * Once connected, go to http://192.168.4.1 in your phone's browser, and you
- * will see a menu that will let you send the WiFi details down to the clock,
- * to be remembered from this point forward. (Even through power cycles!)
- * 
- * A short tap of the HUE button will change color modes, and holding it down will
- * start to cycle the displays through the color wheel. Release the HUE button
- * when it gets to a color you like.
- * 
- * A short tap of the HOUR button will increase the UTC offset by 1, (wrapping back
- * to -12 after +12) and a long tap toggles between 12 and 24-hour mode.
- * 
- * Holding the HOUR button down during power up will let you access the WiFi 
- * configuration page again.
- * 
- * MAKE SURE SPIFFS IS ENABLED in Tools > Flash Size
- * 
- * Enjoy!
- */
+   Lixie II NTP Clock for ESP8266
+   by Connor Nishijima (November 2nd, 2019)
+
+   This example relies on an ESP8266/ESP32 controller,
+   which is used to pull UTC time from an NTP server over WiFi.
+   
+   REQUIRED HARDWARE ---------------------------------------------------------------------
+
+   It requires two external buttons to fully function: (defined as HUE_BUTTON and HOUR_BUTTON below)
+   one for changing color/modes, and one for setting the UTC offset (timezone)
+
+   INSTRUCTIONS --------------------------------------------------------------------------
+
+   Upon booting, it will failt to connect to WiFi as it doesn't yet know your
+   credentials. It will then host it's own WiFi access point named "LIXIE CONFIG"
+   that you can connect your phone to.
+
+   Once connected, go to http://192.168.4.1/ in your phone's browser, and you
+   will see a menu that will let you send the WiFi details down to the clock,
+   to be remembered from this point forward. (Even through power cycles!)
+
+   A short tap of the HUE button will change color modes, and holding it down will
+   start to cycle the displays through the color wheel. Release the HUE button
+   when it gets to a color you like.
+
+   A short tap of the HOUR button will increase the UTC offset by 1, (wrapping back
+   to -12 after +12) and a long tap toggles between 12 and 24-hour mode.
+
+   Holding the HOUR button down during power up will erase WiFi credentials and let
+   you access the WiFi configuration page again.
+   
+   OPTIONAL HARDWARE ---------------------------------------------------------------------
+
+   - A piezo buzzer or small speaker between the BUZZER pin and GND
+   - Two SPST / SPDT switches from both the COLOR_CYCLE and NIGHT_DIMMING pins, that
+     optionally tie those pins to GND
+
+   The buzzer is just for feedback when buttons are pressed, and the two switches
+   enable automated color cycling on modes that support it (full cycle every 5 minutes)
+   and nighttime dimming to 40% brightness from 9PM (21:00) to 6AM (06:00)
+
+   If you don't have a buzzer or switches on-hand, just ignore the buzzer and
+   short the COLOR_CYCLE / NIGHT_DIMMING pins to GND if you want to enable those features.
+
+   MAKE SURE SPIFFS IS ENABLED in Tools > Flash Size
+
+   Enjoy!
+*/
 
 // USER SETTINGS //////////////////////////////////////////////////////////////////
-#define DATA_PIN        D7      // Lixie DIN connects to this pin
+#define DATA_PIN        D6      // Lixie DIN connects to this pin
 #define NUM_DIGITS      4
 
 #define SIX_DIGIT_CLOCK false   // 6 or 4-digit clock? (6 has seconds shown)
 
-#define HOUR_BUTTON     D1      // These are pulled up internally, and should be
-#define HUE_BUTTON      D3      // tied to GND through momentary switches
+#define HOUR_BUTTON     D7      // These are pulled up internally, and should be
+#define HUE_BUTTON      D2      // tied to GND through momentary switches
+
+#define BUZZER          D8      // OPTIONAL
+#define COLOR_CYCLE     D1      // OPTIONAL
+#define NIGHT_DIMMING   D5      // OPTIONAL
 ///////////////////////////////////////////////////////////////////////////////////
 
 Lixie_II lix(DATA_PIN, NUM_DIGITS);
 WiFiUDP ntp_UDP;
-NTPClient time_client(ntp_UDP, "pool.ntp.org", 3600, 900000); // Updates NTP sync every 15 minutes
+NTPClient time_client(ntp_UDP, "pool.ntp.org", 3600, 60000);
 #define SECONDS_PER_HOUR 3600
 bool time_found = false;
 
@@ -64,10 +85,11 @@ struct conf {
   uint8_t hour_12_mode = false;
   uint8_t base_hue = 0;
   uint8_t current_mode = 0;
-  
+
 };
 conf clock_config; // <- global configuration object
 
+float base_hue_f = 0;
 uint32_t settings_last_update = 0;
 bool settings_changed = false;
 const char* settings_file = "/settings.json";
@@ -78,6 +100,14 @@ uint8_t last_seconds = 0;
 #define STABLE 0
 #define RISE   1
 #define FALL   2
+
+uint8_t hh = 0;
+uint8_t mm = 0;
+uint8_t ss = 0;
+
+bool color_cycle_state   = HIGH;
+bool night_dimming_state = HIGH;
+
 bool hour_button_state   = HIGH;
 bool hue_button_state  = HIGH;
 bool hour_button_state_last   = HIGH;
@@ -143,7 +173,7 @@ void run_clock() {
 }
 
 void save_settings() {
-// Delete existing file, otherwise the configuration is appended to the file
+  // Delete existing file, otherwise the configuration is appended to the file
   SPIFFS.remove(settings_file);
 
   // Open file for writing
@@ -152,7 +182,7 @@ void save_settings() {
     Serial.println(F("Failed to create config file"));
     return;
   }
-  else{
+  else {
     Serial.println("Config file opened");
   }
 
@@ -169,7 +199,7 @@ void save_settings() {
   if (serializeJson(doc_out, file) == 0) {
     Serial.println(F("Failed to write to config file"));
   }
-  else{
+  else {
     Serial.println("Config Saved!");
   }
 
@@ -186,16 +216,17 @@ void load_settings() {
 
   // Deserialize the JSON document
   DeserializationError error = deserializeJson(doc_in, file);
-  if (error){
+  if (error) {
     Serial.println(F("Failed to read file, using default configuration"));
   }
-  else{
+  else {
     Serial.println("Config file opened");
     Serial.println("Config Loaded!");
   }
 
   // Copy values from the JsonDocument to the Config
   clock_config.base_hue = doc_in["base_hue"];
+  base_hue_f            = doc_in["base_hue"];
   clock_config.current_mode = doc_in["current_mode"];
   clock_config.time_zone_shift = doc_in["time_zone_shift"];
   clock_config.hour_12_mode = doc_in["hour_12_mode"];
@@ -205,10 +236,23 @@ void load_settings() {
 }
 
 void show_time() {
-  uint8_t hh = time_client.getHours();
-  uint8_t mm = time_client.getMinutes();
-  uint8_t ss = time_client.getSeconds();
+  hh = time_client.getHours();
+  mm = time_client.getMinutes();
+  ss = time_client.getSeconds();
 
+  if (hh < 6 || hh >= 21) { // Dim overnight from 9PM to 6AM (21:00 to 06:00)
+    if (night_dimming_state == HIGH) { // But only if dimming is enabled
+      lix.brightness(0.4);
+    }
+    else { // If not enabled, full brightness
+      lix.brightness(1.0);
+    }
+  }
+  else { // Or if not in the overnight time window, full brightness
+    lix.brightness(1.0);
+  }
+
+  // 12 hour format conversion
   if (clock_config.hour_12_mode == true) {
     if (hh > 12) {
       hh -= 12;
@@ -219,26 +263,34 @@ void show_time() {
   }
 
   uint32_t t_lixie = 1000000; // "1000000" is used to get zero-padding on hours digits
-  // This turns a time of 22:34:57 into the integer (1)223457, whose leftmost numeral will not be shown
+  // This turns a time of 22:34:57 into the integer (1)223457, whose leftmost numeral (1) will not be shown
   t_lixie += (hh * 10000);
   t_lixie += (mm * 100);
   t_lixie += ss;
 
   if (!SIX_DIGIT_CLOCK) {
-    t_lixie /= 100; // Eliminate second places
+    t_lixie /= 100; // Eliminate second places if using a 4 digit clock
   }
 
-  lix.write(t_lixie);
-  if (!time_found) {
+  lix.write(t_lixie); // Update numerals
+  
+  if (!time_found) { // Cues initial fade in
     time_found = true;
     lix.fade_in();
   }
-  Serial.println(t_lixie);
+
+  Serial.print("TIME: ");
+  Serial.println((hh * 10000)+(mm * 100)+ss);
 
   last_seconds = ss;
 }
 
 void color_for_mode() {
+  if (color_cycle_state == HIGH) {
+    base_hue_f += 0.017; // Fully cycles the color wheel every 5 minutes
+  }
+
+  clock_config.base_hue = base_hue_f;
   uint8_t temp_hue = clock_config.base_hue + hue_countdown;
 
   if (clock_config.current_mode == MODE_SOLID) {
@@ -281,6 +333,9 @@ void check_buttons() {
   hour_button_state   = digitalRead(HOUR_BUTTON);
   hue_button_state  = digitalRead(HUE_BUTTON);
 
+  color_cycle_state  = !digitalRead(COLOR_CYCLE);
+  night_dimming_state  = !digitalRead(NIGHT_DIMMING);
+
   if (hour_button_state > hour_button_state_last) {
     hour_button_edge = RISE;
   }
@@ -323,11 +378,18 @@ void parse_buttons() {
       Serial.println("UP");
       clock_config.time_zone_shift += 1;
 
-      if(clock_config.time_zone_shift >= 12){
+      if (clock_config.time_zone_shift >= 12) {
         clock_config.time_zone_shift = -12;
       }
-      
+
       time_client.setTimeOffset(clock_config.time_zone_shift * SECONDS_PER_HOUR);
+      hh = time_client.getHours();
+      if (hh == 0) {
+        beep(1000, 100);
+      }
+      else {
+        beep(2000, 100);
+      }
       show_time();
       update_settings();
     }
@@ -347,6 +409,10 @@ void parse_buttons() {
       clock_config.current_mode++;
       if (clock_config.current_mode >= NUM_MODES) {
         clock_config.current_mode = 0;
+        beep(1000, 100);
+      }
+      else {
+        beep(2000, 100);
       }
       hue_countdown = 127;
       update_settings();
@@ -356,9 +422,9 @@ void parse_buttons() {
   if (hue_button_state == LOW) { // CURRENTLY PRESSING
     uint16_t hue_button_duration = t_now - hue_button_start;
     if (hue_button_duration >= hue_push_wait) {
-      clock_config.base_hue++;
+      base_hue_f++;
       Serial.print("HUE: ");
-      Serial.println(clock_config.base_hue);
+      Serial.println(base_hue_f);
       update_settings();
     }
   }
@@ -368,6 +434,7 @@ void parse_buttons() {
     if (hour_button_duration >= hour_button_wait && hour_mode_started == false) {
       hour_mode_started = true;
       Serial.println("CHANGE HOUR MODE");
+      beep(4000, 250);
       clock_config.hour_12_mode = !clock_config.hour_12_mode;
       update_settings();
     }
@@ -386,15 +453,39 @@ void update_settings() {
   settings_last_update = t_now;
 }
 
+void enter_config_mode() {
+  lix.write(808080);
+  lix.color_all(ON, CRGB(64, 0, 255));
+  beep_dual(2000, 1000, 500);
+}
+
+void config_mode_callback (WiFiManager *myWiFiManager) {
+  enter_config_mode();
+  Serial.println("Entered config mode");
+  Serial.println(WiFi.softAPIP());
+  //if you used auto generated SSID, print it
+  Serial.println(myWiFiManager->getConfigPortalSSID());
+}
+
 void init_wifi() {
   WiFiManager wifiManager;
+  wifiManager.setAPCallback(config_mode_callback);
+  wifiManager.setTimeout(300); // Five minutes
+
   if (digitalRead(HOUR_BUTTON) == LOW) {
     wifiManager.resetSettings();
-    lix.write(808080);
-    lix.color_all(ON, CRGB(64,0,255));
+    enter_config_mode();
+  }
+  else {
+    beep(2000, 100);
+  }
+
+  while (!wifiManager.autoConnect("LIXIE CONFIG")) {
+    lix.sweep_color(CRGB(0, 255, 127), 20, 3, false);
+    lix.clear(); // Removes "8"s before fading in the time
   }
 
-  wifiManager.autoConnect("LIXIE CONFIG");
+  beep_dual(1000, 2000, 100);
   lix.sweep_color(CRGB(0, 255, 127), 20, 3, false);
   lix.clear(); // Removes "8"s before fading in the time
   color_for_mode();
@@ -416,8 +507,13 @@ void init_fs() {
 }
 
 void init_buttons() {
-  pinMode(HOUR_BUTTON,   INPUT_PULLUP);
+  pinMode(HOUR_BUTTON, INPUT_PULLUP);
   pinMode(HUE_BUTTON,  INPUT_PULLUP);
+
+  pinMode(BUZZER, OUTPUT);
+
+  pinMode(COLOR_CYCLE,  INPUT_PULLUP);
+  pinMode(NIGHT_DIMMING,  INPUT_PULLUP);
 }
 
 void init_displays() {
@@ -425,3 +521,33 @@ void init_displays() {
   lix.max_power(5, 1000);
   lix.write(888888);
 }
+
+void beep(uint16_t freq, uint16_t len) {
+  uint32_t period = (F_CPU / freq) / 2;
+  uint32_t cycle_ms = F_CPU / 1000;
+  uint32_t t_start = ESP.getCycleCount();
+  uint32_t last_flip = t_start;
+  uint32_t t_end = t_start + (len * cycle_ms);
+  uint32_t t_now = t_start;
+  bool state = LOW;
+  while (t_now < t_end) {
+    t_now = ESP.getCycleCount();
+    if (t_now - last_flip >= period) {
+      last_flip += period;
+      state = !state;
+
+      if (state) {
+        GPOS = (1 << BUZZER);
+      }
+      else {
+        GPOC = (1 << BUZZER);
+      }
+    }
+  }
+  digitalWrite(BUZZER, LOW);
+}
+
+void beep_dual(uint16_t del1, uint16_t del2, uint16_t len) {
+  beep(del1, len);
+  beep(del2, len);
+}