首页 » 排名链接 » 人人都能做的智能网络时钟!ESP8266实践指南(三)(时钟指南能做人人都实践)

人人都能做的智能网络时钟!ESP8266实践指南(三)(时钟指南能做人人都实践)

南宫静远 2024-11-24 12:01:35 0

扫一扫用手机浏览

文章目录 [+]

好多朋友都说想要看网络时钟的制作教程。
那我们今天就来用ESP8266和MAX7219来制作支持炫酷动画效果的网络时钟吧~

接电后,自动联网获取最新的时间,并且还会实时更新时间,分秒不差~

每过一段时间会滚动显示日期~

人人都能做的智能网络时钟!ESP8266实践指南(三)(时钟指南能做人人都实践) 排名链接
(图片来自网络侵删)
一、所需材料ESP8266 NodeMCU开发板,售价低廉,性能强大MAX7219 LED点阵显示屏模块随点阵屏模块赠送的杜邦线等附件

ESP8266: ESP8266是一个非常适合用于物联网和家庭智能项目的wifi模块。
它的售价非常低廉,在某宝上一块ESP8266开发板只要10几块钱

ESP8266的介绍和入门指南可以参见我上次写的这篇文章:十块钱入门物联网!
ESP8266新手指南

MAX7219:MAX7219是一种集成化的串行输入/输出显示驱动器,用它可以在LED点阵屏幕方便地显示你想要的内容。
我买到的是4合1的MAX7219点阵模块,也只需十来块

MAX7219的介绍和入门指南可以参见我上次写的这篇文章:手把手教你用wifi控制显示屏!
ESP8266实践指南(一)

二、配置开发环境

首先参照我上次写的ESP8266新手指南,设置好基本环境:

手把手教你用wifi控制显示屏!
ESP8266实践指南(一)

这里简单概括一下:

安装串口芯片驱动(CH340或者CP2102)安装Arduino IDE安装用于Arduino IDE的ESP8266插件设置开发板型号并选择正确的COM口

三、接线

根据线路图,连接好ESP8266 NodeMCU模块和MAX7219点阵:

3v3 接 VCCGND 接 GNDD5 接 CLKD7 接 DIND8 接 CS

ESP8266与MAX7219接线图, 原图来自于etechpath

实际接线效果如图:

ESP8266与MAX7219接线实物图

四、上传代码

将以下代码贴入Arduino IDE, 并修改wifi名词和密码:

