NodeMCU(ESP8266)使用UDP控制8x8点阵显示
前言
之前写一篇关于 Arduino Max7219 案例,展示如何使用arduino+Max7219控制8x8点阵显示内容。最近恰好在搞esp8266,所以想用(esp8266+8x8点阵)做一个时钟出来, 但是无奈当时就只有一个8x8的点阵,做时钟需要一个32x8的点阵;所以就先拿这个8x8点阵试试效果。众所周知搞点阵显示是需要取模的, 但是取模毕竟是程序上的效果,并非真实的显示效果,所以我就在想为啥不能用手机来控制点阵取模, 直接就能看到效果,不满意还能直接改不用每次都写入到程序中去,说干就干。
视频展示
废话不多说,先发一个效果视频。
原理
其实原理比较简单;
- ESP8266连接上WiFi,然后开启UDP服务,端口为1234
- 在同一路由器的网络下,用户通过微信小程序向esp8266广播数据
- esp8266接收到数据以后就向Max7219点阵中写入数据
硬件部分
关于MAX7219 和8x8点阵 的介绍我就不搬运了,大家有兴趣可以参考这篇文章,写的比较详细:
Arduino 学习笔记 | 单片机控制驱动MAX7219 8*8 LED点阵显示模块
WIFI UPD库函数啥的可以参考这篇(里面包括UDP协议的介绍): 太极创客 ESP8266 – WiFiUDP库
硬件接线
接线可参考如下接线图(不擅长画图,随便画一画):
代码
秉承不重复造轮子的思想(其实是不想自己去摸索),驱动max7219我们使用了LedControl 库;这个库默认是没有的, 需要自己到库文件管理中搜索(工具->管理库->搜索LedControl->选第一个 );
代码:
#include <ESP8266WiFi.h>
#include <WiFiUdp.h>
#include <LedControl.h>
#define ssid "WiFi名称"
#define password "WiFi密码"
#define upd_port 1234
int DIN = D7;
int CS = D6;
int CLK = D5;
LedControl lc = LedControl(DIN, CLK, CS, 1);
WiFiUDP Udp;
byte wifiicon[8] = {0x3C, 0x42, 0x99, 0x24, 0x42, 0x18, 0x0, 0x18};
byte packetBuffer[9];
void setup() {
Serial.begin(115200);
lc.shutdown(0, false);
lc.setIntensity(0, 8);
lc.clearDisplay(0);
show(wifiicon);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(5000);
}
Serial.println("连接成功");
if (Udp.begin(upd_port)) {
Serial.println("监听成功");
Serial.printf("现在收听IP:%s, UDP端口:%d\n", WiFi.localIP().toString().c_str(), upd_port);
} else {
Serial.println("监听失败");
}
animation();
lc.clearDisplay(0);
}
void loop() {
int packetSize = Udp.parsePacket();
if (packetSize) {
Serial.printf("收到来自远程IP:%s(远程端口:%d)的数据包字节数:%d\n", Udp.remoteIP().toString().c_str(), Udp.remotePort(), packetSize);
Udp.read(packetBuffer, 9);
if (packetBuffer[8] == 0xef) {
show(packetBuffer);
Udp.beginPacket(Udp.remoteIP(), Udp.remotePort());
char replyPacket[1] = {0x01};
Udp.write(replyPacket);
Udp.endPacket();
}
}
}
void show(byte *data) {
for (int i = 0; i < 8; i++) {
lc.setRow(0, i, data[i]);
}
}
void animation() {
byte temp[64][8];
int a = 0x1, b = 0x00, fx = 0x00;
for (int i = 0; i < 64; i++) {
if (b == 0xff || b == 0x00) {
fx = fx == 0x00 ? 0x01 : 0x00;
a = fx == 0x00 ? 0x1 : 0x80;
b = 0x00;
} else {
a = fx == 0x00 ? (a << 0x1) : (a >> 0x1) ;
}
b += a | 0x00;
for (int j = 0; j <= 8; j++) {
if (j == i / 8) {
temp[i][i / 8] = (byte)b;
} else if (j < i / 8) {
temp[i][j] = (byte)0xff;
} else {
temp[i][j] = (byte)0x00;
}
}
}
for (int i = 0; i < 64; i++) {
for (int j = 0; j < 8; j++) {
lc.setRow(0, j, temp[i][j]);
delay(10);
}
}
}
微信小程序
为了方便操作,这里我们直接使用微信小程序来控制。
结尾
这里我提供一个8x8点阵的在线取模工具,做的比较粗糙,如果有需要改进的地方欢迎在评论区留言。
8x8点阵的在线取模工具
参考文章
Arduino Max7219 案例
太极创客 ESP8266 – WiFiUDP库
Arduino 学习笔记 | 单片机控制驱动MAX7219 8*8 LED点阵显示模块
|