关键词
NodeMCU,74HC595,8421BCD,NTP服务器,ESP8266,WiFi,Arduino,LED,时钟
引言
在这个项目中,使用NodeMCU(基于ESP8266的开源物联网平台)和74HC595(8位串行输入、并行输出的移位寄存器)来创建一个数字时钟。通过WiFi连接到网络,获取网络时间,并使用LED灯按照8421BCD码的形式显示时间。此外,还使用两个LED灯来模拟“秒钟”的闪烁的效果。
材料和工具
为了完成这个项目,我们需要以下的硬件和软件工具:
- NodeMCU开发板——1块
- 直插74HC595移位寄存器——2块
- 1206贴片LED灯——18个
- 1206贴片220欧姆电阻——18个
- Type-C母座——1个
- 7*7自锁开关——1个
- 1*15p直插单排针母座——2个
- ESP8266WiFi库,用于WiFi连接
- NTPClient库,用于获取网络时间
- WiFiUdp库,用于UDP通信
设计和实现
连接硬件
使用NodeMCU的D5、D6和D7引脚来控制第一块74HC595的SER、SRCLK和RCLK引脚。
使用NodeMCU的D2、D1和D0引脚来控制第二块74HC595的SER、SRCLK和RCLK引脚。
使用NodeMCU的D4和D3引脚来控制两个LED灯。
编写代码
在代码中,首先设置了所有的引脚为输出模式。然后,连接到WiFi,并开始NTP客户端来获取网络时间。 在主循环中,首先更新NTP客户端,然后获取当前的小时和分钟,并将小时和分钟转换为8421BCD编码,然后通过74HC595扩展IO口,使用16个LED灯进行显示。最后,使用2个LED灯模拟“秒钟”闪烁。
以下为Arduino代码:
#include <ESP8266WiFi.h> // 引入ESP8266WiFi库,用于WiFi连接
#include <NTPClient.h> // 引入NTPClient库,用于获取网络时间
#include <WiFiUdp.h> // 引入WiFiUdp库,用于UDP通信
// 定义74HC595_1的引脚
#define DATA_PIN_1 14 // SER引脚 D5 on NodeMCU 14 on 74HC595_1
#define CLOCK_PIN_1 12 // SRCLK引脚 D6 on NodeMCU 11 on 74HC595_1
#define LATCH_PIN_1 13 // RCLK引脚 D7 on NodeMCU 12 on 74HC595_1
// 定义74HC595_2的引脚
#define DATA_PIN_2 4 // SER引脚 D2 on NodeMCU 14 on 74HC595_2
#define CLOCK_PIN_2 5 // SRCLK引脚 D1 on NodeMCU 11 on 74HC595_2
#define LATCH_PIN_2 16 // RCLK引脚 D0 on NodeMCU 12 on 74HC595_2
// 定义上下两个灯的引脚
#define UPPER 2 // 上面的灯 D4 GPIO2
#define LOWER 0 // 下面的灯 D3 GPIO0
// 替换为你的WiFi信息
const char *ssid = "EXAMPLE";
const char *password = "12345678";
WiFiUDP ntpUDP; // 创建一个WiFiUDP对象,用于UDP通信
// 创建NTP客户端,时区设置为GMT+8
NTPClient timeClient(ntpUDP, "pool.ntp.org", 60 * 60 * 8);
void setup(){
// 设置74HC595_1的引脚为输出模式
pinMode(DATA_PIN_1, OUTPUT);
pinMode(CLOCK_PIN_1, OUTPUT);
pinMode(LATCH_PIN_1, OUTPUT);
// 设置74HC595_2的引脚为输出模式
pinMode(DATA_PIN_2, OUTPUT);
pinMode(CLOCK_PIN_2, OUTPUT);
pinMode(LATCH_PIN_2, OUTPUT);
// 设置上下两个灯的引脚为输出模式
pinMode(UPPER, OUTPUT);
pinMode(LOWER, OUTPUT);
// 初始化所有LED
digitalWrite(LATCH_PIN_1, LOW); // 拉低锁存引脚,开始数据传输
shiftOut(DATA_PIN_1, CLOCK_PIN_1, MSBFIRST, 0); // 发送"00000000"
digitalWrite(LATCH_PIN_1, HIGH); // 拉高锁存引脚,完成数据传输,74HC595并行输出
digitalWrite(LATCH_PIN_2, LOW); // 拉低锁存引脚,开始数据传输
shiftOut(DATA_PIN_2, CLOCK_PIN_2, MSBFIRST, 0); // 发送"00000000"
digitalWrite(LATCH_PIN_2, HIGH); // 拉高锁存引脚,完成数据传输,74HC595并行输出
Serial.begin(115200); // 开始串口通信,波特率为115200
WiFi.begin(ssid, password); // 连接到WiFi
// 等待WiFi连接成功
while ( WiFi.status() != WL_CONNECTED ) {
delay (500);
Serial.print(".");
}
timeClient.begin(); // 开始NTP客户端
}
void loop() {
timeClient.update(); // 更新NTP客户端,获取最新的时间
// 获取当前的小时和分钟
int hour = timeClient.getHours();
int minute = timeClient.getMinutes();
int bcd_hour = ((hour / 10) << 4) | (hour % 10); // 将小时转换为BCD编码
int bcd_minute = ((minute / 10) << 4) | (minute % 10); // 将分钟转换为BCD编码
// 向74HC595_1发送BCD编码的小时
digitalWrite(LATCH_PIN_1, LOW); // 拉低锁存引脚,开始数据传输
shiftOut(DATA_PIN_1, CLOCK_PIN_1, MSBFIRST, bcd_hour); // 发送BCD编码
digitalWrite(LATCH_PIN_1, HIGH); // 拉高锁存引脚,完成数据传输,74HC595并行输出
// 向74HC595_2发送BCD编码的分钟
digitalWrite(LATCH_PIN_2, LOW); // 拉低锁存引脚,开始数据传输
shiftOut(DATA_PIN_2, CLOCK_PIN_2, MSBFIRST, bcd_minute); // 发送BCD编码
digitalWrite(LATCH_PIN_2, HIGH); // 拉高锁存引脚,完成数据传输,74HC595并行输出
// 闪烁上下两个灯
digitalWrite(UPPER, HIGH);
digitalWrite(LOWER, HIGH);
delay(500);
digitalWrite(UPPER, LOW);
digitalWrite(LOWER, LOW);
delay(500);
}
效果
PCB图
成果图
“感谢您阅读这篇文章!如果您有任何问题、建议或想法,欢迎在评论区留言。我期待与您的讨论和交流!”