页面加载中,请稍候
来源:电子工程世界发布时间:2022-08-27646浏览
询问 AI▲更多精彩内容请点击上方蓝字关注我们吧!

本周分享一个迷你但功能齐全的时钟项目,带有RGB效果,兼具温度监测功能。

NodeMCU (ESP8266)
定制PCB板
连接线
电池 5v


用NodeMCU显示时间,用Arduino监测温度;可以选择在每秒钟改变显示的颜色。
迷你LED的额定电压是3.0V到5.5V,16mA(每个LED)。
我们的NodeMCU有3.3V的稳压器,可以正常驱动所有的LED。

这里使用了WS2812 NeoPixel Led,它带有集成的IC,这样我们就可以对每段进行单独寻址。不仅LED是可寻址的,而且还可以改变每个像素的颜色(改变0-255(8位值)的数字值)。
LED有4个引脚,此外,这些LED具有数据输入和数据输出功能,通过这些功能,我们可以把它们连接起来,显示文字或数据。

要制作这个面板,首先我们可以仔细观察一下实际的液晶显示器。这样我们就可以复制段的排列,并为它编写代码。
在上图,各段被命名为A、B、C、D、E、F、G,为了连接所有的段,我们使用串联数据和平行电源的方法:所有的电源线,GND和VCC被并联到所有的LED上;数据输出被提供给串联的下一个LED的数据输入;把第一个面板的Dout连接到第二个面板的Din。


为了连接小时和分钟的面板,我们在两者之间放一个小的PCB板,就是上图中的"Dash"。

ESP8266集成了一个32位Tensilica处理器,标准的数字外围接口。
ESP8266具有板载Wi-Fi支持,利用它可以通过互联网调整时间而不需要任何RTC(实时时钟)模块。这样减少了连接,可以使整个项目变得更简单一些。
如果你使用下面的代码,那么可以在这个7段时钟中添加两个额外的功能。

在13号针脚上添加一个DHT11传感器,在12号针脚上添加一个触觉按钮,这样我们就可以在屏幕上获得摄氏或华氏的温度值。
用一个10k电阻将按钮的12号针脚连接到5V,另一端连接到GND。也就是说,当按钮针脚被拉到GND时,显示器将显示温度读数。
如果没有这个温度传感器,代码也可以正常运行,所以如果你想保持尽可能简单的话,可以不需要这些连接。

通过在A0引脚上做一个电阻分压器网络,添加一个带有10k电阻的LDR传感器,可以相应地改变亮度。
白天的亮度高,晚上的亮度低。
如果你不想要可调节的亮度,下面的代码也可以在没有这些传感器的情况下正常运行,它会保持默认设置。


我在EasyEDA中设计了电路,这里使用了3个LED。因此,每块面板总共需要21个LED。
底层做了连接引脚,这样别人就看不到连接和布线了。
CPL、BOM和Gerber文件在GitHub仓库:
https://github.com/halfstudents/ESP8266-Wi-Fi-based-7-Segment-Display-clock


