Home > Microcontroller >Microcontroller Production > How to use ESP8266 to make a mini fully functional clock

How to use ESP8266 to make a mini fully functional clock

Source: InternetPublisher:containsmachine Keywords: Clock ESP8266 Updated: 2024/05/24

What I am going to make is a mini but fully functional clock, which also has RGB effects and temperature monitoring functions.

Construct

First of all, I wanted to make a 7 segment display. But this time it needed to display larger numbers and RGB effects. Because this can be used to display some readings, like a clock using Nodemcu, temperature monitoring using Arduino. Also, there is an option to change the color after every second or after the next reading.

Previously, because I used 2 LEDs to display each segment of numbers, our eyes could not recognize the numbers quickly and accurately. It means we need to focus. I am happy with the design, but it is time to update it.

This mini LED has a rated voltage of: 3.0v to 5.5volts@16mA (per LED). Our NodeMCU has a 3.3 volt regulator to drive all the LEDs properly.

LEDWS2812B3030:

I used a ws2812neopixiled which comes with an integrated ic so we can address each segment individually. Not only is the LED addressable, but the color of each pixel can also be changed, changing the digital value between 0-255 (8 bit value).

This LED has 4 pins and the pin configuration can be seen in the above mentioned picture. Moreover, these LEDs come with data in and data out functionality which makes them more interesting through which we can add them to display text or data.

Making a 7-Segment Display Using the NeoPixel LEDs:

To make the panel, first we have to take a close look at an actual LCD display. This way we can copy the arrangement of the segments and design the code for it.

So here, the segments are named A, B, C... to G, so to connect all the segments, we use the method of serial data and parallel power. All the power lines, GND and VCC are connected in parallel to all the LEDs. The data OUT is given in series to the data in of the next Led. Always connect the Dout of the first panel to the Din of the second panel.

connect:

To connect the hour and minute panels, there is a small PCB in the middle called Dash which contains 2 LEDs as binary digits. These 2 LEDs will light up every second.

Requirements for NodeMCU/ESP8266:

ESP8266 integrates a 32-bit Tensilica processor and standard digital peripheral interfaces.

Our Esp8266 has onboard Wi-Fi support through which we can adjust the time through the internet without any RTC(Real Time Clock) module. This will reduce the connections and make this project simple.

If you use my code then you can add 2 extra features to this 7 segment clock.

1) Temperature and humidity are controlled by touch switch

Add a DHT11 sensor on pin 13 and a tactile button on pin 12 to get the temperature value in Celsius or Fahrenheit on the screen.

Use a 10k resistor to connect button pin 12 to 5 volts and the other end to GND. Meaning when the button pin is pulled down to GND the display will show the temperature reading. The code will also work without this temperature sensor so if you want to keep it simple these connections are not necessary.

2) Use LDR sensor at pin A0 for brightness control

Add a LDR sensor with a 10k resistor by making a resistor divider network on the A0 pin, this will change the brightness accordingly. High brightness during the day and low brightness at night. If you don't want to adjust the brightness, the code will also work without these sensors, it will lock the default settings.

7-segment clock:

pYYBAGJ-AliARB40AAPRbiCX7Qo031.png

I designed the circuit in EasyEDA for each section, here I am using 3 LEDs. So you need a total of 21 LEDs per panel for this configuration. I made the connecting pins on the bottom layer so that the second person can't see the connections and wiring.

Now connect the dash in the middle and connect the NodeMCU using the schematic given below:

I have been using the cirkit designer software and I think it is the best way to express and present circuits.

Code:
1) First use the library initialization code

#include

#define PIXEL_PER_SEGMENT 3 // Number of LEDs in each Segment
#define PIXEL_DIGITS 4 // Number of connected Digits #define
PIXEL_PIN 2 // GPIO Pin
#define PIXEL_DASH 1 // Binary segment
#define LDR_PIN A0 // LDR pin
#define DHT_PIN 13 // DHT Sensor pin
#define BUTTON_PIN 12 // Button pin
3) For the time format, use Wi-Fi to connect the Internet to the ESP8266

WiFi.begin(ssid, password);
Serial.print("Connecting.");
while ( WiFi.status() != WL_CONNECTED )
4) Setting the time on the Pixel

void disp_Time() {
clearDisplay();
writeDigit(0, Hour / 10);
writeDigit(1, Hour % 10);
writeDigit(2, Minute / 10);
writeDigit(3, Minute % 10);
writeDigit(4, Second / 10);
writeDigit(5, Second % 10);
disp_Dash();
5) Color settings on the panel:

if (index == 0 || index == 1 ) color = strip.Color(0, Brightness, 0);
if (index == 2 || index == 3 ) color = strip.Color(0, Brightness, 0);
if (index == 4 || index == 5 ) color = strip.Color(Brightness, 0, 0);

These are brief descriptions about the code, the code also has temperature and auto time options. The temperature mode can be selected using the tactile switch on digital pin 12

Working code:

#include

#define PIXEL_PER_SEGMENT 3   // Number of LEDs in each Segment
#define PIXEL_DIGITS    4   // Number of connected Digits
#define PIXEL_PIN     2   // GPIO Pin
#define PIXEL_DASH     1  // Binary segment

#define LDR_PIN    A0  // LDR pin
#define DHT_PIN    13  // DHT Sensor pin
#define BUTTON_PIN  12  // Button pin

// Uncomment the type of sensor in use
#define DHT_TYPE  DHT11   // DHT 11
//#define DHT_TYPE  DHT22   // DHT 22 (AM2302)
//#define DHT_TYPE  DHT21   // DHT 21 (AM2301)

