2022-4-28 16:37:40 [显示全部楼层]
3683浏览
查看: 3683|回复: 5

用ESP8266做一个高颜值的RGB时钟!

[复制链接]
本帖最后由 RRoy 于 2022-4-28 16:45 编辑

qw2.jpg

马上要过五一了,这周给大家分享一个用ESP8266做一个高颜值的RGB时钟的项目,这个时钟还具有自动亮度控制功能并配备了温度传感器!


材料准备
  • PCB
  • ESP8266或Nodemcu
  • 跳线
  • 焊接工具


第1步: 准备工作



qw3.jpg

qw4.jpg

Neo Pixel是可寻址的LED,我们可以通过编程,让它显示任何一种颜色或者数字。

Neo Pixel有不同的smd封装,这个项目使用的是Ws2812b-5050 mini RGB。

这种迷你LED的额定电压为3.0V到5.5V,电流为16mA(每个LED)。

NodeMCU有3.3V的稳压器,可以正常驱动所有的LED。



第2步:使用Neo Pixel Led制作7段显示器
qw5.jpg

qw6.jpg

qw7.jpg

在这里,我们需要把所有的电源并联起来,把所有的数据连接串联起来,使用7段显示方法,如上图连接所有的LED。

每段有2个LED,整个面板总共有14个LED。

我们需要4个面板来显示时间(2个显示小时,2个显示分钟)。

当然还可以再连接两个面板来显示秒/任何其他数值,或者温度。

不管怎么连接,记住总是要把第一个面板的DOUT连接到第二个面板的DIN。



第3步:连接仪表盘

qw8.jpg


qw9.jpg

为了连接小时和分钟面板,在两面板之间有一个小的PCB板,名为Dash,包含了2个LED作为二进制数字,这2个LED灯每隔一秒就会发光一次。
第四步:NodeMCU/ESP8266介绍
qw10.jpg

ESP8266集成了一个32位Tensilica处理器,标准的数字外围接口。

我们的ESP8266具有板载Wi-Fi支持,通过它我们可以连上互联网调整时间,而不需要任何RTC(实时时钟)模块。

这样子的话可以减少连接,使整个项目变得更简单一些。



第5步:代码中支持的功能

qw11.jpg

如果使用本文提供的代码,那么我们可以在这个7段时钟中增加2个额外的功能:


1. 使用触觉开关的温度和湿度显示

在13号针脚上添加一个DHT11传感器,在12号针脚上添加一个触觉按钮,可以在屏幕上获得摄氏或华氏的温度值。

用一个10k电阻将按钮的第12针脚连接到5V,另一端连接到GND。也就是说,当按钮针脚被拉到GND时,显示器将显示温度读数。如果没有这个温度传感器,代码也可以工作,所以如果你想让项目简单一点,也可以不需要这些连接。


2. 使用引脚A0的LDR传感器进行亮度控制

qw12.jpg

通过在A0引脚上做一个电阻分压器网络,添加一个带有10k电阻的LDR传感器,可以相应地改变亮度。

白天的亮度高,晚上的亮度低。如果你不想要可调节亮度,这部分代码也可以在没有这些传感器的情况下工作,它将会锁定在默认设置。


第7步:视频演示





第8步:7-段时钟
qw13.jpg


qw14.jpg

现在,我们有4个面板和一个Dash(仪表盘)。

根据上面GIF图来连接面板和仪表盘;将2个面板串联在一起。

然后使用上面给出的原理图连接NodeMCU。


第9步:代码

首先使用库来初始化代码:
  1. #include <ESP8266WiFi.h>
  2. #include <Adafruit_NeoPixel.h>
  3. #include <WiFiUdp.h>
  4. #include <NTPClient.h>
  5. #include <TimeLib.h>
  6. #include <DHT.h>
  7. #include <Adafruit_Sensor.h>
复制代码
定义所有像素、I/O引脚、传感器引脚:
  1. #define PIXEL_PER_SEGMENT 2 // Number of LEDs in each Segment
  2. #define PIXEL_DIGITS 4 // Number of connected Digits
  3. #define PIXEL_PIN 2 // GPIO Pin
  4. #define PIXEL_DASH 1 // Binary segment
  5. #define LDR_PIN A0 // LDR pin
  6. #define DHT_PIN 13 // DHT Sensor pin
  7. #define BUTTON_PIN 12 // Button pin
复制代码

对于时间格式,使用Wi-Fi把ESP8266连接到互联网:

  1. WiFi.begin(ssid, password);
  2. Serial.print("Connecting.");
  3. while ( WiFi.status() != WL_CONNECTED )
