資料介紹
描述
在這個項目中,時間、日期和最新的頭條新聞將在 LED 矩陣上顯示為自動收報機。日期和時間將從時間服務器更新。標題來自所謂的 RSS 提要。這是由各種網絡服務器提供的服務,例如 tagesschau.de。此服務使用 http 或 https 作為傳輸協議,但數據不是像往常一樣以 HTML 格式提供,而是以 XML 格式提供,即沒有布局信息。
電路
LED 矩陣僅連接到 ESP32 的 SPI 總線。ESP32 MOSI (GPIO23) 的數據輸出連接到矩陣的 DIN。ESP32 CLK (GPIO19) 的時鐘輸出連接到矩陣的時鐘輸入。ESP32的GPIO16用作片選,連接到矩陣的CS連接器。矩陣由 5V 供電,這對 ESP32 沒有問題,因為這里使用的所有連接器都用作輸出,因此無法從矩陣獲得更高的電壓。
程序
除了 ESP32 包之外,您還需要四個庫。我們使用 TinyXML 庫從接收到的 XML 數據中提取所需的信息。圖書館只有三個功能。
void init (uint8_t* buffer, uint16_t maxbuflen, XMLcallback XMLcb); 該函數在設置函數中被調用。參數buffer指向一個存放臨時數據的字節數組,參數maxbuflen指定了緩沖區的大小。參數 XMLcallback 指向一個回調函數
void XML_callback(uint8_t statusflags, char* tagName, uint16_t tagNameLen, char* data, uint16_t dataLen)
只要 XML 元素已被完全處理,就會調用它。statusflags 參數指定提供哪些數據。由于我們對 XML 標記的內容感興趣,因此我們將只使用狀態 STATUS_TAG_TEXT。tagName 參數指向包含項目完整 XML 路徑的字符數組。對于新聞源項目的標題,這是路徑“/rss/channel/item/title”。tagNameLen 參數返回路徑的長度。參數數據還指向包含數據的字符數組。最后一個參數 dataLen 返回數據數組的大小。
無效重置();此函數重置所有內部指針。它應該總是在讀入新的 XML 數據之前被調用。
void processChar(uint8_t ch); 此函數將要處理的 XML 數據的一個字符發送到 XML 解析器。必須為接收到的每個字符順序調用此函數。如果傳輸的字符導致 XML 塊的完成,則使用相應的數據調用回調函數。LG_Matrix_Print 庫用于在 LED 矩陣上顯示字符串。草圖中使用了以下函數:void setEnabled(bool enabled); ?啟用或禁用對 LED 矩陣的訪問。
void setIntensity(uint8_t level); 此功能更改顯示屏的亮度。允許使用 0 到 15 之間的值。通常1就足夠了
無效顯示();顯示存儲器的內容被傳輸到矩陣并因此可見。
void clear()清除顯示內存。
int printText(int start, String text, boolean isUTF8 = true); 此函數使用內部字符集將文本參數中指定的字符串(從第 n 個字符開始)轉換為顯存中相應的位模式。輸出開始的字符在 start 參數中指定。可選參數 isUTF8 打開或關閉內部代碼轉換器。
void ticker(字符串消息,uint16_t 等待);這個函數可以很容易地實現一個自動收報機。參數 message 指向包含要顯示的文本的字符串。第二個參數 wait 指定在文本前進一個像素之前等待的時間(以毫秒為單位)。圖書館負責其他一切。
布爾更新代碼();必須在循環函數中調用此函數以更新代碼。
該庫包含其他功能,但在此草圖中未使用它們。WebConfig 庫用于通過瀏覽器配置 WLAN 訪問數據以及其他設置。配置存儲在閃存文件系統 SPIFFS 中,即使在微控制器關閉后也會保留。詳細說明可以在:? https? ://github.com/GerLech/WebConfig/blob/master/README.md或在我的書Smarthome 中找到。
WebConfig 庫需要 Arduino_JSON 庫,因此也必須安裝它,但未包含在草圖中。
草圖
#include //Bibliothek für die Matrixanzeige
#include
//Web Client für den Empfang des RSS-Feeds
#include //Filesystem zum Speichern der Konfiguration
#include //Webserver für die Konfiguration
#include //Multicast DNS für Namensaufl?sung
#include
//Bibliothek zur Konfiguration über eine Webseite
#include //XML-Interpreter zum Lesen des RSS-Feed
#define LEDMATRIX_CS_PIN 16 //CS Pin der LED Matrix
// Anzahl der 8x8 LED Segmente
#define LEDMATRIX_SEGMENTS 4
// Timeout zum Lesen des RSS-Feed in Sekunden
#define READ_TIMEOUT 10
//Prameter für das Konfigurations-Formular
String params = "["
"{"
"'name':'ssid',"
"'label':'Name des WLAN',""'type':"+String(INPUTTEXT)+","
"'default':''"
"},"
"{"
"'name':'pwd',"
"'label':'WLAN Passwort',"
"'type':"+String(INPUTPASSWORD)+","
"'default':''"
"},"
"{"
"'name':'rssUrl',"
"'label':'RSS Feed URL',"
"'type':"+String(INPUTTEXT)+","
"'default':''"
"},"
"{"
"'name':'ntp',"
"'label':'NTP Server',"
"'type':"+String(INPUTTEXT)+","
"'default':'de.pool.ntp.org'"
"},"
"{"
"'name':'maxNews',"
"'label':'Schlagzeilen',"
"'type':"+String(INPUTNUMBER)+","
"'min':1,'max':10,"
"'default':'1'"
"},"
"{"
"'name':'intens',"
"'label':'Helligkeit',"
"'type':"+String(INPUTNUMBER)+","
"'min':1,'max':15,"
"'default':'1'"
"},"
"{"
"'name':'disptime',"
"'label':'Anzeigedauer (s)',"
"'type':"+String(INPUTNUMBER)+","
"'min':1,'max':30,"
"'default':'5'"
"}"
"]";
//Web Server Instanz
WebServer server;
//Web Konfigurations Instanz
WebConfig conf;
//LED Matrix Instanz
LG_Matrix_Print lmd(LEDMATRIX_SEGMENTS, LEDMATRIX_CS_PIN);
//XML Interpreter Instanz
TinyXML xml;
//Globale Variablen
uint32_t last = 0; //Zeit der letzten Aktion in ms
uint8_t buffer[2000]; //Buffer für XML-Interpreter
String news[10]; //Speicher für Nachrichten (Max. 10)
uint8_t newsCnt = 0; //Anzahl der aktuellen Nachrichten im Speicher
uint8_t curNews = 0; //Index der gerade angezeigten Nachricht
uint8_t dispMode = 0; //Art der Anzeige 0=Zeit, 1=Datum, 2=News;
//Diese Funktion wird vom XML-Interpreter aufgerufen,
//wenn ein XML-Tag gelesen wurde
//tagName enth?lt den vollst?ndigen XML-Pfad des Tags,
//data den Inhalt des Tags
void XML_callback(uint8_t statusflags, char* tagName, uint16_t tagNameLen, char* data, uint16_t dataLen) {
if (statusflags & STATUS_TAG_TEXT) {
//Serial.println(tagName);
//wenn wir einen Titel-Tag finden,
//und die maximale Anzahl der Meldungen noch
//nicht erreicht ist, wird die Meldung gespeichert
//und der Z?hler erh?ht
if (strcasecmp(tagName,"/rss/channel/item/title")==0) {
data[dataLen] = '\0';
if (newsCnt < conf.getInt("maxNews")) {
//Die maximale Anzahl der Nachrichten wird
//aus der Konfiguration gelesen
news[newsCnt] = data;
newsCnt++;
}
}
}
}
//WLAN Verbindung initialisieren
boolean initWiFi() {
boolean connected = false;
WiFi.mode(WIFI_STA);
Serial.print("Verbindung zu ");
Serial.print(conf.values[0]);
Serial.println(" herstellen");
if (conf.values[0] != "") {
//wenn eine SSID bekannt ist,
//wird versucht eine Verbindung herzustellen
WiFi.begin(conf.values[0].c_str(),conf.values[1].c_str());
uint8_t cnt = 0;
while ((WiFi.status() != WL_CONNECTED) && (cnt<20)){
delay(500);
Serial.print(".");
cnt++;
}
Serial.println();
if (WiFi.status() == WL_CONNECTED) {
Serial.print("IP-Adresse = ");
Serial.println(WiFi.localIP());
connected = true;
}
}
//konnte keine Verbindung hergestellt werden,
//wird ein Accesspoint gestartet
//der Accesspoint hat kein Passwort. über die IP-Adresse
//192.168.4.1 kann?die Konfiguration durchgeführt werden
if (!connected) {
WiFi.mode(WIFI_AP);
WiFi.softAP(conf.getApName(),"",1);
}
return connected;
}
//Diese Funktion wird aufgerufen,
//wenn der Webserver eine Anfrage erh?lt
void handleRoot() {
//Die Anfrage wird an die Konfigurationsinstanz weitergegeben
conf.handleFormRequest(&server);
}
//Neue Nachrichten vom RSS-Feed lesen
void getNews() {
String error = "";
if(WiFi.status()== WL_CONNECTED){
//HTTP Client
HTTPClient http;
Serial.print("[HTTP] begin...\n");
//url aus der Konfiguration
http.begin(conf.getValue("rssUrl"));
Serial.print("[HTTP] GET...\n");
// Anfrage abschicken
int httpCode = http.GET();
// httpCode ist im Fall eines Fehlers negativ
if(httpCode > 0) {
// HTTP Antwort vom Server erhalten
Serial.printf("[HTTP] GET... code: %d\n", httpCode);
if(httpCode == HTTP_CODE_OK) {
String payload = http.getString();
xml.reset();
for (uint16_t i=0; i.length(); i++) xml.processChar(payload[i]);
}
else{
error = "Server antwortet mit "+String(httpCode);
}
} else {
error = "Server antwortet mit "+http.errorToString(httpCode);
}
http.end();
if (newsCnt > 0) {
//Falls Nachrichten empfangen wurden,
//wird die erste Nachricht angezeigt
curNews = 0;
lmd.ticker(news[0],100);
}
} else {
initWiFi();
error = "Keine Internetverbindung!";
}
if (error != "") {
news[0] = error;
newsCnt = 1;
curNews = 0;
lmd.ticker(news[0],100);
}
}
//Die aktuelle Uhrzeit wird angezeigt wenn start wahr ist
void showTime(boolean start){
if (start) {
Serial.println("Time Start");
last = millis();
char sttime[10];
struct tm timeinfo;
dispMode=0;
if(getLocalTime(&timeinfo)){
strftime(sttime, sizeof(sttime), "%H:%M ", &timeinfo);
lmd.printText(0,String(sttime));
lmd.display();
} else {
//liefert die RTC keine Werte so wird ??:?? angezeigt
lmd.printText(0,"??:?? ");
lmd.display();
}
} else {
//Wenn das Ende der Anzeigedauer erreicht wurde,
//wird auf Datum umgeschaltet
if ((millis()-last) > (conf.getInt("disptime")*1000)) {
showDate(true);
}
}
}
//Das aktuelle Datum wird angezeigt wenn start wahr ist
void showDate(boolean start) {
if (start) {
Serial.println("Date Start");
last = millis();
char sttime[10];
struct tm timeinfo;
dispMode = 1;
if(getLocalTime(&timeinfo)){
strftime(sttime, sizeof(sttime), "%d.%b ", &timeinfo);
lmd.printText(0,String(sttime));
lmd.display();
} else {
//liefert die RTC keine Werte so wird ??.??? angezeigt
lmd.printText(0,"??.???");
lmd.display();
}
} else {
//Wenn das Ende der Anzeigedauer erreicht wurde,
//wird auf News umgeschaltet
if ((millis()-last) > (conf.getInt("disptime")*1000)) {
showNews(true);
}
}
}
//Eine Nachricht wird angezeigt wenn start wahr ist
//werden Nachrichten?vom Server geholt und
//die erste Nachricht angezeigt sonst die n?chste
void showNews(boolean start) {
if (start) {
Serial.println("News Start");
if (curNews == 0) {
getNews();
} else {
lmd.ticker(news[curNews],100);
}
dispMode = 2;
} else {
//der Ticker wird aktualisiert. Wenn das Ende der Nachricht erreicht
//wurde wird auf die n?chste Nachricht weitergeschaltet.
//Die Anzeige?wird auf Zeitanzeige umgeschaltet
if (!lmd.updateTicker()) {
curNews++;
if (curNews >= newsCnt) curNews = 0;
showTime(true);
}
}
}
//Wird einmal beim Start des Programms ausgeführt
void setup() {
//Filesystem initialisieren und
//falls noch nicht geschehen, formatieren
SPIFFS.begin(true);
//Serielle Schnittstelle starten
Serial.begin(115200);
//XML-Interpreter initialisieren
xml.init((uint8_t *)buffer, sizeof(buffer), &XML_callback);
//Formular zur Webkonfiguration vorbereiten
conf.setDescription(params);
//Konfiguration falls vorhanden aus dem Filesystem lesen
conf.readConfig();
// Anzeige initialisieren
lmd.setEnabled(true);
lmd.setIntensity(conf.getInt("intens")); // 0 = low, 10 = high
lmd.clear();
lmd.display();
//WLAN Verbindung herstellen
initWiFi();
//Multicast DNS starten
char dns[30];
sprintf(dns,"%s.local",conf.getApName());
if (MDNS.begin(dns)) {
Serial.println("MDNS responder gestartet");
}
//Webserver starten
server.on("/",handleRoot);
server.begin(80);
delay(1000);
//Wenn eine Internetvebindung besteht, die Echtzeituhr des ESP32
//mit Daten vom Zeitserver starten
if (WiFi.status()== WL_CONNECTED) configTzTime("CET-1CEST,M3.5.0/03,M10.5.0/03", conf.getValue("ntp"));
showTime(true);
}
void loop() {
if (millis() < last) last=millis();
//falls ein überlauf auftrat nach etwa 50 Tagen
//Anfragen des Webserver behandeln
server.handleClient();
//Anzeige aktualisieren
switch (dispMode) {
case 0: showTime(false); break;
case 1: showDate(false); break;
case 2: showNews(false); break;
}
}
啟動后,程序還不能與WLAN建立連接。因此,接入點被啟動。它的 SSID 是 ESP32 的 MAC 地址。在智能手機的 WLAN 設置中,您應該會看到 SSID。您現在可以選擇此網絡并連接到它。網絡不需要密碼。智能手機可能會報告無法連接互聯網,以及您是否要保留所選網絡。在這種情況下,點擊 Keep。< pan>
現在您可以啟動瀏覽器并調用 URL 192.168.4.1。矩陣時鐘的配置頁面應該會出現。
接入點的名稱是 MAC 地址,可以根據需要進行更改。隨后是 WLAN 的訪問數據。例如,對于 RSS 提要的 URL,您可NTP 服務器可以保持原樣。但是您也可以設置例如帶有 fritz.box 的 Fritzbox。接下來,您必須設置標題的最大數量、顯示屏的亮度和以秒為單位的時間,時間和日期應顯示多長時間。最后點擊保存并重新啟動。矩陣時鐘將重新啟動,現在應該連接到 WLAN。在串行監視器的輸出中,您可以跟隨登錄。然后可以通過路由器分配給矩陣時鐘的 IP 地址訪問配置頁面。
安裝在外殼中
那些擁有 3D 打印機的人可以打印出合適的房屋。一共需要四個部分。一個底部部件 Uhr_unterten.stl,一個蓋子 Uhr_deckel.stl 和兩個顯示器支架 Uhr_halter.stl。現在到大會。首先,面包板配有兩個母連接器和一個帶角度的公連接器。< pan>
下面的接線是在后面板上進行的。
現在您可以將控制器插入母連接器,并通過 5 針電纜將矩陣與控制器連接起來。在這里你必須注意引腳的正確順序。插入后,是時候再次檢查所有內容并在開始安裝之前進行試運行了。
下一步是在外殼中安裝矩陣和面包板。為了連接矩陣,必須首先將兩個支架連接到矩陣。
現在您可以將矩陣固定在蓋子上,將面包板固定在底座上。< pan>
就是這樣了。帶有新聞提要的矩陣時鐘已準備就緒
玩得開心。
?
- Haiku eInk閱讀器開源分享
- 模擬閱讀器開源分享
- 基于鴻蒙系統的ZBar條形碼閱讀器教程 11次下載
- 電子閱讀器的電路原理圖免費下載 49次下載
- Python簡歷樣本—模擬儀表閱讀器下載 1次下載
- 基于圖論的閱讀器防碰撞算法 1次下載
- PDF閱讀器AcroRd32軟件 22次下載
- 身份證閱讀器SDK使用手冊 23次下載
- Flash單片機原理(請用超星閱讀器閱讀) 5次下載
- 超星閱讀器免費下載 19次下載
- 基于S1D13521的電子紙閱讀器的設計 129次下載
- PDF閱讀器綠色版 0次下載
- 基于S6700的閱讀器的設計與實現
- txt文檔閱讀器
- djvu閱讀器下載
- 手搓了一個ESP32墨水屏閱讀器,蠻簡單的 331次閱讀
- 基于XIAO的翻頁顯示器設計 504次閱讀
- 工業顯示器和普通顯示器的區別 4945次閱讀
- 基于鉆井深度顯示器和帶有Arduino支持的7段顯示器設計 2480次閱讀
- ZigBee模塊在RFID射頻識別閱讀器中有著怎樣的作用 2689次閱讀
- 數字顯示器的工作原理_數字顯示器電路圖 3w次閱讀
- 顯示器上的眾多接口你都了解嗎 6702次閱讀
- 采用LabVIEW圖形化編程語言設計的基于軟件無線電的RFID閱讀器 2226次閱讀
- 電腦硬件基礎篇顯示器(顯示器工作原理及作用_特性參數及型號和位置) 3.1w次閱讀
- 液晶顯示器的優缺點_液晶顯示器原理介紹 1.5w次閱讀
- 平視顯示器是什么_平視顯示器原理_平視顯示器類型 4031次閱讀
- 顯示器色溫怎么調節 2.1w次閱讀
- 采用新型集成元件來簡化RFID閱讀器設計 1083次閱讀
- 基于ISO18000-6C協議的UHF RFID閱讀器接收電路設計 3772次閱讀
- AMOLED顯示器電源所需IC簡述 5750次閱讀
下載排行
本周
- 1山景DSP芯片AP8248A2數據手冊
- 1.06 MB | 532次下載 | 免費
- 2RK3399完整板原理圖(支持平板,盒子VR)
- 3.28 MB | 339次下載 | 免費
- 3TC358743XBG評估板參考手冊
- 1.36 MB | 330次下載 | 免費
- 4DFM軟件使用教程
- 0.84 MB | 295次下載 | 免費
- 5元宇宙深度解析—未來的未來-風口還是泡沫
- 6.40 MB | 227次下載 | 免費
- 6迪文DGUS開發指南
- 31.67 MB | 194次下載 | 免費
- 7元宇宙底層硬件系列報告
- 13.42 MB | 182次下載 | 免費
- 8FP5207XR-G1中文應用手冊
- 1.09 MB | 178次下載 | 免費
本月
- 1OrCAD10.5下載OrCAD10.5中文版軟件
- 0.00 MB | 234315次下載 | 免費
- 2555集成電路應用800例(新編版)
- 0.00 MB | 33566次下載 | 免費
- 3接口電路圖大全
- 未知 | 30323次下載 | 免費
- 4開關電源設計實例指南
- 未知 | 21549次下載 | 免費
- 5電氣工程師手冊免費下載(新編第二版pdf電子書)
- 0.00 MB | 15349次下載 | 免費
- 6數字電路基礎pdf(下載)
- 未知 | 13750次下載 | 免費
- 7電子制作實例集錦 下載
- 未知 | 8113次下載 | 免費
- 8《LED驅動電路設計》 溫德爾著
- 0.00 MB | 6656次下載 | 免費
總榜
- 1matlab軟件下載入口
- 未知 | 935054次下載 | 免費
- 2protel99se軟件下載(可英文版轉中文版)
- 78.1 MB | 537798次下載 | 免費
- 3MATLAB 7.1 下載 (含軟件介紹)
- 未知 | 420027次下載 | 免費
- 4OrCAD10.5下載OrCAD10.5中文版軟件
- 0.00 MB | 234315次下載 | 免費
- 5Altium DXP2002下載入口
- 未知 | 233046次下載 | 免費
- 6電路仿真軟件multisim 10.0免費下載
- 340992 | 191187次下載 | 免費
- 7十天學會AVR單片機與C語言視頻教程 下載
- 158M | 183279次下載 | 免費
- 8proe5.0野火版下載(中文版免費下載)
- 未知 | 138040次下載 | 免費
評論
查看更多