arduino之16*16点阵庆祝祖国70周年
之前电脑上存了很多自己写的关于arduino的有趣的小demo,因为重装了系统,不小心误删了所有的文件(气的半死),所以现在准备一有空就重写一下之前写过的东东,顺带再温习一次,这次总不能再删了吧,嘿嘿。
这次主要想记录一下点阵的使用,方便以后查阅,也分享出来和伙伴们一起学习进步。这次在代码中,用的最多的就是指针的使用,就当回顾知识点了。
用到的材料:一个16*16点阵(由4块8*8的led点阵组成的),arduino的uno。
用到的库文件:LedControl.h ,因为点阵是使用的max7219,这个库很不错。
先看看效果,下面是视频链接:
下面直接上代码,有兴趣的小伙伴可以玩玩。
#include <LedControl.h>
const int DIN = ;
const int CLK = ;
const int CS = ;
int maxLen;//字的总个数
int row;//纵向移动数组的行数
int col;//横向移动数组的列数
//自定义函数
void showWordByArr(LedControl led, byte[][]); //通过数组显示
void showWordByPtr(LedControl led, byte(*word)[]); //通过数组指针显示
void showWords(LedControl led, byte(*words)[][]); //显示一组文字
void showTopMoveWords(LedControl led, byte(*words)[][]); //向上移动显示文字
void showLeftMoveWords(LedControl led, byte(*words)[][]); //向左移动显示文字 //初始化对象,每个对象最多可以操作8个设备(超过8个设备就再创建一个对象)。
LedControl led = LedControl(DIN, CLK, CS , );//我这里是4块8*8的led点阵,所以设备数量填4(最大为8)。
byte a[][] = //实心五角星
{
0x01, 0x00, //第一,二个设备
0x01, 0x00,
0x03, 0x80,
0x03, 0x80,
0x03, 0x80,
0x07, 0xC0,
0xFF, 0xFE,
0x7F, 0xFC,
0x3F, 0xF8, //第三,四个设备
0x0F, 0xE0,
0x0F, 0xE0,
0x1F, 0xF0,
0x1E, 0xF0,
0x18, 0x30,
0x20, 0x08,
0x00, 0x00
};
byte b[][] = //空心五角星
{
0x01, 0x00, 0x01, 0x00, 0x02, 0x80, 0x02, 0x80, 0x02, 0x80, 0x04, 0x40, 0xFC, 0x7E, 0x40, 0x04,
0x30, 0x18, 0x08, 0x20, 0x08, 0x20, 0x11, 0x90, 0x16, 0x50, 0x18, 0x30, 0x20, 0x08, 0x00, 0x00
};
byte c[][] = //空心取反
{
0xFE, 0xFF, 0xFE, 0xFF, 0xFC, 0x7F, 0xFC, 0x7F, 0xFC, 0x7F, 0xF8, 0x3F, 0x00, 0x01, 0x80, 0x03,
0xC0, 0x07, 0xF0, 0x1F, 0xF0, 0x1F, 0xE0, 0x0F, 0xE1, 0x0F, 0xE7, 0xCF, 0xDF, 0xF7, 0xFF, 0xFF
}; byte topWords[][][] = //庆祝祖国70周年
{
{0x00},
{
0x01, 0x00, 0x00, 0x80, 0x3F, 0xFE, 0x20, 0x00, 0x20, 0x80, 0x20, 0x80, 0x20, 0x80, 0x2F, 0xFC,
0x20, 0x80, 0x21, 0x40, 0x21, 0x40, 0x22, 0x20, 0x42, 0x20, 0x44, 0x10, 0x88, 0x08, 0x10, 0x06
},
{
0x20, 0x00, 0x13, 0xFC, 0x12, 0x04, 0xFA, 0x04, 0x0A, 0x04, 0x12, 0x04, 0x13, 0xFC, 0x38, 0x90,
0x54, 0x90, 0x94, 0x90, 0x10, 0x90, 0x11, 0x12, 0x11, 0x12, 0x12, 0x12, 0x14, 0x0E, 0x18, 0x00
},
{
0x20, 0x00, 0x11, 0xF8, 0x11, 0x08, 0xF9, 0x08, 0x09, 0x08, 0x11, 0xF8, 0x11, 0x08, 0x39, 0x08,
0x55, 0x08, 0x95, 0xF8, 0x11, 0x08, 0x11, 0x08, 0x11, 0x08, 0x11, 0x08, 0x17, 0xFE, 0x10, 0x00
},
{
0x00, 0x00, 0x7F, 0xFC, 0x40, 0x04, 0x40, 0x04, 0x5F, 0xF4, 0x41, 0x04, 0x41, 0x04, 0x4F, 0xE4,
0x41, 0x04, 0x41, 0x44, 0x41, 0x24, 0x5F, 0xF4, 0x40, 0x04, 0x40, 0x04, 0x7F, 0xFC, 0x40, 0x04
},
{
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7C, 0x18, 0x44, 0x24, 0x44, 0x42, 0x08, 0x42, 0x08, 0x42,
0x10, 0x42, 0x10, 0x42, 0x10, 0x42, 0x10, 0x24, 0x10, 0x18, 0x00, 0x00, 0x00, 0x00
},
{
0x00, 0x00, 0x3F, 0xF8, 0x21, 0x08, 0x21, 0x08, 0x2F, 0xE8, 0x21, 0x08, 0x21, 0x08, 0x3F, 0xF8,
0x20, 0x08, 0x27, 0xC8, 0x24, 0x48, 0x24, 0x48, 0x27, 0xC8, 0x40, 0x08, 0x40, 0x28, 0x80, 0x10
},
{
0x10, 0x00, 0x10, 0x00, 0x1F, 0xFC, 0x20, 0x80, 0x20, 0x80, 0x40, 0x80, 0x1F, 0xF8, 0x10, 0x80,
0x10, 0x80, 0x10, 0x80, 0xFF, 0xFE, 0x00, 0x80, 0x00, 0x80, 0x00, 0x80, 0x00, 0x80, 0x00, 0x80
},
{
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x00,0x30,0x00,0x10,0x00,0x20,0x00,0x00,0x00
} };
byte words[][][]= //愿祖国繁荣昌盛,越来越好,
{
{
0x00,0x00,0x3F,0xFE,0x20,0x80,0x27,0xF8,0x24,0x08,0x27,0xF8,0x24,0x08,0x27,0xF8,
0x22,0x50,0x24,0x48,0x29,0x44,0x20,0x80,0x20,0x44,0x4A,0x42,0x4A,0x12,0x91,0xF0
},
{
0x20,0x00,0x11,0xF8,0x11,0x08,0xF9,0x08,0x09,0x08,0x11,0xF8,0x11,0x08,0x39,0x08,
0x55,0x08,0x95,0xF8,0x11,0x08,0x11,0x08,0x11,0x08,0x11,0x08,0x17,0xFE,0x10,0x00
},
{
0x00,0x00,0x7F,0xFC,0x40,0x04,0x40,0x04,0x5F,0xF4,0x41,0x04,0x41,0x04,0x4F,0xE4,
0x41,0x04,0x41,0x44,0x41,0x24,0x5F,0xF4,0x40,0x04,0x40,0x04,0x7F,0xFC,0x40,0x04
},
{
0x20,0x20,0x3F,0x20,0x40,0x3E,0xBE,0x48,0x2A,0xA8,0xFF,0x28,0x4A,0x10,0x7F,0x28,
0x04,0x46,0x08,0x80,0x1F,0x00,0x02,0x10,0x3F,0xF8,0x01,0x08,0x15,0x20,0x22,0x10
},
{
0x08,0x20,0x08,0x20,0xFF,0xFE,0x08,0x20,0x00,0x00,0x7F,0xFE,0x40,0x02,0x81,0x04,
0x01,0x00,0x7F,0xFC,0x03,0x80,0x05,0x40,0x09,0x20,0x31,0x18,0xC1,0x06,0x01,0x00
},
{
0x1F,0xF0,0x10,0x10,0x10,0x10,0x1F,0xF0,0x10,0x10,0x10,0x10,0x1F,0xF0,0x00,0x00,
0x3F,0xF8,0x20,0x08,0x20,0x08,0x3F,0xF8,0x20,0x08,0x20,0x08,0x3F,0xF8,0x20,0x08
},
{
0x00,0x90,0x00,0x88,0x3F,0xFC,0x20,0x80,0x20,0x88,0x3E,0x48,0x22,0x50,0x22,0x24,
0x4A,0x54,0x44,0x8C,0x81,0x04,0x3F,0xF8,0x24,0x48,0x24,0x48,0xFF,0xFE,0x00,0x00
},
{
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x00,0x30,0x00,0x10,0x00,0x20,0x00,0x00,0x00
},
{
0x10,0x28,0x10,0x24,0x10,0x20,0x7D,0xFC,0x11,0x20,0x11,0x24,0xFD,0x24,0x11,0x28,
0x11,0x28,0x51,0x10,0x5D,0x94,0x51,0x2C,0x70,0x44,0x50,0x00,0x4F,0xFE,0x80,0x00
},
{
0x01,0x00,0x01,0x00,0x01,0x00,0x7F,0xFC,0x01,0x00,0x11,0x10,0x09,0x10,0x09,0x20,
0xFF,0xFE,0x03,0x80,0x05,0x40,0x09,0x20,0x31,0x18,0xC1,0x06,0x01,0x00,0x01,0x00
},
{
0x10,0x28,0x10,0x24,0x10,0x20,0x7D,0xFC,0x11,0x20,0x11,0x24,0xFD,0x24,0x11,0x28,
0x11,0x28,0x51,0x10,0x5D,0x94,0x51,0x2C,0x70,0x44,0x50,0x00,0x4F,0xFE,0x80,0x00
},
{
0x10,0x00,0x10,0xFC,0x10,0x04,0x10,0x08,0xFC,0x10,0x24,0x20,0x24,0x20,0x25,0xFE,
0x24,0x20,0x48,0x20,0x28,0x20,0x10,0x20,0x28,0x20,0x44,0x20,0x84,0xA0,0x00,0x40
},
{
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x00,0x30,0x00,0x10,0x00,0x20,0x00,0x00,0x00
}
};
byte leftWords[][][]= //我爱你中国!
{
{
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x1A,0x1C,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
},
{
0x04,0x24,0x24,0x24,0x7F,0xC4,0x44,0x04,0x04,0xFF,0x04,0x44,0x34,0x05,0x04,0x00,
0x00,0x10,0x12,0x21,0xFE,0x40,0x82,0x02,0x04,0xC8,0x30,0x28,0x44,0x82,0x1F,0x00
},
{
0x01,0x26,0x34,0x2C,0x24,0x24,0x37,0x4C,0x44,0x44,0x4C,0x74,0xC4,0x45,0x06,0x00,
0x00,0x82,0x84,0x89,0x91,0xE1,0xB2,0xAA,0xA4,0xA4,0xAA,0xB2,0x81,0x01,0x01,0x00
},
{
0x00,0x01,0x06,0x1F,0xE0,0x02,0x04,0x18,0xF0,0x10,0x13,0x10,0x10,0x14,0x18,0x00,
0x80,0x00,0x00,0xFF,0x00,0x08,0x30,0xC0,0x02,0x01,0xFE,0x00,0x80,0x60,0x18,0x00
},
{
0x00,0x00,0x0F,0x08,0x08,0x08,0x08,0xFF,0x08,0x08,0x08,0x08,0x0F,0x00,0x00,0x00,
0x00,0x00,0xF0,0x20,0x20,0x20,0x20,0xFF,0x20,0x20,0x20,0x20,0xF0,0x00,0x00,0x00
},
{
0x00,0x7F,0x40,0x48,0x49,0x49,0x49,0x4F,0x49,0x49,0x49,0x48,0x40,0x7F,0x00,0x00,
0x00,0xFF,0x02,0x12,0x12,0x12,0x12,0xF2,0x12,0x52,0x32,0x12,0x02,0xFF,0x00,0x00
},
{
0x00,0x00,0x00,0x7F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0xCC,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
}
}; void setup() {
for (int i = ; i < ; ++i)
{
led.shutdown(i, false);//关闭省电模式,这一步必须做,否则显示不出来(因为在构造函数中,默认开启了省电模式,所以,我们要关闭该模式)。
led.clearDisplay(i);//清空数据
}
maxLen = sizeof(words)/sizeof(*words);//计算总的字数
row = * (sizeof(topWords) / sizeof(*topWords));//计算向上移动的字的总行数
col = * (sizeof(leftWords) / sizeof(*leftWords));//计算向左移动的字的总列数
} void loop() {
// put your main code here, to run repeatedly:
showWordByPtr(led, b); //显示空心五角星
delay();
for(int i =;i<;++i)
{
showWordByArr(led, a); //实心五角星
delay();
showWordByArr(led, c); //空心取反
delay();
}
showWordByArr(led, a); //实心五角星
delay();
showTopMoveWords(led, topWords); //字向左滚动
delay();
showWords(led, words); //字原地变换
delay();
showLeftMoveWords(led, leftWords); //字向右滚动
delay();
} void showWordByArr(LedControl led, byte word[][])
{
for (int i = ; i < ; ++i)
{
if (i < )
{
for (int j = ; j < ; ++j)
{
led.setRow(i, j, word[j][i]);
}
}
else
{
for (int j = ; j < ; ++j)
{
led.setRow(i, j, word[j + ][i - ]);
}
}
}
} void showWordByPtr(LedControl led, byte (*word)[])
{
for (int i = ; i < ; ++i)
{
if (i < )
{
for (int j = ; j < ; ++j)
{
led.setRow(i, j, *(*(word + j) + i));
}
}
else
{
for (int j = ; j < ; ++j)
{
led.setRow(i, j, *(*(word + j + ) + i - ));
}
}
}
} void showWords(LedControl led, byte (*words)[][])
{
for (int i = ; i < maxLen; ++i)
{
showWordByPtr(led, *(words + i));
delay();
}
} void showTopMoveWords(LedControl led, byte(*words)[][])
{
byte *temp = *(*words); //获取第一个二维数组的第一行的(第一个元素)的指针
byte* dump = temp;
for(int n =;n<=row-;++n)
{
dump = temp;
for (int i = ; i < ; ++i)//共4块8*8led点阵,每块显示完再到下一块
{
dump = temp;
if (i < ) //第一、二块的点阵
{
for (int j = ; j < ; ++j) //每块点阵共8行,所以循环8次
{
led.setRow(i, j, *(dump + i));
dump+=; //指向下一行的第一个位置
}
}
else //第三、四块点阵显示
{
dump+=; //因为是显示二维数组的后半部分,这里要加一下。
for (int j = ; j < ; ++j)
{
led.setRow(i, j, *(dump+i-));
dump+=;
}
}
}
temp += ;//每次循环完,指向下一行。
delay(); //每次显示之间间隔35ms,这是我自己测试的,如果想要更快或更慢可以相应调整这个参数。
}
} void showLeftMoveWords(LedControl led, byte(*words)[][])
{
byte* first = *(*words);
byte* firstChangeFlag = first + ;//开始遍历的指针需要变换的标志(也就是当first和firstChangeFlag相等时,说明first需要再偏移17).
byte* temp = first; //负责显示第一、二个led点阵的指针
byte* temp1 = first + ; //负责显示第三、四个点阵的指针
for (int n = ; n < col - ; ++n)
{
temp = first;
temp1 = first + ;
for (int i=;i<;++i)
{
if (i < ) //第一、二个点阵
{
for (int j = ; j < ; ++j)
{
led.setColumn(i, j, *temp);
if (temp == firstChangeFlag)
{
temp += ;
}
else
{
temp++;
}
}
}
else //第三、四个点阵
{
for (int k=; k<; ++k)
{
led.setColumn(i, k, *temp1);
if (temp1 == firstChangeFlag+)
{
temp1 += ;
}
else
{
temp1++;
}
}
}
}
if (first == firstChangeFlag)
{
first += ;
firstChangeFlag = first + ;
}
else
{
first++;
}
//delay(1000);
}
}
最后总结一下:
1. 汉字的点阵数组是使用16*16字模软件提取出来的,我用的是字模提取 v2.2版本,网上搜一下就有。
2. 原来写过的,只是单纯的显示汉字,这次把文字移动显示加上去了。
3. 向左移动文字的那个函数想了好久才写出来的,主要是太浮躁了,后来静下心来仔细推敲,是发现指针遍历数组的顺序有问题,这才解决了。
4. 通过视频可以看到,向左移动显示的效果还是有点问题的,上面一半的显示和下面一半的显示有一点不同步,难道是处理器跟不上?(自我安慰)。希望有路过大神指点一下。
5. 最后要感谢下面的文章,是当初玩点阵入门的时候的参考资料。
Arduino Uno 使用MAX7219驱动单个8*8点阵LED模块 - 凌顺实验室
2019-10-15更新:
今天上班钻孔的时候(我是做模具的),突然来了灵感,想到了解决横向滚动,上下屏不同步的解决办法。
回来一试,效果很好(几乎看不出来,不同步了)。原来我是按照先显示第1和第2块led点阵,再显示第3块和第4块点阵的方式的(这是向上滚动字幕的显示方式),
既然向左滚动,那应该是先显示最左边的点阵,即先显示第1和第3块点阵,再显示右边的第2和第4块led点阵,这样就解决了,代码稍加改动如下:
void showLeftMoveWords(LedControl led, byte(*words)[][])
{
byte* first = *(*words);
byte* firstChangeFlag = first + ;//开始遍历的指针需要变换的标志(也就是当first和firstChangeFlag相等时,说明first需要再偏移17).
byte* temp = first; //负责显示第一、二个led点阵的指针
byte* temp1 = first + ; //负责显示第三、四个点阵的指针
for (int n = ; n < col - ; ++n)
{
temp = first;
temp1 = first + ;
//原来是先显示第1块和第2块,再显示第3,4块的,所以导致上下屏不同步。
for (int i = ; i < ; ++i) //这里循环2次,分2次显示,先显示第1块和第3块led,再显示第2块和第4块led。
{
for (int j = ; j < ; ++j)
{
led.setColumn(i, j, *temp);
if (temp == firstChangeFlag)
{
temp += ;
}
else
{
temp++;
}
}
for (int k = ; k < ; ++k)
{
led.setColumn(i+, k, *temp1);
if (temp1 == firstChangeFlag + )
{
temp1 += ;
}
else
{
temp1++;
}
}
}
if (first == firstChangeFlag)
{
first += ;
firstChangeFlag = first + ;
}
else
{
first++;
}
}
}
再次总结:
1. 这个点阵模块在某宝上花了三十几块大洋买的,玩到这样也算对的起我的大洋了。。。
2. 突然发现,点阵可以拿来玩一些数据结构的演练,有空得好好试下玩玩(比如,拿这点阵玩贪吃蛇。。。)。
3. 遇到问题,一定要冷静思考,切勿焦躁,烦躁是大忌,这也是成为一名职业程序员的基本修养(虽然,目前还不是)。
arduino之16*16点阵庆祝祖国70周年的更多相关文章
- 矢量图标转成16*16大小的SVG格式
著作权归作者所有.商业转载请联系作者获得授权,非商业转载请注明出处.作者:一一链接:http://www.zhihu.com/question/32233782/answer/68629385来源:知 ...
- UCOSii任务就绪表之OSUnMapTbl[16*16]的数组是如何得到的
我比较喜欢图,如下图: 图1: INT8U const OSUnMapTbl[]数组内的数据. 1.UCOSii的优先级相关内容 首先先介绍一个概念:优先级.UCOSii的优先级按倒叙排列,即优先级数 ...
- 不使用局部变量和for循环或其它循环打印出如m=19,n=2結果为2 4 8 16 16 8 4 2形式的串
需求:不使用局部变量和for循环或其它循环打印形如:2 4 8 16 16 8 4 2 这样的串 代码MainTest.java package com.szp.study.javase.specia ...
- 2017.9.16~17,热烈庆祝共创力罗老师《敏捷MINI体验式实战培训》在某大型企业成功举办!
2017.9.16~17日,深圳市共创力企业管理咨询有限公司为某上市企业提供了为期两天的内训服务.该次内训的主题为<敏捷MINI体验式实践培训>,为期两天.此次培训由共创力资深讲师Geor ...
- 2017年1月4日 16:16:24开始学习Linux——好像回到上次发随笔的时间。
auto为C语言局部变量的默认属性 static指明变量的静态属性,也具有作用域限定符的意义 static修饰的全局变量作用域只是生命的文件中,修饰的函数作用域只是声明的文件中 register指明将 ...
- Hbase常见异常 分类: B7_HBASE 2015-02-02 16:16 412人阅读 评论(0) 收藏
1. HBase is able to connect to ZooKeeper but the connection closes immediately hbase(main):001:0> ...
- Linux mint 启动文本模式(不启动图形界面)
Linux Mint 系统用了很久,很顺手,赞一个! 有一天想同时运行多个虚拟机linux系统做实验,想着只启动文本模式可以省点内存资源,结果试了多种方法都不成功,网上现有针对Ubuntu原版和Cen ...
- Python中print()函数不换行的方法以及分隔符替换
一.让print()函数不换行 在Python中,print()函数默认是换行的.但是,在很多情况下,我们需要不换行的输出(比如在算法竞赛中).那么,在Python中如何做到这一点呢? 其实很简单.只 ...
- Python使用print打印时,展示内容不换行
原理 Python的print()函数中参数end='' 默认为\n,所以会自动换行; 默认的print()函数: print(end='\n') 方案 Python 2: 在print语句的末尾加上 ...
随机推荐
- Swift4.0复习类
1.类的属性: 2.类的方法: 3.类作为引用类型: “Swift新增了一对操作符 === 与 !== 用于判定同一个类的两个对象引用是否指向同一对象实例.” 摘录来自: “大话Swift 4.0”. ...
- vue骨架屏以及seo优化
参考文档 vue骨架屏 https://blog.csdn.net/ly124100427/article/details/81168908 vue seo优化 1.SSR服务器渲染: 2.静态化: ...
- sharp.js中文文档
高性能node.js图像处理库,使用libvips库来实现. 英文地址:sharp.pixelplumbing.com/ 中文文档地址:yunlzhang.github.io/sharp-docum…
- adb中文乱码问题怎么解决?
1.chcp 65001 执行完命令后 2.在cmd命令弹出的终端页面,右键单击属性设置成字体Lucida Console ,设置完成就解决了 adb 中文乱码问题
- centos7下使用yum安装mysql5.7.10
原文地址:http://www.mamicode.com/info-detail-503994.html CentOS7的yum源中默认好像是没有mysql的.为了解决这个问题,我们要先下载mysql ...
- jquery获取父,同,子级元素
一.获取父级元素 1. parent([expr]): 获取指定元素的所有父级元素 <div id="par_div"><a id="href_fir& ...
- 实现不同分辨率、不同浏览器下高度自适应、iframe高度自适应
html: <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <tit ...
- JUC之原子类
在分析原子类之前,先来了解CAS操作 CAS CAS,compare and swap的缩写,中文翻译成比较并交换. CAS 操作包含三个操作数 —— 内存位置(V).预期原值(A)和新值(B).如果 ...
- Python程序设计基本方法图
Python程序设计基本方法图
- python 并发的开端
目录 网络并发 进程的基础 2.操作系统 操作系统的发展史 多道技术 第二代 1955~1965 磁带存储--批处理系统 第三代集成电路,多道程序系统(1955~1965) 进程的理论(重点) 2.操 ...