【花雕动手做】有趣好玩的音乐可视化(30)--P6 LED单元板

2022-11-031万
AI 快速预览详细 收起
本文介绍了如何使用P6 LED单元板进行音乐可视化。P6 LED单元板包含512个RGB LED,排列在16x32网格中。通过实际动手试验,逐步积累有用的音乐频谱可视化的资料,并形成实用好玩的音乐可视器项目。


偶然心血来潮,想要做一个音乐可视化的系列专题。这个专题的难度有点高,涉及面也比较广泛,相关的FFT和FHT等算法也相当复杂,不过还是打算从最简单的开始,实际动手做做试验,耐心尝试一下各种方案,逐步积累些有用的音乐频谱可视化的资料,也会争取成型一些实用好玩的音乐可视器项目。

找到二片P6 LED单元板,它们有 512 个明亮的 RGB LED,排列在正面的 16x32 网格中。

【花雕动手做】有趣好玩的音乐可视化(30)--P6 LED单元板图2

【花雕动手做】有趣好玩的音乐可视化(30)--P6 LED单元板图1

创作许可协议

本项目采用 None(不开放任何权利,保留所有权利) 进行许可。

评论(26)
驴友花雕
驴友花雕
作者

驴友花雕
驴友花雕
作者
实验场景图 动态图

