NodeMcu(ESP8266)+LedControl库实现8x8点阵数字下滑显示

前言

搞32x8的点阵时钟的过程中,想让数字下滑显示,然后搞了两天天终于搞出来,分享给大家!

视频展示

废话不多说,先发一个效果视频。

硬件接线

接线可参考如下接线图(不擅长画图,随便画一画):

代码

这个主要是代码太绕了,脑子转不过来,这个代码主要还是使用了LedControl库,所以理论上只要能用这个库的arduino板子都是可以使用这段代码的(需要简单修改一下)

秉承不重复造轮子的思想(其实是不想自己去摸索),驱动max7219我们使用了LedControl库;这个库默认是没有的, 需要自己到库文件管理中搜索(工具->管理库->搜索LedControl->选第一个);

代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
#include <LedControl.h>

const int DIN = D7;
const int CS = D6;
const int CLK = D5;

// 示例化对象 4:表示4个点阵屏幕
LedControl lc = LedControl(DIN, CLK, CS, 1);


unsigned char templatedata[10][8] = {
{0x0, 0xE0, 0xA0, 0xA0, 0xA0, 0xE0, 0x0, 0x0},// 0
{0x0, 0x40, 0xC0, 0x40, 0x40, 0xE0, 0x0, 0x0},// 1
{0x0, 0xE0, 0x20, 0xE0, 0x80, 0xE0, 0x0, 0x0},// 2
{0x0, 0xE0, 0x20, 0xE0, 0x20, 0xE0, 0x0, 0x0},// 3
{0x0, 0xA0, 0xA0, 0xE0, 0x20, 0x20, 0x0, 0x0},// 4
{0x0, 0xE0, 0x80, 0xE0, 0x20, 0xE0, 0x0, 0x0},// 5
{0x0, 0xE0, 0x80, 0xE0, 0xA0, 0xE0, 0x0, 0x0},// 6
{0x0, 0xE0, 0x20, 0x20, 0x20, 0x20, 0x0, 0x0},// 7
{0x0, 0xE0, 0xA0, 0xE0, 0xA0, 0xE0, 0x0, 0x0},// 8
{0x0, 0xE0, 0xA0, 0xE0, 0x20, 0xE0, 0x0, 0x0}// 9
};

unsigned char writedata[8];

/**
获取需要显示的数字
*/
unsigned char * getshownum(uint8_t nums) {
unsigned char *ten = templatedata[(nums / 10)], *one = templatedata[nums % 10];
unsigned char *arr = new uint8_t [8];
for (int i = 0; i < 8; i++) {
arr[i] = *ten + ((*one & 0xE0) >> 4);
ten++;
one++;
}
return arr;
}

/**
显示数字
*/
void shownum(uint8_t nums) {
unsigned char *xs = getshownum(nums);
for (uint8_t i = 0; i < 8; i++) {
writedata[i] = *xs;
xs++;
}
showLed();
}


/**
初始化写入数据
*/
void inits() {
for (uint8_t j = 0; j < 8; j++) {
writedata[j] = 0x0;
}
}

/**
显示内容
*/
void showLed() {
for (uint8_t i = 0; i < 8; i++) {
lc.setRow(0, i, writedata[i]);
}
}


/**
让数组向下移动
*/
void downMove() {
unsigned char temp = writedata[7];
for (uint8_t k = 7; k > 0; k--) {
writedata[k] = writedata[k - 1];
}
writedata[0] = temp;
showLed();
}


/**
动态显示数字
*/
void sliderNum(uint8_t nums) {
// 保存原来的数字
unsigned char *xs = getshownum(nums);
bool ten = false, one = false;
// 这里的做法待优化,主要是判断个位或者十位部分是否改变,来判断是否需要刷新数字
for (uint8_t j = 0; j < 8; j++) {
// 判断十位部分是否变动
if ((writedata[j] & 0xf0) != (xs[j] & 0xf0)) {
ten = true;
}
// 判断个位部分是否变动
if ((writedata[j] & 0xf) != (xs[j] & 0xf)) {
one = true;
}
}
for (uint8_t i = 0; i < 8; i++) {
if (one) {
// 刷新个位部分数字
slideDown(xs[abs(i - 7)], true);
}
if (ten) {
// 刷线十位部分数字
slideDown(xs[abs(i - 7)], false);
}
showLed();
delay(80);
}
}
/**
刷新数字
*/
void slideDown(unsigned char first, bool isright) {
unsigned char f = isright ? 0xf : 0xf << 4, f1 = isright ? 0xf0 : 0xf0 >> 4;
for (uint8_t k = 7; k > 0; k--) {
writedata[k] = (((writedata[k] & f1) + (writedata[k - 1] & f)) & f) + (writedata[k] & f1);
}
writedata[0] = ((first & f) & f) + (writedata[0] & f1);
}

void setup() {
Serial.begin(115200);
//启用点阵
lc.shutdown(0, false);
// 将亮度设置为最低
lc.setIntensity(0, 1);
// 初始化数组
inits();
shownum(00);
}

void loop() {
for (uint8_t j = 0; j <= 99; j++) {
sliderNum(j);
delay(1000);
}
}

结尾

这里我提供一个8x832x8点阵的在线取模工具,做的比较粗糙,如果有需要改进的地方欢迎在评论区留言。

8x8点阵的在线取模工具
32x8点阵的在线取模工具