// source code modified from John Rogers @ https://github.com/K1WIZ/ESP8266-8x32-Matrix-clock// copyright@OrangeZero 零度橙子 2020, all rights reserved#include "Arduino.h"#include <ESP8266WiFi.h>WiFiClient client;int day, month, year, dayOfWeek;int summerTime = 0;String date;#define NUM_MAX 4#define DIN_PIN D7#define CS_PIN D8#define CLK_PIN D5#include "max7219.h"#include "fonts.h"#define HOSTNAME "ESP-Clock"// =======================================================================// CHANGE YOUR CONFIG HERE:// 在此处修改你的wifi名称和密码,注意ESP8266只支持2.4Gwifi!// =======================================================================const char ssid = "ssid"; // wifi名称,只支持2.4gconst char password = "password"; // wifi密码void setup() { Serial.begin(115200); initMAX7219(); sendCmdAll(CMD_SHUTDOWN,1); sendCmdAll(CMD_INTENSITY,5); Serial.print("Connecting WiFi "); WiFi.begin(ssid, password); printStringWithShift("Connecting",15); while (WiFi.status() != WL_CONNECTED) { delay(500); Serial.print("."); } Serial.println(""); Serial.print("MyIP: "); Serial.println(WiFi.localIP()); printStringWithShift((String(" MyIP: ")+WiFi.localIP().toString()).c_str(), 15); delay(1500);}// =============================DEFINE VARS==============================#define MAX_DIGITS 20byte dig[MAX_DIGITS]={0};byte digold[MAX_DIGITS]={0};byte digtrans[MAX_DIGITS]={0};int updCnt = 0;int dots = 0;long dotTime = 0;long clkTime = 0;int dx=0;int dy=0;byte del=0;int h,m,s;float utcOffset = +8; // 时区,中国是东八区,保持原样即可。
如果你在海外,需要改成正确的时区。
long localEpoc = 0;long localMillisAtUpdate = 0;// =======================================================================void loop(){ if(updCnt<=0) { // every 10 scrolls, ~450s=7.5m updCnt = 60; Serial.println("Getting data ..."); printStringWithShift(" Setting Time...",15); getTime(); Serial.println("Data loaded"); clkTime = millis(); } if(millis()-clkTime > 60000 && !del && dots) { // clock for 30s, then scrolls for about 30s printStringWithShift(date.c_str(),40); delay(2000); updCnt--; clkTime = millis(); } if(millis()-dotTime > 500) { dotTime = millis(); dots = !dots; } updateTime(); showAnimClock();}// =======================================================================void showSimpleClock(){ dx=dy=0; clr(); showDigit(h/10, 0, dig6x8); showDigit(h%10, 8, dig6x8); showDigit(m/10, 17, dig6x8); showDigit(m%10, 25, dig6x8); showDigit(s/10, 34, dig6x8); showDigit(s%10, 42, dig6x8); setCol(15,dots ? B00100100 : 0); setCol(32,dots ? B00100100 : 0); refreshAll();}// =======================================================================void showAnimClock(){ byte digPos[6]={0,8,17,25,34,42}; int digHt = 12; int num = 6; int i; if(del==0) { del = digHt; for(i=0; i<num; i++) digold[i] = dig[i]; dig[0] = h/10 ? h/10 : 10; dig[1] = h%10; dig[2] = m/10; dig[3] = m%10; dig[4] = s/10; dig[5] = s%10; for(i=0; i<num; i++) digtrans[i] = (dig[i]==digold[i]) ? 0 : digHt; } else del--; clr(); for(i=0; i<num; i++) { if(digtrans[i]==0) { dy=0; showDigit(dig[i], digPos[i], dig6x8); } else { dy = digHt-digtrans[i]; showDigit(digold[i], digPos[i], dig6x8); dy = -digtrans[i]; showDigit(dig[i], digPos[i], dig6x8); digtrans[i]--; } } dy=0; setCol(15,dots ? B00100100 : 0); setCol(32,dots ? B00100100 : 0); refreshAll(); delay(30);}// =======================================================================void showDigit(char ch, int col, const uint8_t data){ if(dy<-8 | dy>8) return; int len = pgm_read_byte(data); int w = pgm_read_byte(data + 1 + ch len); col += dx; for (int i = 0; i < w; i++) if(col+i>=0 && col+i<8NUM_MAX) { byte v = pgm_read_byte(data + 1 + ch len + 1 + i); if(!dy) scr[col + i] = v; else scr[col + i] |= dy>0 ? v>>dy : v<<-dy; }}// =======================================================================void setCol(int col, byte v){ if(dy<-8 | dy>8) return; col += dx; if(col>=0 && col<8NUM_MAX) if(!dy) scr[col] = v; else scr[col] |= dy>0 ? v>>dy : v<<-dy;}// =======================================================================int showChar(char ch, const uint8_t data){ int len = pgm_read_byte(data); int i,w = pgm_read_byte(data + 1 + ch len); for (i = 0; i < w; i++) scr[NUM_MAX8 + i] = pgm_read_byte(data + 1 + ch len + 1 + i); scr[NUM_MAX8 + i] = 0; return w;}// =======================================================================int dualChar = 0;unsigned char convertPolish(unsigned char _c){ unsigned char c = _c; if(c==196 || c==197 || c==195) { dualChar = c; return 0; } if(dualChar) { switch(_c) { case 133: c = 1+'~'; break; // 'ą' case 135: c = 2+'~'; break; // 'ć' case 153: c = 3+'~'; break; // 'ę' case 130: c = 4+'~'; break; // 'ł' case 132: c = dualChar==197 ? 5+'~' : 10+'~'; break; // 'ń' and 'Ą' case 179: c = 6+'~'; break; // 'ó' case 155: c = 7+'~'; break; // 'ś' case 186: c = 8+'~'; break; // 'ź' case 188: c = 9+'~'; break; // 'ż' //case 132: c = 10+'~'; break; // 'Ą' case 134: c = 11+'~'; break; // 'Ć' case 152: c = 12+'~'; break; // 'Ę' case 129: c = 13+'~'; break; // 'Ł' case 131: c = 14+'~'; break; // 'Ń' case 147: c = 15+'~'; break; // 'Ó' case 154: c = 16+'~'; break; // 'Ś' case 185: c = 17+'~'; break; // 'Ź' case 187: c = 18+'~'; break; // 'Ż' default: break; } dualChar = 0; return c; } switch(_c) { case 185: c = 1+'~'; break; case 230: c = 2+'~'; break; case 234: c = 3+'~'; break; case 179: c = 4+'~'; break; case 241: c = 5+'~'; break; case 243: c = 6+'~'; break; case 156: c = 7+'~'; break; case 159: c = 8+'~'; break; case 191: c = 9+'~'; break; case 165: c = 10+'~'; break; case 198: c = 11+'~'; break; case 202: c = 12+'~'; break; case 163: c = 13+'~'; break; case 209: c = 14+'~'; break; case 211: c = 15+'~'; break; case 140: c = 16+'~'; break; case 143: c = 17+'~'; break; case 175: c = 18+'~'; break; default: break; } return c;}// =======================================================================void printCharWithShift(unsigned char c, int shiftDelay) { c = convertPolish(c); if (c < ' ' || c > '~'+25) return; c -= 32; int w = showChar(c, font); for (int i=0; i<w+1; i++) { delay(shiftDelay); scrollLeft(); refreshAll(); }}// =======================================================================void printStringWithShift(const char s, int shiftDelay){ while (s) { printCharWithShift(s, shiftDelay); s++; }}// =======================================================================void getTime(){ WiFiClient client; if (!client.connect("www.baidu.com", 80)) { Serial.println("connection to baidu failed"); return; } client.print(String("GET / HTTP/1.1\r\n") + String("Host: www.baidu.com\r\n") + String("Connection: close\r\n\r\n")); int repeatCounter = 0; while (!client.available() && repeatCounter < 10) { delay(500); //Serial.println("."); repeatCounter++; } String line; client.setNoDelay(false); while(client.connected() && client.available()) { line = client.readStringUntil('\n'); line.toUpperCase(); if (line.startsWith("DATE: ")) { date = " "+line.substring(6, 22); date.toUpperCase();// decodeDate(date); h = line.substring(23, 25).toInt(); m = line.substring(26, 28).toInt(); s = line.substring(29, 31).toInt(); summerTime = checkSummerTime(); if(h+utcOffset+summerTime>23) { if(++day>31) { day=1; month++; }; // needs better patch if(++dayOfWeek>7) dayOfWeek=1; } localMillisAtUpdate = millis(); localEpoc = (h 60 60 + m 60 + s); } } client.stop();}// =======================================================================int checkSummerTime(){ if(month>3 && month<10) return 1; if(month==3 && day>=31-(((5year/4)+4)%7) ) return 1; if(month==10 && day<31-(((5year/4)+1)%7) ) return 1; return 0;}// =======================================================================// =======================================================================void updateTime(){ long curEpoch = localEpoc + ((millis() - localMillisAtUpdate) / 1000); long epoch = int( curEpoch + 3600 ( utcOffset + summerTime ) + 86400L ) % 86400L; h = ((epoch % 86400L) / 3600) % 24; m = (epoch % 3600) / 60; s = epoch % 60;}// =======================================================================

点击按钮,上传代码到ESP8266:

稍等片刻,上传完成,屏幕开始显示信息,待时间获取成功后,我们的网络时钟就完成啦~

只要用USB线接上一个充电宝,就可以把他放在任意位置当一个真正的时钟啦~

默认显示时间,每隔一小会儿,会滚动显示日期。
在时间变幻的时候,还有翻页效果~

大家有没有觉得一点都不难,而且成就感满满呢~

大家有什么还有什么想要做的物联网或者智能家居项目呢?在下面留言告诉我吧~

我是零度橙子,科技达人,谷歌认证云计算架构师,AWS认证devops专家,大家可以关注我,了解有用有趣的科技知识~

标签:

相关文章