复制代码
时间设置:
  1. void disp_Time() {
  2. clearDisplay();
  3. writeDigit(0, Hour / 10);
  4. writeDigit(1, Hour % 10);
  5. writeDigit(2, Minute / 10);
  6. writeDigit(3, Minute % 10);
  7. writeDigit(4, Second / 10);
  8. writeDigit(5, Second % 10);
  9. disp_Dash();
复制代码


面板上的颜色设置:
  1. if (index == 0 || index == 1 ) color = strip.Color(0, Brightness, 0);
  2. if (index == 2 || index == 3 ) color = strip.Color(0, Brightness, 0);
  3. if (index == 4 || index == 5 ) color = strip.Color(Brightness, 0, 0);
复制代码


这只是一个简单的介绍,同时代码还有温度和自动时间选项。

温度模式可以通过数字针脚12的开关来选择。

第十步:完整代码


  1. #include <ESP8266WiFi.h>
  2. #include <Adafruit_NeoPixel.h>
  3. #include <WiFiUdp.h>
  4. #include <NTPClient.h>
  5. #include <TimeLib.h>
  6. #include <DHT.h>
  7. #include <Adafruit_Sensor.h>
  8. #define PIXEL_PER_SEGMENT  2     // Number of LEDs in each Segment
  9. #define PIXEL_DIGITS       4     // Number of connected Digits
  10. #define PIXEL_PIN          2     // GPIO Pin
  11. #define PIXEL_DASH         1    // Binary segment
  12. #define LDR_PIN       A0    // LDR pin
  13. #define DHT_PIN       13    // DHT Sensor pin
  14. #define BUTTON_PIN    12    // Button pin
  15. // Uncomment the type of sensor in use
  16. #define DHT_TYPE    DHT11     // DHT 11
  17. //#define DHT_TYPE    DHT22     // DHT 22 (AM2302)
  18. //#define DHT_TYPE    DHT21     // DHT 21 (AM2301)
  19. #define TIME_FORMAT        12    // 12 = 12 hours format || 24 = 24 hours format
  20. Adafruit_NeoPixel strip = Adafruit_NeoPixel((PIXEL_PER_SEGMENT * 7 * PIXEL_DIGITS) + (PIXEL_DASH * 2), PIXEL_PIN, NEO_GRB + NEO_KHZ800);
  21. DHT dht(DHT_PIN, DHT_TYPE);
  22. // set Wi-Fi SSID and password
  23. const char *ssid     = "Hackster";
  24. const char *password = "Sainisagar7294";
  25. WiFiUDP ntpUDP;
  26. // 'time.nist.gov' is used (default server) with +1 hour offset (3600 seconds) 60 seconds (60000 milliseconds) update interval
  27. NTPClient timeClient(ntpUDP, "time.nist.gov", 19800, 60000); //GMT+5:30 : 5*3600+30*60=19800
  28. int period = 2000;   //Update frequency
  29. unsigned long time_now = 0;
  30. int Second, Minute, Hour;
  31. // set default brightness
  32. int Brightness = 40;
  33. // current temperature, updated in loop()
  34. int Temperature;
  35. bool Show_Temp = false;
  36. //Digits array
  37. byte digits[12] = {
  38.   //abcdefg
  39.   0b1111110,     // 0
  40.   0b0110000,     // 1
  41.   0b1101101,     // 2
  42.   0b1111001,     // 3
  43.   0b0110011,     // 4
  44.   0b1011011,     // 5
  45.   0b1011111,     // 6
  46.   0b1110000,     // 7
  47.   0b1111111,     // 8
  48.   0b1110011,      // 9
  49.   0b1001110,     // C
  50.   0b1000111,     // F
  51. };
  52. //Clear all the Pixels
  53. void clearDisplay() {
  54.   for (int i = 0; i < strip.numPixels(); i++) {
  55.     strip.setPixelColor(i, strip.Color(0, 0, 0));
  56.   }
  57.   strip.show();
  58. }
  59. void setup() {
  60.   Serial.begin(115200);
  61.   strip.begin();
  62.   strip.show();
  63.   dht.begin();
  64.   pinMode(BUTTON_PIN, INPUT);
  65.   WiFi.begin(ssid, password);
  66.   Serial.print("Connecting.");
  67.   while ( WiFi.status() != WL_CONNECTED ) {
  68.     delay(500);
  69.     Serial.print(".");
  70.   }
  71.   Serial.println("connected");
  72.   timeClient.begin();
  73.   delay(10);
  74. }
  75. void loop() {
  76.   if (WiFi.status() == WL_CONNECTED) { // check WiFi connection status
  77.     int sensor_val = analogRead(LDR_PIN);
  78.     Brightness =40;
  79.     timeClient.update();
  80.     int Hours;
  81.     unsigned long unix_epoch = timeClient.getEpochTime();   // get UNIX Epoch time
  82.     Second = second(unix_epoch);                            // get seconds
  83.     Minute = minute(unix_epoch);                            // get minutes
  84.     Hours  = hour(unix_epoch);                              // get hours
  85.     if (TIME_FORMAT == 12) {
  86.       if (Hours > 12) {
  87.         Hour = Hours - 12;
  88.       }
  89.       else
  90.         Hour = Hours;
  91.     }
  92.     else
  93.       Hour = Hours;
  94.   }
  95.   if (digitalRead(BUTTON_PIN) == LOW) {
  96.     Show_Temp = true;
  97.   }
  98.   else
  99.     Show_Temp = false;
  100.   if (Show_Temp) {
  101.     Temperature = dht.readTemperature();
  102.     Serial.println(Temperature);
  103.     clearDisplay();
  104.     writeDigit(0, Temperature / 10);
  105.     writeDigit(1, Temperature % 10);
  106.     writeDigit(2, 10);
  107.     strip.setPixelColor(28, strip.Color(Brightness, Brightness,  Brightness));
  108.     strip.show();
  109.     delay(3000);
  110.     clearDisplay();
  111.     Show_Temp = false;
  112.   }
  113.   while (millis() > time_now + period) {
  114.     time_now = millis();
  115.     disp_Time();     // Show Time
  116.   }
  117. }
  118. void disp_Time() {
  119.   clearDisplay();
  120.   writeDigit(0, Hour / 10);
  121.   writeDigit(1, Hour % 10);
  122.   writeDigit(2, Minute / 10);
  123.   writeDigit(3, Minute % 10);
  124.   writeDigit(4, Second / 10);
  125.   writeDigit(5, Second % 10);
  126.   disp_Dash();
  127.   strip.show();
  128. }
  129. void disp_Dash() {
  130.   int dot, dash;
  131.   for (int i = 0; i < 2; i++) {
  132.     dot = 2 * (PIXEL_PER_SEGMENT * 7) + i;
  133.     for (int j = 0; j < PIXEL_DASH; j++) {
  134.       dash = dot + j * (2 * (PIXEL_PER_SEGMENT * 7) + 2);
  135.       Second % 2 == 0 ? strip.setPixelColor(dash, strip.Color(0,Brightness ,0)) : strip.setPixelColor(dash, strip.Color(0, Brightness,0));
  136.     }
  137.   }
  138. }
  139. void writeDigit(int index, int val) {
  140.   byte digit = digits[val];
  141.   int margin;
  142.   if (index == 0 || index == 1 ) margin = 0;
  143.   if (index == 2 || index == 3 ) margin = 1;
  144.   if (index == 4 || index == 5 ) margin = 2;
  145.   for (int i = 6; i >= 0; i--) {
  146.     int offset = index * (PIXEL_PER_SEGMENT * 7) + i * PIXEL_PER_SEGMENT + margin * 2;
  147.     uint32_t color;
  148.     if (digit & 0x01 != 0) {
  149.       if (index == 0 || index == 1 ) color = strip.Color(Brightness, 0,  Brightness);
  150.       if (index == 2 || index == 3 ) color = strip.Color(Brightness, 0,Brightness);
  151.       if (index == 4 || index == 5 ) color = strip.Color(Brightness, 0,  0);
  152.     }
  153.     else
  154.       color = strip.Color(0, 0, 0);
  155.     for (int j = offset; j < offset + PIXEL_PER_SEGMENT; j++) {
  156.       strip.setPixelColor(j, color);
  157.     }
  158.     digit = digit >> 1;
  159.   }
  160. }
复制代码

第11步:完整电路图(高清版本文末下载)
qw15.jpg

qw16.jpg


第12步:PCB设计(面板部分)
qw17.jpg

主要的PCB设计,用于显示数字和其他字母。

第13步:PCB设计(Dash部分)
qw18.jpg

qw19.jpg


第14步:故障排除
  • DIN总是与DOUT串联在一起,如果接反了或从任何地方断开了,整个装置就会停止工作;
  • 按上面的图连接Dash;
  • 确保所有的连接都焊接好,干焊会导致数据值和颜色的改变;
  • 在焊接时,不要把印刷电路板加热太多,温度保持在300度。


第15步:完整展示

qw20.jpg


qw21.jpg

喜欢大家喜欢这个项目,提前祝大家五一快乐!

原文链接:https://www.instructables.com/RGB-7-Segment-Clock-Using-ESP8266/
原作者:sainisagar7294
译文首发于:DF创客社区
转载请注明原作者及出处




drive-download-20220428T064734Z-001.zip

832.59 KB, 下载次数: 114

hnyzcj  版主

发表于 2022-4-28 20:53:22

漂亮
回复

使用道具 举报

 初级技匠

发表于 2022-5-1 09:00:34

牛逼                  
回复

使用道具 举报

一路逍遥  学徒

发表于 2022-5-3 19:06:28

太 棒 了
回复

使用道具 举报

橘子一只awa  学徒

发表于 2022-5-4 09:08:26

                                         awa
回复

使用道具 举报

派大星ym  初级技匠

发表于 2022-8-1 13:45:13

颜值爱了爱了
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

为本项目制作心愿单
购买心愿单
心愿单 编辑
[[wsData.name]]

硬件清单

  • [[d.name]]
btnicon
我也要做!
点击进入购买页面
上海智位机器人股份有限公司 沪ICP备09038501号-4

© 2013-2022 Comsenz Inc. Powered by Discuz! X3.4 Licensed

mail