这是一款类似 HUD(抬头显示器,又称平视显示器)的时钟,通过 WiFi 获取当前时间。它基于 ESP32 控制器,使用四个常见的 8×8 点阵显示单元,由 MAX7219 芯片驱动。
组件清单- 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_PIN 16 // 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_PIN 16 // 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[8]; // 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[0]), 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[i]);
- }
- 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[4];
- char txt[6] = " : ";
-
- 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[0] = tmtime.tm_hour / 10;
- digit[1] = tmtime.tm_hour % 10;
- digit[2] = tmtime.tm_min / 10;
- digit[3] = tmtime.tm_min % 10;
-
- txt[0] = digit[0] + '0';
- txt[1] = digit[1] + '0';
- txt[3] = digit[2] + '0';
- txt[4] = digit[3] + '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
译文首发于:趣无尽
转载请注明来源信息
|