使用esp8266做一个流水灯:基于ESP8266做一个漂亮的迷你时钟
使用esp8266做一个流水灯:基于ESP8266做一个漂亮的迷你时钟在上图,各段被命名为A、B、C、D、E、F、G,为了连接所有的段,我们使用串联数据和平行电源的方法:所有的电源线,GND和VCC被并联到所有的LED上;数据输出被提供给串联的下一个LED的数据输入;把第一个面板的Dout连接到第二个面板的Din。要制作这个面板,首先我们可以仔细观察一下实际的液晶显示器。这样我们就可以复制段的排列,并为它编写代码。我们的NodeMCU有3.3V的稳压器,可以正常驱动所有的LED。这里使用了WS2812 NeoPixel Led,它带有集成的IC,这样我们就可以对每段进行单独寻址。不仅LED是可寻址的,而且还可以改变每个像素的颜色(改变0-255(8位值)的数字值)。LED有4个引脚,此外,这些LED具有数据输入和数据输出功能,通过这些功能,我们可以把它们连接起来,显示文字或数据。
本周分享一个迷你但功能齐全的时钟项目,带有RGB效果,兼具温度监测功能。
第1步:材料准备- NodeMCU (ESP8266)
- 定制PCB板
- 连接线
- 电池 5v
构思
用NodeMCU显示时间,用Arduino监测温度;可以选择在每秒钟改变显示的颜色。
迷你LED的额定电压是3.0V到5.5V,16mA(每个LED)。
我们的NodeMCU有3.3V的稳压器,可以正常驱动所有的LED。
第2步:LED WS2812B 3030这里使用了WS2812 NeoPixel Led,它带有集成的IC,这样我们就可以对每段进行单独寻址。不仅LED是可寻址的,而且还可以改变每个像素的颜色(改变0-255(8位值)的数字值)。
LED有4个引脚,此外,这些LED具有数据输入和数据输出功能,通过这些功能,我们可以把它们连接起来,显示文字或数据。
第3步:使用NeoPixel Led制作要制作这个面板,首先我们可以仔细观察一下实际的液晶显示器。这样我们就可以复制段的排列,并为它编写代码。
在上图,各段被命名为A、B、C、D、E、F、G,为了连接所有的段,我们使用串联数据和平行电源的方法:所有的电源线,GND和VCC被并联到所有的LED上;数据输出被提供给串联的下一个LED的数据输入;把第一个面板的Dout连接到第二个面板的Din。
第4步:连接为了连接小时和分钟的面板,我们在两者之间放一个小的PCB板,就是上图中的"Dash"。
第5步:NodeMCU/ESP8266ESP8266集成了一个32位Tensilica处理器,标准的数字外围接口。
ESP8266具有板载Wi-Fi支持,利用它可以通过互联网调整时间而不需要任何RTC(实时时钟)模块。这样减少了连接,可以使整个项目变得更简单一些。
如果你使用下面的代码,那么可以在这个7段时钟中添加两个额外的功能。
第6步:温度和湿度在13号针脚上添加一个DHT11传感器,在12号针脚上添加一个触觉按钮,这样我们就可以在屏幕上获得摄氏或华氏的温度值。
用一个10k电阻将按钮的12号针脚连接到5V,另一端连接到GND。也就是说,当按钮针脚被拉到GND时,显示器将显示温度读数。
如果没有这个温度传感器,代码也可以正常运行,所以如果你想保持尽可能简单的话,可以不需要这些连接。
第7步:亮度控制通过在A0引脚上做一个电阻分压器网络,添加一个带有10k电阻的LDR传感器,可以相应地改变亮度。
白天的亮度高,晚上的亮度低。
如果你不想要可调节的亮度,下面的代码也可以在没有这些传感器的情况下正常运行,它会保持默认设置。
第8步:7段时钟我在EasyEDA中设计了电路,这里使用了3个LED。因此,每块面板总共需要21个LED。
底层做了连接引脚,这样别人就看不到连接和布线了。
CPL、BOM和Gerber文件在GitHub仓库:
https://github.com/halfstudents/ESP8266-Wi-Fi-based-7-Segment-Display-clock
或者也可以在文末打包下载。
第9步:连接使用上面的原理图连接NodeMCU。
这边用到的软件是Cirkit Designer,一个非常不错的软件。
平时你可以在学校演示的时候用这个线图、面包板电路以及创建一些自定义组件。另外,它最近还增加了代码编译、BOM和一些新的元件。
使用Cirkit Designer,我们可以绘制出逼真的电路图,这些电路图与物料清单相连接,这样就可以无缝订购电路中的部件。
Windows、Linux、Mac都可以使用,下载地址:https://www.cirkitstudio.com/download.html
第10步:代码部分- 首先用librarie初始化代码:
#include <ESP8266WiFi.h>
#include <Adafruit_NeoPixel.h>
#include <WiFiUDP.h>
#include <NTPClient.h>
#include <TimeLib.h>
#include <DHT.h>
#include <Adafruit_Sensor.h>
- 定义所有Pixels、I/O引脚、传感器引脚:
#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
- 调整时间,使用Wi-Fi连接互联网到ESP8266:
WiFi.begin(SSID password);
Serial.print("Connecting.");
while ( WiFi.status() != WL_CONNECTED )
- 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)面板显示的颜色设置:
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>
#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 // 5
0b1011111 // 6
0b1110000 // 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;
}
}
第11步:完整电路图
第12步:PCB设计
这是主要的PCB设计,用于显示数字和其他字母。
这个项目涉及到的所有文件,可以在文末打包下载。
第13步:故障处理- “Din”与“Dout”是串联在一起的,如果接反了或从哪里断开了,整个装置就会停止工作。
- 如上图所示,连接“Dash”部分。
- 确保所有的连接都焊接好了,干焊会导致数据值和颜色的改变。
- 在焊接的时候,注意PCB温度不要太高。
原文链接:https://www.instructables.com/ESP8266-Wi-Fi-Based-7-Segment-Display-Clock/
GitHub仓库链接:https://github.com/halfstudents/ESP8266-Wi-Fi-based-7-Segment-Display-clock
译文首发于DF创客社区:https://mc.dfrobot.com.cn/thread-313635-1-1.html
项目作者:sainisagar7294