[backcolor=rgb(255, 255, 255)][font=Tahoma, "]LED模组会轮流显示:一个白点、全屏绿色、全屏黄色、一个黄色的矩形框、一个红色的X、一个蓝色的圆、一个填充紫圆、英文字。[/font][/backcolor]
驴友花雕
驴友花雕
作者
实验场景图

驴友花雕
驴友花雕
作者
【花雕动手做】有趣好玩的音乐可视化系列项目(30)--P6LED单元板
项目程序之二:点亮P6单元板——显示图形与文字
[code]/*
【花雕动手做】有趣好玩的音乐可视化系列项目(30)--P6LED单元板
项目程序之二:点亮P6单元板——显示图形与文字
*/
#include
#include
#define CLK 8
#define LAT A3
#define OE 9
#define A A0
#define B A1
#define C A2
RGBmatrixPanel matrix(A, B, C, CLK, LAT, OE, false);
void setup() {
matrix.begin();
}
void loop() {
// draw a pixel in solid white
matrix.drawPixel(0, 0, matrix.Color333(7, 7, 7));
delay(500);
// fix the screen with green
matrix.fillRect(0, 0, 32, 16, matrix.Color333(0, 7, 0));
delay(500);
// draw a box in yellow
matrix.drawRect(0, 0, 32, 16, matrix.Color333(7, 7, 0));
delay(500);
// draw an 'X' in red
matrix.drawLine(0, 0, 31, 15, matrix.Color333(7, 0, 0));
matrix.drawLine(31, 0, 0, 15, matrix.Color333(7, 0, 0));
delay(500);
// draw a blue circle
matrix.drawCircle(7, 7, 7, matrix.Color333(0, 0, 7));
delay(500);
// fill a violet circle
matrix.fillCircle(23, 7, 7, matrix.Color333(7, 0, 7));
delay(500);
// fill the screen with 'black'
matrix.fillScreen(matrix.Color333(0, 0, 0));
// draw some text!
matrix.setCursor(1, 0);
matrix.setTextSize(1);
// print each letter with a rainbow color
matrix.setTextColor(matrix.Color333(7, 0, 0));
matrix.print('1');
matrix.setTextColor(matrix.Color333(7, 4, 0));
matrix.print('6');
matrix.setTextColor(matrix.Color333(7, 7, 0));
matrix.print('x');
matrix.setTextColor(matrix.Color333(4, 7, 0));
matrix.print('3');
matrix.setTextColor(matrix.Color333(0, 7, 0));
matrix.print('2');
matrix.setCursor(1, 9); // next line
matrix.setTextColor(matrix.Color333(0, 7, 7));
matrix.print('*');
matrix.setTextColor(matrix.Color333(0, 4, 7));
matrix.print('R');
matrix.setTextColor(matrix.Color333(0, 0, 7));
matrix.print('G');
matrix.setTextColor(matrix.Color333(4, 0, 7));
matrix.print('B');
matrix.setTextColor(matrix.Color333(7, 0, 4));
matrix.print("*");
delay(5000);
}[/code]
驴友花雕
驴友花雕
作者
[backcolor=rgb(255, 255, 255)][font=Tahoma, "]HUB75接口,是个兼容大部分市面LED单元板的通用型接口,具体接线定义有些不同,比如HUB75B\HUB75E等。[/font][/backcolor]
[backcolor=rgb(255, 255, 255)][font=Tahoma, "]这次自制的扩展板,只是专门匹配Arduino UNO开发板的专用板,由于性能限制,最多只能使用32x16,或者32x32的简单控制。[/font][/backcolor]
[backcolor=rgb(255, 255, 255)][font=Tahoma, "]下一张扩展板,准备尝试搭配ESP32开发板,以适应大部分P5\P4\P3的单元板模组,主要规格可能有32x32\64x32\64x64,还有128x64等。[/font][/backcolor]
[backcolor=rgb(255, 255, 255)][font=Tahoma, "]
[/font][/backcolor]
[backcolor=rgb(255, 255, 255)][font=Tahoma, "]
[/font][/backcolor]

驴友花雕
驴友花雕
作者
实验接线图

驴友花雕
驴友花雕
作者
[table]
[tr][td]实验的视频记录
优酷:https://v.youku.com/v_show/id_XNTkxOTYzNzk4MA==.html?spm=a2hcb.playlsit.page.1
B站:https://www.bilibili.com/video/BV1AD4y147BJ/?vd_source=98c6b1fc23b2787403d97f8d3cc0b7e5
[media=x,500,375]https://www.bilibili.com/video/BV1AD4y147BJ/?vd_source=98c6b1fc23b2787403d97f8d3cc0b7e5[/media][/td][/tr]
[/table]
驴友花雕
驴友花雕
作者
实验场景图 动态图

驴友花雕
驴友花雕
作者
实验场景图

驴友花雕
驴友花雕
作者
【花雕动手做】有趣好玩的音乐可视化系列项目(30)--P6LED单元板
项目程序之一:点亮P6单元板——点与线的简单控制
[code]/*
【花雕动手做】有趣好玩的音乐可视化系列项目(30)--P6LED单元板
项目程序之一:点亮P6单元板——点与线的简单控制
*/
#include //核心图形库
#include //硬件特定库
#define CLK 8 //必须在这个端口上! (在Mega上使用PIN 11)
#define LAT A3
#define OE 9
#define A A0
#define B A1
#define C A2
//最后一个参数='false'禁用双屏障
RGBmatrixPanel matrix(A, B, C, CLK, LAT, OE, false);
void setup() {
matrix.begin(); //矩阵开始(启动)
}
void loop() {
//用红色在0,0处画一个像素
matrix.drawPixel(0, 0, matrix.Color333(7, 0, 0));
delay(500);
matrix.fillScreen(matrix.Color333(0, 0, 0));
delay(500);
//用绿色在31,0处画一个像素
matrix.drawPixel(31, 0, matrix.Color333(0, 7, 0));
delay(500);
matrix.fillScreen(matrix.Color333(0, 0, 0));
delay(500);
//用蓝色在31,15处画一个像素
matrix.drawPixel(31, 15, matrix.Color333(0, 0, 7));
delay(500);
matrix.fillScreen(matrix.Color333(0, 0, 0));
delay(500);
//用白色在0,15处画一个像素
matrix.drawPixel(0, 15, matrix.Color333(5, 5, 5));
delay(500);
matrix.fillScreen(matrix.Color333(0, 0, 0));
delay(500);
//用四种颜色在单元板四角各画一个像素
matrix.drawPixel(0, 0, matrix.Color333(7, 0, 0));
matrix.drawPixel(31, 0, matrix.Color333(0, 7, 0));
matrix.drawPixel(31, 15, matrix.Color333(0, 0, 7));
matrix.drawPixel(0, 15, matrix.Color333(5, 5, 5));
delay(500);
matrix.fillScreen(matrix.Color333(0, 0, 0));
delay(500);
matrix.drawLine(0, 0, 31, 0, matrix.Color333(7, 0, 0));
delay(500);
matrix.fillScreen(matrix.Color333(0, 0, 0));
delay(500);
matrix.drawLine(31, 0, 31, 15, matrix.Color333(0, 7, 0));
delay(500);
matrix.fillScreen(matrix.Color333(0, 0, 0));
delay(500);
matrix.drawLine(0, 15, 31, 15, matrix.Color333(0, 0, 7));
delay(500);
matrix.fillScreen(matrix.Color333(0, 0, 0));
delay(500);
matrix.drawLine(0, 0, 0, 15, matrix.Color333(5, 5, 5));
delay(500);
matrix.fillScreen(matrix.Color333(0, 0, 0));
delay(500);
matrix.drawLine(0, 0, 31, 0, matrix.Color333(7, 0, 0));
matrix.drawLine(31, 0, 31, 15, matrix.Color333(0, 7, 0));
matrix.drawLine(0, 15, 31, 15, matrix.Color333(0, 0, 7));
matrix.drawLine(0, 0, 0, 15, matrix.Color333(5, 5, 5));
delay(500);
matrix.fillScreen(matrix.Color333(0, 0, 0));
delay(500);
matrix.drawLine(0, 0, 31, 15, matrix.Color333(4, 7, 0));
delay(500);
matrix.fillScreen(matrix.Color333(0, 0, 0));
delay(500);
matrix.drawLine(31, 0, 0, 15, matrix.Color333(4, 7, 0));
delay(500);
matrix.fillScreen(matrix.Color333(0, 0, 0));
delay(500);
matrix.drawLine(0, 0, 31, 15, matrix.Color333(0, 7, 4));
matrix.drawLine(31, 0, 0, 15, matrix.Color333(0, 7, 4));
delay(500);
matrix.fillScreen(matrix.Color333(0, 0, 0));
delay(500);
matrix.drawLine(0, 0, 31, 0, matrix.Color333(7, 0, 0));
matrix.drawLine(31, 0, 31, 15, matrix.Color333(0, 7, 0));
matrix.drawLine(0, 15, 31, 15, matrix.Color333(0, 0, 7));
matrix.drawLine(0, 0, 0, 15, matrix.Color333(5, 5, 5));
matrix.drawLine(0, 0, 31, 15, matrix.Color333(0, 7, 0));
matrix.drawLine(31, 0, 0, 15, matrix.Color333(0, 7, 0));
delay(500);
matrix.fillScreen(matrix.Color333(0, 0, 0));
delay(500);
matrix.drawLine(0, 0, 31, 0, matrix.Color333(7, 0, 0));
matrix.drawLine(31, 0, 31, 15, matrix.Color333(7, 0, 0));
matrix.drawLine(0, 15, 31, 15, matrix.Color333(7, 0, 0));
matrix.drawLine(0, 0, 0, 15, matrix.Color333(7, 0, 0));
matrix.drawLine(0, 0, 31, 15, matrix.Color333(7, 0, 0));
matrix.drawLine(31, 0, 0, 15, matrix.Color333(7, 0, 0));
delay(500);
matrix.fillScreen(matrix.Color333(0, 0, 0));
delay(500);
matrix.drawLine(0, 0, 31, 0, matrix.Color333(0, 7, 0));
matrix.drawLine(31, 0, 31, 15, matrix.Color333(0, 7, 0));
matrix.drawLine(0, 15, 31, 15, matrix.Color333(0, 7, 0));
matrix.drawLine(0, 0, 0, 15, matrix.Color333(0, 7, 0));
matrix.drawLine(0, 0, 31, 15, matrix.Color333(0, 7, 0));
matrix.drawLine(31, 0, 0, 15, matrix.Color333(0, 7, 0));
delay(500);
matrix.fillScreen(matrix.Color333(0, 0, 0));
delay(500);
matrix.drawLine(0, 0, 31, 0, matrix.Color333(0, 0, 7));
matrix.drawLine(31, 0, 31, 15, matrix.Color333(0, 0, 7));
matrix.drawLine(0, 15, 31, 15, matrix.Color333(0, 0, 7));
matrix.drawLine(0, 0, 0, 15, matrix.Color333(0, 0, 7));
matrix.drawLine(0, 0, 31, 15, matrix.Color333(0, 0, 7));
matrix.drawLine(31, 0, 0, 15, matrix.Color333(0, 0, 7));
delay(500);
matrix.fillScreen(matrix.Color333(0, 0, 0));
delay(500);
}[/code]
驴友花雕
驴友花雕
作者
驴友花雕
驴友花雕
作者
HUB75接口扩展板接线
UNO HUB75
D2 R1
D3 G1
D4 B1
D5 R2
D6 G2
D7 B2
D8 CLK
D9 OE
A0 A
A1 B
A2 C
A3 STB
GND GND

驴友花雕
驴友花雕
作者
[font=宋体]做好的是这样,可以直接插在Arduino uno开发板上[/font][font=Tahoma, "][font=宋体][size=16px]
[/font][/size][/font]
[font=Tahoma, "]

[/font]
驴友花雕
驴友花雕
作者
[align=left][font=Tahoma, "][font=宋体][size=12pt]自制[/font][font=Calibri]HUB75[/font][font=宋体]接口的Arduino[/font][font=Calibri]UNO[/font][font=宋体]扩展板[/font][/size][/font][/align]
[align=left][font=Tahoma, "]以Proto Shield [font=宋体]原型[/font][font=宋体]扩展[/font][font=宋体]板[/font][font=宋体]为主,加装羊角[/font][font=Calibri]P16[/font][font=宋体]插座,方便于做实验[/font][/font][/align][font=宋体]
[/font]

驴友花雕
驴友花雕
作者
找到一张P6 32X16单元板的参考电原理图

驴友花雕
驴友花雕
作者
[backcolor=rgb(255, 255, 255)][font=Tahoma, "]面板具有 Molex 式接头,只需插入随附的电源线,注意正确的极性。如果您的电源线在此电源线的另一端带有铲子,则可以将它们拧入 2.1 毫米接线端子适配器。效果很好!不要让暴露的连接器接触金属……你应该用热缩管或电工胶带覆盖它。[/font][/backcolor]
[backcolor=rgb(255, 255, 255)][font=Tahoma, "]
[/font][/backcolor]

驴友花雕
驴友花雕
作者
[backcolor=rgb(255, 255, 255)][font=Tahoma, "]电源连接器[/font][/backcolor]
[backcolor=rgb(255, 255, 255)][font=Tahoma, "]尽管 LED 是非常高效的光源,但在一个地方获得足够多的 LED,电流确实会增加。单个 32x16或32x32 RGB 矩阵,全倾斜运行(所有像素设置为白色),可能需要近 4 安培的电流!对于64x32矩阵,该数字翻倍。不过,平均而言,显示典型的图形和动画,这些面板将使用更少的... 2A电源通常足以用于单个 32x16 或 32x32 面板,或 4A 用于 64x32 面板。使用额定电流更大的更大电源(例如 10A 电源)没有害处,但切勿 使用电压更高的电源(使用 5V,周期)!在这些面板上,电源连接与数据连接是分开的。让我们从连接 5V 电源开始……[/font][/backcolor]
[backcolor=rgb(255, 255, 255)][font=Tahoma, "]
[/font][/backcolor]

驴友花雕
驴友花雕
作者

驴友花雕
驴友花雕
作者
可供参考的HUB75接口定义

驴友花雕
驴友花雕
作者

关于LED点阵屏单元板的通信接口——HUB75的坑
因为 HUB75 接口标准缺乏明确规范,导致一些厂商并没有完全按照上面的格式传输数据。就拿我买到的第一块单元板为例,虽然号称 1/32 扫的 HUB75,但它的行选择信号并不是标准的5位地址线,而是将每半场的 32 条行选择线接入了一个串入并出移位寄存器,使用 ABC 三条信号线作为移位寄存器的数据、时钟、锁存信号,相当于直接把上面的简化版行选择直接集成进了单元板,这直接导致了我找到的所有关于 HUB75 的资料全都跑不通。最后我根据芯片型号找到手册、用万用表一个一个焊点试验摸出走线才把这块单元板的驱动原理摸通。询问卖家有没有资料,卖家只说不兼容市面上的控制器(所有卖家都这么说,不知道是不是为了让你买他们家的控制器),完全不提供任何技术支持,这个就是最大的坑——单元板拿到手之前,你永远不知道它到底该怎么用。
参考资料
https://github.com/hzeller/rpi-rgb-led-matrix/issues/956
https://bikerglen.com/projects/lighting/led-panel-1up/
https://www.sparkfun.com/news/2650