Flower Box
.png)


I made this project as a valentines gift. It shows time, and messages at a specified time and date. Also, an RGB button can be pressed to light up the acrylic. I've 3D printed the case using black and clear PLA filament.
Here's the materials I used:
Supplies
-
NodeMCU V3 ESP8266 ESP-12E
-
Digital Capacitive Touch Switch Module TTP223B
-
Grove – RGB LED Stick (10 – WS2813 Mini)
-
5V Relay Module SPDT
-
7 segment display 4 digit LED module TM1637
Hardware
.png)






See the pictures for the schematic and the hardware I used. Here's the components:
- NodeMCU WiFi Board
- Any ESP8266 board can be used. i used this since its what i have.
- Digital Capacitive Touch Switch Module TTP223B
- To use a switch to turn on the lights
- Grove – RGB LED Stick (10 – WS2813 Mini)
- Light up the acrylic
- 5V Relay Module SPDT
- To turn on the lights
- 7 segment display 4 digit LED module TM1637
- Show the time
Connection to NodeMCU
- 7 segment display 4 digit LED module TM1637 CLK → 12
- 7 segment display 4 digit LED module TM1637 D10 → 14
- 7 segment display 4 digit LED module TM1637 VIN → 5V
- 7 segment display 4 digit LED module TM1637 GND → GND
- Grove – RGB LED Stick GND → GND
-
Grove – RGB LED Stick VIN → 5V
-
Grove – RGB LED Stick SIG → 4
-
5V Relay Module GND → GND
-
5V Relay Module VIN → 5V
-
5V Relay Module IN → 5
-
5V Relay Module Common → 5V
-
5V Relay Module Normally Close → Flower
- Flower other wire → GND
- Capacitive Touch Switch VIN → 5V
- Capacitive Touch Switch GND → GND
- Capacitive Touch Switch SIG → 13
Arduino Code

