23902| 19
|
[项目] 8*8 LED 三色全彩点阵模块配合rgb_matrix库的简单实验 |
实验目标:调用reb_matrix库函数实现Arduino UNO主控板控制三色全彩点阵模块的动画显示,并且能用按键切换动画效果。 实验器材: 主控模块:DFRduino UNO R3 扩展模块:IO 传感器扩展板 V7.1 显示模块:8*8 LED 三色全彩点阵模块(模块可级联,1x1, 1x4,2x2,3x3等) 按键模块:数字大按钮模块 8*8 LED 三色全彩点阵模块 开始做实验:实验分为硬件搭建和软件编程两个部分。 1.硬件的搭建 首先简单介绍一下这个8x8的点阵模块,最上面8个引脚,最下面两个排插,左边8个引脚和右边一个排插都是为了方便模块间级联留出来的接口,这样级联的时候很方面。 两个模块级联的时候像上面那样,直接将一个模块的左边8个引脚插入另一个模块右边的排插就行了,其他级联类似上面的连接。 除了上下左右的引脚和插排,在每个模块的右上角还有单独的6个引脚,标号为:VCC,GND,1,2,3,这几个接口是和主控板连接的,采取的是SPI通信模式。以连接DFRduino UNO R3说明一下引脚连接方式: 模块 DFRduino UNO R3 VCC VCC GND GND 1 13 2 8 3 11 还有个按键模块,按键接DFRduino UNO R3主控板的2号引脚,既可以用作中断触发,也可以用作普通的数字输入。 最终的实物接线图 2.软件编程 硬件的搭载还是不难的,连接的线不多,很容易就记住了,搭载好硬件后我们就可以脑洞想要显示在点阵屏上的动画了,这时我们还要做一些准备工作。 a.下载操作这个点阵屏的库文件https://mc.dfrobot.com.cn/forum.php?mod=attachment&aid=MTkwNjd8ODBlN2Y2MDNiMTg5OWVmYzAzODk5Mzg4ZGRlN2Y1YWV8MTczMDg1MTg1Nw%3D%3D&request=yes&_f=.zip(如果不喜欢这个库可以自己尝试编写库文件),将这个库文件放入arduino的库中我们就可以直接使用了。 b.下载一个好用的点阵屏动画取模软件,EXE格式,我这边上传不了,截个图,长这样,挺好用的。 准备工作做好后我们开始编写程序,首先简单介绍下rgb_matrix库文件中常用的几个函数,知道这几个常用的函数后就可以做出很多动画效果了,想更深入的了解可以研究研究库文件的编写: //初始化硬件连接,定义连接的引脚 1.rgb_matrix(uint8_t x8, uint8_t y8,uint8_t _data_pin, uint8_t _clk_pin,uint8_t _latch_pin); 例: rgb_matrix M = rgb_matrix(1,2,11,13,8); //x方向一个子板,y方向2个子版级联,使用硬件spi,latch使用数字8口 //向顶层图层缓存中写入一个ASCII字符 2.int put_char(uint16_t x,uint16_t y, uint8_t asc, uint8_t rotation, uint8_t mode, uint8_t color); 例: M.put_char(0,0,’B’,NO_ROT,MULTIPLY,RED+GREEN); //在(0,0)出不翻转使用红+绿色显示B,如果这个位置上原来有数据,那么和原有数据叠加 //向指定图层缓存中写入一个ASCII字符(可注意一下和上面函数的差别) 3.int put_char(uint16_t x,uint16_t y, uint8_t asc, uint8_t rotation, uint8_t mode, uint8_t color, uint8_t index); 例: M.put_char(0,0,’B’,ANTI_90,COVER,RED,TOP_LAYER); //在顶层(0,0)处逆时针翻转90度,使用红色显示字符B,如果这个位置上有数据,那么将其覆盖。 //在顶层用红色画一个点 4.int plot(int16_t x, int16_t y); 例: M.plot(1,2) //顶层(1,2)这个点用红色点亮 //向指定图层加入单色图片 5.int put_pic(int16_t x, int16_t y, uint8_t size_x, uint8_t size_y, const char p[], uint8_t mode,uint8_t color,uint8_t index); 例: const char pic[] = { 0x02,0x04,0x1F,0xE0,0x02,0x04,0x18,0xF0, 0x10,0x13,0x10,0x10,0x14,0x18,0x00,0x00, 0x00,0x00,0xFF,0x00,0x00,0x10,0x20,0xC2, 0x01,0xFE,0x00,0x80,0x60,0x30,0x00,0x00 }; M.put_pic(0,0,16,16,pic,COVER,GREEN,TOP_LAYER); //在顶层用绿色显示一个16X16图片,如果这个位置原来有数据,那么覆盖它。 //向顶层图层加入汉字(最少需要四块模块级联才能显示数字哦) 6.int put_HZ(int16_t x, int16_t y, const char p[]); 例: const char ni[] = { 0x02,0x04,0x1F,0xE0,0x02,0x04,0x18,0xF0, 0x10,0x13,0x10,0x10,0x14,0x18,0x00,0x00, 0x00,0x00,0xFF,0x00,0x00,0x10,0x20,0xC2, 0x01,0xFE,0x00,0x80,0x60,0x30,0x00,0x00 }; M.put_HZ(0,0,ni,COVER,GREEN,TOP_LAYER); //在顶层(0,0)处用红色显示汉字”你” 下面以库文件自带的一个例子改造显示一个我们想要的画面,我们显示一个大写字母A, #include <rgb_matrix.h> #include <SPI.h> unsigned long time=0; unsigned int tick_100ms = 0; unsigned char counter=0; #define N_X 1 #define N_Y 1 //Hardware SPI #define DATA_PIN 11 #define CLK_PIN 13 #define LATCH_PIN 8 rgb_matrix M = rgb_matrix(N_X, N_Y, DATA_PIN, CLK_PIN, LATCH_PIN); //初始化硬件连接方式 unsigned char cmd[50]={0},cmd_num=0; unsigned char st=0; void setup() { } void hook(void) { int i = 0; unsigned long enter_time,exit_time; enter_time = micros(); if((++counter)%10 == 0) //调节画面,消除重影,可根据具体实现调节参数 { if(millis() - time >= 100) { time = millis(); tick_100ms ++; //M.move(UP,1,0); //移动图层的,让现实画面呈现动态效果,这里屏蔽掉了,如果不屏蔽,显示效果就是动态的了 if(tick_100ms%5 == 0) { M.clear(); M.put_char(0,1,'A',1,MULTIPLY,RED ,TOP_LAYER); //在点阵屏上现实一个字母A } } } exit_time = micros(); //下面的程序都是为了条件画面现实效果的,时间太长或者太短都可能会造成点阵屏画面的重影 if(enter_time < exit_time) { if(exit_time - enter_time < 500) { delayMicroseconds(500 - (exit_time-enter_time)); } } } void loop() { M.display(hook); //进入display函数,这个display函数是一个死循环函数 ,进去就出不来了,会不间断调用函数hook() } 显示效果 如果我们想显示一个表情或着其他图形,我们怎么办呢,很简单,这个时候我们准备的取模软件就派上用场了,使用起来很简单,操作几次就熟悉了,下面我们改造上面的程序,让它显示一个小爱心,只要在程序中加两条语句就行了: 1.const char love[]={0x00,0x66,0xFF,0xFF,0xFF,0x7E,0x3C,0x18,};//爱心图案存放的数组,数组值是用下面去摸软件得到的 2.M.put_pic(0,0,8,8,love,COVER,BLUE,TOP_LAYER); //在点阵屏上显示一个爱心 取模软件效果图 具体程序如下,改动部分高亮显示了: #include <rgb_matrix.h> #include <SPI.h> unsigned long time=0; unsigned int tick_100ms = 0; unsigned char counter=0; const char love[]={0x00,0x66,0xFF,0xFF,0xFF,0x7E,0x3C,0x18,};//爱心图案存放的数组 #define N_X 1 #define N_Y 1 //Hardware SPI #define DATA_PIN 11 #define CLK_PIN 13 #define LATCH_PIN 8 rgb_matrix M = rgb_matrix(N_X, N_Y, DATA_PIN, CLK_PIN, LATCH_PIN); unsigned char cmd[50]={0},cmd_num=0; unsigned char st=0; void setup() { } void hook(void) { int i = 0; unsigned long enter_time,exit_time; enter_time = micros(); if((++counter)%10 == 0) //调节画面,消除重影,可根据具体实现调节参数 { if(millis() - time >= 100) { time = millis(); tick_100ms ++; //M.move(UP,1,0); //移动图层的,让现实画面呈现动态效果,这里屏蔽掉了,如果不屏蔽,显示效果就是动态的了 if(tick_100ms%5 == 0) { M.clear(); //M.put_char(0,1,'A',1,MULTIPLY,RED ,TOP_LAYER); //在点阵屏上显示一个字母A M.put_pic(0,0,8,8,love,COVER,BLUE,TOP_LAYER); //在点阵屏上显示一个爱心 } } } exit_time = micros(); //下面的程序都是为了条件画面现实效果的,时间太长或者太短都可能会造成点阵屏画面的重影 if(enter_time < exit_time) { if(exit_time - enter_time < 500) { delayMicroseconds(500 - (exit_time-enter_time)); } } } void loop() { M.display(hook); //进入display函数,这个display函数是一个死循环函数 } 显示效果,是不是很简单,按照上面类似的做法,添加想要的图案就可以做出很多显示效果了。 下面是级联的显示效果: 眼睛表情 DFROBOT字样(动态效果) SB字样,可以恶搞哦,当你让朋友按下按键的时候,出现这副画面,你就可以“取笑”你朋友了哦,哈哈... 好有爱有木有,动态效果会很漂亮,做一个送给女朋友吧! 如果我们想要在已经写好的多个画面中选择一个喜欢的动画显示出来该怎么办呢???,下面就解决这个问题!!! 当每个单个的动画效果都做出来的时候,我们想把它组合在一起,然后可以用按键区切换每个画面,这样可玩又高了。但是问题来了,显示函数是一个死循环函数,而且在display()死循环里面的hook()函数里面添加按键判断程序会造成点阵显示乱码,不能在主循环里面添加程序,那么在这里只有两种方法实现按键检测了(如果有第三种实现,亲,可以告诉我一下哦),第一种就是修改库文件(选择性使用,不推荐),让它支持按键检测,下载的库文件是不支持按键检测的,第二种就是利用中断来实现(推荐这种方法),当实现按键后就很简单了,主循环里改变程序执行流就行了,用分支语句控制。 这: 第一种方法:修改一下库文件,不建议使用,用中断更方便,这里说明一下怎么修改,可以顺便熟悉一下库文件的编写 a.修改rgb_matrix.h文件,加入 uint8_t signal_pin; //按键触发引脚 b.将初始化函数改成这样: rgb_matrix(uint8_t x8, uint8_t y8,uint8_t _data_pin, uint8_t _clk_pin,uint8_t _latch_pin,uint8_t signal_pin); c.将显示函数改成下面的格式(注意:在rgb_matrix.cpp文件的实现函数中也要做相应修改) void display(void (*display_hook)(uint8_t temp)); d.修改rgb_matrix.cpp文件 在rgb_matrix::rgb_matrix()函数实现下面加入下面两句: signal_pin = _signal_pin; //初始化引脚参数的传递 pinMode(signal_pin, INPUT); //将引脚设置为输入模式 e.在void rgb_matrix::display()实现函数中做如下修改: 首先加入 static uint8_t change = 0; static uint8_t ; 将最后面的程序改成这样:程序代码中724到734行之间 digitalWrite(latch_pin,HIGH); val = digitalRead(signal_pin); // read input value if (val == LOW) { // check if the input is LOW change++; // turn LED ON if(change >= 6 ) change = 0; } if(((uint16_t)display_hook) != NULL) { (*display_hook)(change); } OK,库就修改完成了,在程序中直接定义相关引脚并且传入参数就行了,不推荐使用,可以试着修改玩玩。 第二种方法:中断 void setup() { attachInterrupt(0,blink,FALLING); } void blink() { count++; if(count == 4) //主循环中根据count的数值的不同控制不同画面的显示 count = 0; } 下面是一个简单的按键切换动画的效果视频,按键切换用中断实现,原理很简单,程序比较LOW,仅供参考:https://mc.dfrobot.com.cn/forum.php?mod=attachment&aid=MTkwNjl8MGRhOGExNjJjZWNkNTA0OTFhNjNkMDQzYzJiZGY2ZmJ8MTczMDg1MTg1Nw%3D%3D&request=yes&_f=.zip 发现上传上来的程序都编程网址了,有空再捣鼓捣鼓怎么上传文件。 视频: |
Jason_G 发表于 2017-4-24 14:05 为什么我运行您的代码,会出现这样的错误no matching function for call to 'rgb_matrix::rgb_matrix(int, int, int, int, int)' ,您能指教一下吗?谢谢您 |
Jason_G 发表于 2017-4-25 12:15 您好,代码可以了,可是LED点阵不亮,是不是需要开关,我看到您上边提到 |
Jason_G 发表于 2017-4-25 23:09 您好,今天毕设中期答辩,正好又出现之前那个问题了,实在不知道怎么解决了,您方便远程操控帮我整下吗?看看什么问题,这是我QQ号:1378411641 |
© 2013-2024 Comsenz Inc. Powered by Discuz! X3.4 Licensed