#define TIME_FORMAT    12  // 12 = 12 hours format || 24 = 24 hours format

Adafruit_NeoPixel strip = Adafruit_NeoPixel((PIXEL_PER_SEGMENT * 7 * PIXEL_DIGITS) + (PIXEL_DASH * 2), PIXEL_PIN, NEO_GRB + NEO_KHZ800);
DHT dht(DHT_PIN, DHT_TYPE);

// set Wi-Fi SSID and password
const char *ssid   = "Hackster";
const char *password = "*************";

WiFiUDP ntpUDP;
// ’time.nist.gov’ is used (default server) with +1 hour offset (3600 seconds) 60 seconds (60000 milliseconds) update interval
NTPClient timeClient(ntpUDP, "time.nist.gov", 19800, 60000); //GMT+5:30 : 5*3600+30*60=19800

int period = 2000;  //Update frequency
unsigned long time_now = 0;
int Second, Minute, Hour;

// set default brightness
int Brightness = 40;
// current temperature, updated in loop()
int Temperature;

bool Show_Temp = false;

//Digits array
byte digits[12] = {
//abcdefg
0b1111110, // 0
0b0110000, // 1
0b1101101, // 2
0b1111001, // 3
0b0110011, // 4
0b1011011
, // 6
0b111111 0000 , // 7
0b1111111, // 8
0b1110011, // 9
0b1001110, // C
0b1000111, // F
};

//Clear all the Pixels
void clearDisplay() {
for (int i = 0; i < strip.numPixels(); i++) {
 strip.setPixelColor(i, strip.Color(0, 0, 0));
}
strip.show();
}

void setup() {
Serial.begin(115200);
strip.begin();
strip.show();

dht.begin();
pinMode(BUTTON_PIN, INPUT);

WiFi.begin(ssid, password);
Serial.print("Connecting.");
while ( WiFi.status() != WL_CONNECTED ) {
 delay(500);
 Serial.print(".");
}
Serial.println("connected");
timeClient.begin();
delay(10);
}

void loop() {
if (WiFi.status() == WL_CONNECTED) { // check WiFi connection status
 int sensor_val = analogRead(LDR_PIN);
 Brightness =40;
 timeClient.update();
 int Hours;
 unsigned long unix_epoch = timeClient.getEpochTime();  // get UNIX Epoch time
 Second = second(unix_epoch);              // get seconds
 Minute = minute(unix_epoch);              // get minutes
 Hours = hour(unix_epoch);               // get hours

if (TIME_FORMAT == 12) {
  if (Hours > 12) {
Hour = Hours - 12;
  }
  else
Hour = Hours;
 }
 else
  Hour = Hours;
}

if (digitalRead(BUTTON_PIN) == LOW) {
 Show_Temp = true;
}
else
 Show_Temp = false;

if (Show_Temp) {
 Temperature = dht.readTemperature();
 Serial.println(Temperature);
 clearDisplay();
 writeDigit(0, Temperature / 10);
 writeDigit(1, Temperature % 10);
 writeDigit(2, 10);
 strip.setPixelColor(28, strip.Color(Brightness, Brightness, Brightness));
 strip.show();
 delay(3000);
 clearDisplay();
 Show_Temp = false;
}
while (millis() > time_now + period) {
 time_now = millis();
 disp_Time();   // Show Time
}
}

void disp_Time() {
clearDisplay();
writeDigit(0, Hour / 10);
writeDigit(1, Hour % 10);
writeDigit(2, Minute / 10);
writeDigit(3, Minute % 10);
writeDigit(4, Second / 10);
writeDigit(5, Second % 10);
disp_Dash();
strip.show();
}

void disp_Dash() {
int dot, dash;
for (int i = 0; i < 2; i++) {
 dot = 2 * (PIXEL_PER_SEGMENT * 7) + i;
 for (int j = 0; j < PIXEL_DASH; j++) {
  dash = dot + j * (2 * (PIXEL_PER_SEGMENT * 7) + 2);
  Second % 2 == 0 ? strip.setPixelColor(dash, strip.Color(0,Brightness ,0)) : strip.setPixelColor(dash, strip.Color(0, Brightness,0));
 }
}
}

void writeDigit(int index, int val) {
byte digit = digits[val];
int margin;
if (index == 0 || index == 1 ) margin = 0;
if (index == 2 || index == 3 ) margin = 1;
if (index == 4 || index == 5 ) margin = 2;
for (int i = 6; i >= 0; i--) {
 int offset = index * (PIXEL_PER_SEGMENT * 7) + i * PIXEL_PER_SEGMENT + margin * 2;
 uint32_t color;
 if (digit & 0x01 != 0) {
  if (index == 0 || index == 1 ) color = strip.Color(Brightness, 0, Brightness);
  if (index == 2 || index == 3 ) color = strip.Color(Brightness, 0,Brightness);
  if (index == 4 || index == 5 ) color = strip.Color(Brightness, 0, 0);
 }
 else
  color = strip.Color(0, 0, 0);

for (int j = offset; j < offset + PIXEL_PER_SEGMENT; j++) {
  strip.setPixelColor(j, color);
 }
 digit = digit >> 1;
}
}

EEWorld
subscription
account

EEWorld
service
account

Automotive
development
circle

About Us Customer Service Contact Information Datasheet Sitemap LatestNews


Room 1530, 15th Floor, Building B, No.18 Zhongguancun Street, Haidian District, Beijing, Postal Code: 100190 China Telephone: 008610 8235 0740

Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved 京ICP证060456号 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号