Add the following libraries to your Arduino IDE:
Here's the code I used with commented explanation. Copy this to your arduino IDE, upload and light it up!
//Varaibles to change /*Get offset from <a href="https://en.wikipedia.org/wiki/List_of_UTC_time_offsets"> https://en.wikipedia.org/wiki/List_of_UTC_time_of...</a> ex: For UTC -5.00 : -5 * 60 * 60 : -18000 */ const long utcOffset = 28800; int specialDay=16; int specialMonth = 2; String monthlyMessage = "lets dance to foreber"; String yearlyMessage = "its been a happy year"; //Wifi Credentials #ifndef STASSID #define STASSID "PutYourWifiSSIDHere" #define STAPSK "PutYourWifiPassHere" #endif //Libraries to use the RGB LED Stick #include <Adafruit_NeoPixel.h> #ifdef __AVR__ #include <avr/power.h> // Required for 16 MHz Adafruit Trinket #endif #define LED_PIN 4 //Pin the RGB LED Stick is connected #define NUMPIXELS 10 //Numbers of NeoPixels are attached to the module Adafruit_NeoPixel pixels(NUMPIXELS, LED_PIN, NEO_GRB + NEO_KHZ800);// Declare our NeoPixel strip object: //Libraries to use the 7 Segment display #include <TM1637Display.h> const int CLK = 12; //Set the CLK pin connection to the display const int DIO = 14; //Set the DIO pin connection to the display TM1637Display display(CLK, DIO); //set up the 4-Digit Display. //Pin connections const int buttonPin = 13; //pin connected to the switch const int ledPin = 5; //pin connected to the relay //Other Varaibles int numCounter = 0; int buttonState = 0; // variable for reading the switch status unsigned long previousMillis = 0;// will store last time LED was updated unsigned long previousMillis1 = 0; const long interval = 40000; int pressed; String curr_min; String prev_min; //Libraries to use the Wifi #include <ESP8266WiFi.h> #include <WiFiUdp.h> const char* ssid = STASSID; const char* password = STAPSK; //Libraries to get time from the internet #include <NTPClient.h> //UTC Time const long utcOffsetInSeconds = utcOffset; char daysOfTheWeek[7][12] = {"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"}; WiFiUDP ntpUDP; // Define NTP Client to get time NTPClient timeClient(ntpUDP, "pool.ntp.org", utcOffsetInSeconds); //To set Wifi Manager #include <DNSServer.h> #include <ESP8266WebServer.h> #include <WiFiManager.h> void setup() { WiFiManager wifiManager; wifiManager.autoConnect("Love Watch"); timeClient.begin(); pinMode(ledPin, OUTPUT); pinMode(buttonPin, INPUT); display.setBrightness(0x0a); //set the diplay to maximum brightness pixels.begin(); pixels.clear(); digitalWrite(ledPin, HIGH); Serial.begin(9600); timeClient.update(); String curr_min = String(timeClient.getMinutes()); if ( curr_min.toInt() < 10) { curr_min = "0" + curr_min; } String curr_time = String(timeClient.getHours()) + curr_min; display.showNumberDecEx(curr_time.toInt(), 0b11100000, false, 4, 0); } //letters aside from k,m,q,v,w,x to print text on the 7 segment display const uint8_t a = 0x77 ; const uint8_t b = 0x7c ; const uint8_t c = 0x39 ; const uint8_t d = 0x5e ; const uint8_t e = 0x79 ; const uint8_t f = 0x71 ; const uint8_t g = 0x6f ; const uint8_t h = 0x76 ; const uint8_t _i = 0x6 ; const uint8_t j = 0xe ; const uint8_t l = 0x38 ; const uint8_t n = 0x37 ; const uint8_t o = 0x5c ; const uint8_t p = 0x73 ; const uint8_t r = 0x50 ; const uint8_t s = 0x6d ; const uint8_t t = 0x31 ; const uint8_t u = 0x3e ; const uint8_t y = 0x6e ; const uint8_t z = 0x5b ; uint8_t _char = 0; const uint8_t blank = 0x00; void send_message(String message) { if (_char > message.length()) { _char = 0; } uint8_t segment; uint8_t _display [3]; for (int i = 0; i < 4; i++) { switch (message.charAt(_char + i)) { case 'a': _display[i] = a; break; case 'b': _display[i] = b; break; case 'c': _display[i] = c; break; case 'd': _display[i] = d; break; case 'e': _display[i] = e; break; case 'f': _display[i] = f; break; case 'g': _display[i] = g; break; case 'h': _display[i] = h; break; case 'i': _display[i] = _i; break; case 'j': _display[i] = j; break; case 'l': _display[i] = l; break; case 'n': _display[i] = n; break; case 'o': _display[i] = o; break; case 'p': _display[i] = p; break; case 'r': _display[i] = r; break; case 's': _display[i] = s; break; case 't': _display[i] = t; break; case 'u': _display[i] = u; break; case 'y': _display[i] = y; break; case 'z': _display[i] = z; break; default: _display[i] = blank; break; } } display.setSegments(_display); _char ++; } void loop() { unsigned long currentMillis = millis(); timeClient.update(); curr_min = timeClient.getMinutes(); if ( curr_min.toInt() < 10) { curr_min = "0" + curr_min; } String curr_time = String(timeClient.getHours()) + curr_min; unsigned long epochTime = timeClient.getEpochTime(); struct tm *ptm = gmtime ((time_t *)&epochTime); int monthDay = ptm->tm_mday; int currentMonth = ptm->tm_mon + 1; if ( curr_min != prev_min) { prev_min = curr_min; Serial.println(curr_time); display.showNumberDecEx(curr_time.toInt(), 0b11100000, false, 4, 0); } if (currentMillis - previousMillis1 >= 500) { previousMillis1 = currentMillis; if (curr_time == "000") { if (monthDay == specialDay && currentMonth == specialMonth) { send_message(yearlyMessage); } else if (monthDay == specialDay) { send_message(monthlyMessage); } } if (curr_time == "2311") { for (int i = 0; i < NUMPIXELS; i++) { pixels.setPixelColor(i, pixels.Color(255, 0, 127)); pixels.show(); } send_message("good nyt "); //change this message using small letters letters aside from k,m,q,v,w,x } else if (curr_time == "630") { for (int i = 0; i < NUMPIXELS; i++) { pixels.setPixelColor(i, pixels.Color(0, 0, 0)); pixels.show(); } send_message("ganbate");//change this message using small letters letters aside from k,m,q,v,w,x } else if (curr_time == "930") { send_message("hi");//change this message using small letters letters aside from k,m,q,v,w,x } else if (curr_time == "1159") { send_message("lets eat "); //change this message using small letters letters aside from k,m,q,v,w,x } else if (curr_time == "1830") { send_message("lets eat"); //change this message using small letters letters aside from k,m,q,v,w,x } else if (curr_time == "959") { send_message("gud nyt ");//change this message using small letters letters aside from k,m,q,v,w,x } } //checks if the switch is pressed for 1 second. If yes, turn on the RGB Lights to Purple buttonState = digitalRead(buttonPin); if (buttonState == HIGH) { pressed ++; Serial.println("touched"); } else { pressed = 0; } if (pressed >= 10) { pressed = 0; if (digitalRead(ledPin)) { for (int i = 0; i < NUMPIXELS; i++) { pixels.setPixelColor(i, pixels.Color(255, 0, 127));//Change the color of the rgb lights here pixels.show(); } } else if (!digitalRead(ledPin)) { for (int i = 0; i < NUMPIXELS; i++) { pixels.setPixelColor(i, pixels.Color(0, 0, 0)); pixels.show(); } } digitalWrite(ledPin, !digitalRead(ledPin)); Serial.println("on"); } delay(100); }<br>