使用上面的原理图连接NodeMCU。
这边用到的软件是Cirkit Designer,一个非常不错的软件。
平时你可以在学校演示的时候用这个线图、面包板电路以及创建一些自定义组件。另外,它最近还增加了代码编译、BOM和一些新的元件。
使用Cirkit Designer,我们可以绘制出逼真的电路图,这些电路图与物料清单相连接,这样就可以无缝订购电路中的部件。
Windows、Linux、Mac都可以使用,下载地址:https://www.cirkitstudio.com/download.html
#include<ESP8266WiFi.h>
#include<Adafruit_NeoPixel.h>
#include<WiFiUdp.h>
#include<NTPClient.h>
#include<TimeLib.h>
#include<DHT.h>
#include<Adafruit_Sensor.h>#definePIXEL_PER_SEGMENT3//NumberofLEDsineachSegment
#definePIXEL_DIGITS4//NumberofconnectedDigits
#definePIXEL_PIN2//GPIOPin
#definePIXEL_DASH1//Binarysegment
#defineLDR_PINA0//LDRpin
#defineDHT_PIN13//DHTSensorpin
#defineBUTTON_PIN12//ButtonpinWiFi.begin(ssid,password);
Serial.print("Connecting.");
while(WiFi.status()!=WL_CONNECTED)voiddisp_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)面板显示的颜色设置:
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);完整代码:
#include<ESP8266WiFi.h>
#include<Adafruit_NeoPixel.h>
#include<WiFiUdp.h>
#include<NTPClient.h>
#include<TimeLib.h>
#include<DHT.h>
#include<Adafruit_Sensor.h>
#definePIXEL_PER_SEGMENT3//NumberofLEDsineachSegment
#definePIXEL_DIGITS4//NumberofconnectedDigits
#definePIXEL_PIN2//GPIOPin
#definePIXEL_DASH1//Binarysegment
#defineLDR_PINA0//LDRpin
#defineDHT_PIN13//DHTSensorpin
#defineBUTTON_PIN12//Buttonpin
//Uncommentthetypeofsensorinuse
#defineDHT_TYPEDHT11//DHT11
//#defineDHT_TYPEDHT22//DHT22(AM2302)
//#defineDHT_TYPEDHT21//DHT21(AM2301)
#defineTIME_FORMAT12//12=12hoursformat||24=24hoursformat
Adafruit_NeoPixelstrip=Adafruit_NeoPixel((PIXEL_PER_SEGMENT*7*PIXEL_DIGITS)+(PIXEL_DASH*2),PIXEL_PIN,NEO_GRB+NEO_KHZ800);
DHTdht(DHT_PIN,DHT_TYPE);
//setWi-FiSSIDandpassword
constchar*ssid="Hackster";
constchar*password="*************";
WiFiUDPntpUDP;
//'time.nist.gov'isused(defaultserver)with+1houroffset(3600seconds)60seconds(60000milliseconds)updateinterval
NTPClienttimeClient(ntpUDP,"time.nist.gov",19800,60000);//GMT+5:30:5*3600+30*60=19800
intperiod=2000;//Updatefrequency
unsignedlongtime_now=0;
intSecond,Minute,Hour;
//setdefaultbrightness
intBrightness=40;
//currenttemperature,updatedinloop()
intTemperature;
boolShow_Temp=false;
//Digitsarray
bytedigits[12]={
//abcdefg
0b1111110,//0
0b0110000,//1
0b1101101,//2
0b1111001,//3
0b0110011,//4
0b1011011,//5
0b1011111,//6
0b1110000,//7
0b1111111,//8
0b1110011,//9
0b1001110,//C
0b1000111,//F
};
//ClearallthePixels
voidclearDisplay(){
for(inti=0;i<strip.numPixels();i++){
strip.setPixelColor(i,strip.Color(0,0,0));
}
strip.show();
}
voidsetup(){
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);
}
voidloop(){
if(WiFi.status()==WL_CONNECTED){//checkWiFiconnectionstatus
intsensor_val=analogRead(LDR_PIN);
Brightness=40;
timeClient.update();
intHours;
unsignedlongunix_epoch=timeClient.getEpochTime();//getUNIXEpochtime
Second=second(unix_epoch);//getseconds
Minute=minute(unix_epoch);//getminutes
Hours=hour(unix_epoch);//gethours
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();//ShowTime
}
}
voiddisp_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();
}
voiddisp_Dash(){
intdot,dash;
for(inti=0;i<2;i++){
dot=2*(PIXEL_PER_SEGMENT*7)+i;
for(intj=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));
}
}
}
voidwriteDigit(intindex,intval){
bytedigit=digits[val];
intmargin;
if(index==0||index==1)margin=0;
if(index==2||index==3)margin=1;
if(index==4||index==5)margin=2;
for(inti=6;i>=0;i--){
intoffset=index*(PIXEL_PER_SEGMENT*7)+i*PIXEL_PER_SEGMENT+margin*2;
uint32_tcolor;
if(digit0x01!=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(intj=offset;j<offset+PIXEL_PER_SEGMENT;j++){
strip.setPixelColor(j,color);
}
digit=digit>>1;
}
}


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

“Din”与“Dout”是串联在一起的,如果接反了或从哪里断开了,整个装置就会停止工作。
如上图所示,连接“Dash”部分。
确保所有的连接都焊接好了,干焊会导致数据值和颜色的改变。
在焊接的时候,注意PCB温度不要太高。
推荐阅读
便携烙铁开源系统IronOS,你也可以做!
添加微信回复“进群”
拉你进技术交流群!
国产芯|汽车电子|物联网|新能源|电源|工业|嵌入式…..
在公众号内回复您想搜索的任意内容,如问题关键字、技术名词、bug代码等,就能轻松获得与之相关的专业技术内容反馈。快去试试吧!
如果您想经常看到我们的文章,可以进入我们的主页,点击屏幕右上角「三个小点」,点击「设为星标」。
欢迎扫码关注



新闻来源:电子工程世界,文中所述为作者独立观点,不代表icspec立场。更多精彩资讯请下载icspec App。如对本稿件有异议,请联系微信客服specltkj。
暂无评论哦,快来评论一下吧!
2026-07-16
2026-06-08

2026-07-22