I've got a 4 year old who is supposed to stay in her room until a certain time when nap time is over, but not knowing how to tell time, asks over the monitor if it's time yet every minute or so. To try to remedy this, I'm wanting to take a WS2812B strip (~60 LEDs) with the following behavior:
All light up at a certain time
1 LED goes out each minute (Would take an hour, obviously)
Optional Once time's up (LEDs are all off), they flash or do something fun
So far, I've got the code (below) to light up all 60 initially using red, yellow, & green as desired. When it comes to how to make one turn off each minute + implement the timing feature, I'm stuck. I've found some various code online which seems to relate, but am not having luck with it. Using a NodeMCU so implemented which is getting the correct time, too.
Reading what I typed, I can see how that may look bad if that's what you're after, but isn't. She's only in there for 2 hours total and usually has to be woken up. If she comes out early, she awakens her 2 year old brother who is napping at the same time.
Yes, an analog might work; but why not make it something fun?
I choose NTP because I want it to start daily at 2:30pm CST. I've got some RTCs, but didn't want to use extra hardware. I choose a NodeMCU over Arduino because I'd like to eventually evolve it to where a custom timer could be started via our phones if needed or at least be able to flash OTA initially.
Can't answer your second one as that's part of the reason I posted. Not sure how to set the time then make LEDs follow suite. Did find this project (video / code) which is similar to perhaps test code from, but the timing method seemed confusing plus not exactly what I'm after.
That library you are using, in addition to .getFormattedTime(), has .getHours() and .getMinutes(). This may be all you need.
You can calculate the minutes since midnight as timeClient.getHours()*60+timeClient.getMinutes(). Then subtract that from 15*60+30 to calculate how many minutes nap time are remaining. Over 60 means it's not nap time yet. Zero/negative means nap time is over. Use remaining minutes of nap-time to determine how many LEDs should be lit.
Hi @bzowk
Test it out with this code.
It starts at 14:30 pm and counts from 59 to 0.
From 59 to 40 in red, from 40 to 20 in yellow and from 20 to 0 in green.
When finished he is shown a rainbow of colors.
The LED strip is connected to D1 (GPIO5).
Then say the result.
// by RV mineirn
#include <NTPClient.h>
#include <ESP8266WiFi.h>
#include <WiFiUdp.h>
// https://github.com/FastLED/FastLED/wiki/ESP8266-notes
#define FASTLED_ESP8266_RAW_PIN_ORDER // Require for FastLed on ESP8266 put before <FastLED.h>
#define FASTLED_ESP8266_NODEMCU_PIN_ORDER // Require for FastLed on ESP8266 put before <FastLED.h>
#define FASTLED_ESP8266_D1_PIN_ORDER // Require for FastLed on ESP8266 put before <FastLED.h>
#include <FastLED.h>
#define NUM_LEDS 60
#define DATA_PIN D1
#define COLOR_ORDER GRB
#define CHIPSET WS2812B
#define BRIGHTNESS 60
#define VOLTS 5
#define MAX_AMPS 500
const char *ssid = "XXXXXXXXX";
const char *password = "XXXXXXXXX";
const long utcOffsetInSeconds = -21600;
WiFiUDP ntpUDP;
NTPClient timeClient(ntpUDP, "pool.ntp.org", utcOffsetInSeconds);
CRGB leds[NUM_LEDS];
int minNTP = 0; // Each minute
int hourNTP = 0; // Each hour
int lastminNTP = 0; // Previus minute
int timePass = 0; // Set incitial time
bool countDown = false; // Controle countdown ou flash
uint8_t gHue = 0; // Rotating "base color"
//--------------------------------------------------------------------------
void setup() {
Serial.begin(115200); // Inicialize Serial
Serial.println("\n"); // New line
WiFi.begin(ssid, password); // Inicialize WIFI
while ( WiFi.status() != WL_CONNECTED ) { // If not connected try again
delay ( 500 ); // Delay
Serial.print ( "." ); // Print
}
timeClient.begin(); // Inicialize NCP time
FastLED.addLeds<CHIPSET, DATA_PIN, COLOR_ORDER>(leds, NUM_LEDS); // Add LEDS
FastLED.setMaxPowerInVoltsAndMilliamps (VOLTS, MAX_AMPS);
FastLED.setBrightness(BRIGHTNESS);
FastLED.clear();
for (int i = 0; i < 60; i++) { // Turn off all LEDs
leds[i] = CRGB::Black;
}
FastLED.show();
}
//--------------------------------------------------------------------------
void loop() {
String tempNTP; // Work variable
timeClient.update(); // Refres NTP time
tempNTP = timeClient.getFormattedTime().substring(0, 2); // Split hour from time
hourNTP = tempNTP.toInt(); // Transform in int
//Serial.print(hourNTP); Serial.print(" ");
tempNTP = timeClient.getFormattedTime().substring(3, 5); // Split minutes from time
minNTP = tempNTP.toInt(); // Transform in int
//Serial.println(minNTP);
if (countDown == true) // If countdown is allowed
{
tempNTP = timeClient.getFormattedTime().substring(3, 5); // Split minutes from time
minNTP = tempNTP.toInt(); // Transform in int
if (lastminNTP != minNTP) // If pass 1 minute
{
lastminNTP = minNTP; // Recharge control
//Serial.print(minNTP); Serial.print(" "); // Print minute
timePass--; // Countdown time
if (timePass < 0) // If time < 0
timePass = 0; // Time = 0
if (timePass == 0) // If time finish
countDown = false; // Disable time countdown
//Serial.println(timePass); // Print time pass
for (int i = 0; i < 60; i++) { // Turn off all LEDs
leds[i] = CRGB::Black;
}
if (timePass >= 41) // IF time > 41 minutes (Seconds)
{
for (int i = 0; i < timePass; i++) { // Turn LEDS RED until minutes
leds[i] = CRGB::Red;
}
}
if (timePass >= 21 and timePass < 41 ) // IF time > 21 minutes and < 41 (Seconds)
{
for (int i = 0; i < timePass; i++) { // Turn LEDS RED until Yellow
leds[i] = CRGB::Yellow;
}
}
if (timePass >= 0 and timePass < 21) // IF time > 0 minutes and < 21 (Seconds)
{
for (int i = 0; i < timePass; i++) { // Turn LEDS RED until green
leds[i] = CRGB::Green;
}
}
yield();
FastLED.show(); // Show LEDs
delay(100);
}
}
if (countDown == false) // If time ended show rainbow
{
if (hourNTP == 14 and minNTP == 30) // If is time to countdown
{
countDown = true; // Block bouncing
timePass = 59; // Charge countdown time
}
delay(200);
for (int i = 0; i < 60; i++) { // Show rainbow
fadeToBlackBy( leds, NUM_LEDS, 1);
leds[i] += CHSV( gHue++, 200, 180);
}
FastLED.show();
}
}