ESP32 + LED 点阵 DIY 透明面板的数字时钟
这是一款类似 HUD(抬头显示器,又称平视显示器)的时钟,通过 WiFi 获取当前时间。它基于 ESP32 控制器,使用四个常见的 8×8 点阵显示单元,由 MAX7219 芯片驱动。
https://dfrobot.loll.cc/video/HUD-like%20WiFi%20Sync%20Clock%20-%20Transparent%20Dot%20Matrix%20Display.mp4
组件清单
[*]8×8 点阵显示单元(MAX7219)× 4
[*]ESP32 微控制器 × 1
[*]1mm 厚,165 x 75mm 亚克力板 × 1
3D 打印外壳
外壳打印没有支撑,采用丙烯酸板。具体数值为:W=165mm,H=75mm。
最后可使用哑光黑色油漆涂抹外壳。我使用了极低反射率的油漆(MUSOU BLACK),涂满装置和机身的上。
3D 打印文件可以在文末打包下载。
安装 ESP32 微控制器
将 ESP32 微控制器连接到点阵显示单元。将 MAX72XX 库安装到 Arduino IDE 中。
以我的项目为例,连接了 DIN-16、CS-17、CLK-21。源代码中的连接是可变的。可见下文第115-117行。
#define CLK_PIN 21// or SCK
#define DATA_PIN16// or MOSI
#define CS_PIN 17// or SS
在源代码中配置 WiFi。你也可以使用 SmartConfig 智能手机应用程序来执行此操作。
#define WIFI_SSID "SSID" // your WiFi's SSID
#define WIFI_PASS "PASS" // your WiFi's password
将微控制器安装到外壳的外部。当然,你也可以使用任何其他的微控制器。
时钟文件代码可以在文末打包下载。
#include <MD_MAX72xx.h>
#include <SPI.h>
#include <WiFi.h>
//////////////////////////////
// MAX7219 hardware configuration
//////////////////////////////
#define BRIGHTNESS MAX_INTENSITY/2
#define HARDWARE_TYPE MD_MAX72XX::FC16_HW
#define MAX_DEVICES 4
#define CLK_PIN 21// or SCK
#define DATA_PIN16// or MOSI
#define CS_PIN 17// or SS
MD_MAX72XX mx = MD_MAX72XX(HARDWARE_TYPE, DATA_PIN, CLK_PIN, CS_PIN, MAX_DEVICES); // Arbitrary pins
//////////////////////////////
// WiFi and NTP section
//////////////////////////////
// switch between 24H (12 rotors) / 12H (10 rotors)
#define HOUR12 false
// NTP settings
#define TIMEZONE 9 // timezone (GMT = 0, Japan = 9)
#define NTP_SERVER "pool.ntp.org"
#define WIFI_SMARTCONFIG false
#if !WIFI_SMARTCONFIG
// if you do not use smartConfifg, please specify SSID and password here
#define WIFI_SSID "SSID_HERE" // your WiFi's SSID
#define WIFI_PASS "PASS_HERE" // your WiFi's password
#endif
void getNTP(void) {
for(int i = 0; WiFi.status() != WL_CONNECTED; i++) {
if(i > 30) {
ESP.restart();
}
Serial.println("Waiting for WiFi connection..");
delay(1000);
}
configTime(TIMEZONE * 3600L, 0, NTP_SERVER);
printLocalTime();
}
void printLocalTime() {
struct tm timeinfo;
if (!getLocalTime(&timeinfo)) {
Serial.println("Failed to obtain time");
return;
}
Serial.println(&timeinfo, "%A, %Y-%m-%d %H:%M:%S");
}
void wifiSetup() {
int wifiMotion = 400; // while wainting for wifi, large motion
int smatconfigMotion = 100; // while wainting for smartConfig, small motion
WiFi.mode(WIFI_STA);
#if WIFI_SMARTCONFIG
WiFi.begin();
#else
WiFi.begin(WIFI_SSID, WIFI_PASS);
#endif
showText("WiFi..");
for (int i = 0; ; i++) {
Serial.println("Connecting to WiFi...");
delay(1000);
if (WiFi.status() == WL_CONNECTED) {
break;
}
#if WIFI_SMARTCONFIG
if(i > 6)
break;
#endif
}
#if WIFI_SMARTCONFIG
if (WiFi.status() != WL_CONNECTED) {
WiFi.mode(WIFI_AP_STA);
WiFi.beginSmartConfig();
//Wait for SmartConfig packet from mobile
Serial.println("Waiting for SmartConfig.");
while (!WiFi.smartConfigDone()) {
Serial.print(".");
showText("SmCfg");
delay(1000);
mx.clear();
delay(500);
}
Serial.println("");
Serial.println("SmartConfig received.");
//Wait for WiFi to connect to AP
Serial.println("Waiting for WiFi");
showText("WiFi");
while (WiFi.status() != WL_CONNECTED) {
delay(1000);
Serial.print(",");
}
mx.clear();
delay(500);
}
Serial.println("WiFi Connected.");
#endif
Serial.print("SSID: ");
Serial.println(WiFi.SSID());
Serial.print("IP Address: ");
Serial.println(WiFi.localIP());
}
void setup()
{
Serial.begin(115200);
Serial.println("start");
mx.begin();
mx.control(MD_MAX72XX::INTENSITY, BRIGHTNESS);
mx.control(MD_MAX72XX::UPDATE, MD_MAX72XX::ON);
mx.clear();
wifiSetup();
getNTP(); // get current time
}
void showText(char *message) {
char *p = message;
uint8_t charWidth;
uint8_t cBuf;// this should be ok for all built-in fonts
int sum = -2;
mx.clear();
while (*p != '\0') {
charWidth = mx.getChar(*p++, sizeof(cBuf) / sizeof(cBuf), cBuf);
mx.transform(MD_MAX72XX::TSL);
mx.transform(MD_MAX72XX::TSL); // double column space
for (uint8_t i=0; i<charWidth; i++) {
mx.transform(MD_MAX72XX::TSL);
if (i < charWidth)
mx.setColumn(0, cBuf);
}
sum += charWidth + 2;
}
//centering
for(int i = 0; i < (MAX_DEVICES * ROW_SIZE - sum) / 2; i++) {
mx.transform(MD_MAX72XX::TSL);
}
mx.transform(MD_MAX72XX::TFUD); // flip upside down -- for heads up display
}
void loop()
{
static int prevhour = -1;
static int prevMin = -1;
struct tm tmtime;
int digit;
char txt = ":";
getLocalTime(&tmtime);
if(prevMin == tmtime.tm_min)
return;
prevMin = tmtime.tm_min;
#if HOUR12
tmtime.tm_hour %= 12;
if(tmtime.tm_hour == 0)
tmtime.tm_hour = 12;
#endif
digit = tmtime.tm_hour / 10;
digit = tmtime.tm_hour % 10;
digit = tmtime.tm_min / 10;
digit = tmtime.tm_min % 10;
txt = digit + '0';
txt = digit + '0';
txt = digit + '0';
txt = digit + '0';
for(int i = BRIGHTNESS; i >= 0; i--) {
mx.control(MD_MAX72XX::INTENSITY, i);
delay(50);
}
showText(txt);
for(int i = 0; i <= BRIGHTNESS; i++) {
mx.control(MD_MAX72XX::INTENSITY, i);
delay(50);
}
if(tmtime.tm_hour != prevhour) { // get current time via NTP every 6 hours
if(tmtime.tm_hour % 6 == 0)
getNTP();
prevhour = tmtime.tm_hour;
}
}
完成
将显示单元安装到位并插入亚克力板,整个项目就完成了。
原文地址:https://www.instructables.com/HU ... rent-Dot-Matrix-Di/
项目作者:shiura
译文首发于:趣无尽
转载请注明来源信息
大神666{:6_213:}
太神了,欢迎来到自己做不了,别人都能做系列 太厉害了!!! 这个不错,这个点阵是多大的 ? 3mm 吗,如果选更小的,1.9 的,不知效果怎么样呀
我咧个牛逼,我只会买qwq55555555 这个项目我做好了,运行了大半年了,非常好用 点阵屏? 程序烧不进去板里,求助呀!!!!!! !!!!!!!!
页:
[1]