电子发烧友App

硬声App

0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示
电子发烧友网>电子资料下载>电子资料>RGB LED矩阵面板开源项目

RGB LED矩阵面板开源项目

2023-07-12 | zip | 0.00 MB | 次下载 | 免费

资料介绍

描述

介绍

近年来,RGB LED 矩阵面板的使用变得流行起来。您是这些面板的爱好者之一吗?您是否希望为您的项目添加很多颜色?这些巨大的 RGB LED 矩阵面板是一个很棒的起点。您可以使用它们创建动画、游戏或各种其他有趣的显示。最重要的是,得益于两个 IDC 连接器和一个无缝框架,这些面板可以菊花链式连接在一起,形成更大的 LED 显示屏。在本教程中,我们将学习如何使用这些面板。本教程由 7 个部分组成。留在我身边。

如何?

如前所述,在本教程中,我们将学习如何设置这些面板。现在,如何将这些面板之一连接到 Raspberry Pi根据Henner Zeller的教程,连接一个面板需要 16 个连接,这会使它变得更难。看下面的图片!连接这些电线非常混乱。

 
 
 
 
pYYBAGO0HLmAIMNSAAI9Pl25Wzs991.jpg
 
1 / 2需要连接 16 根电线,这很混乱。
 

解决办法是什么?

摆脱这些电线的最佳方法是使用替代驱动板。RGB矩阵面板驱动板ElectroDragon团队基于Henner Zeller RPI矩阵的有源转接板设计的。

 
 
 
 
poYBAGO0HL6AFuveAAXYxGkKrDc840.jpg
 
1 / 6ElectroDragon RGB 矩阵面板驱动板
 

特征:

  • 非常便宜,只要2.5美元!
  • 最多支持三个端口输出到驱动器,P0,P1和P2(HUB75)。
  • 支持Raspberry Pi 2 and 3 & Zero,大部分管脚用于矩阵驱动。
  • 支持 E 线选择引脚(适用于 64x64 RGB 矩阵面板)。
  • 板载四个逻辑缓冲器74HCT245。通过I2C接口外接板载RTC DS1307,不可与P3口同时使用,通过开关选择。
  • 额外的板载 AT24C256 EEPROM,替代 I2C 25 和 26 引脚上的 256K 内存。Raspberry PI 3 无法支持替代 I2C 接口,因此只能使用 Raspberry Pi 2。
  • 完全兼容hzeller 适配板

电源供应

树莓派上安装ElectroDragon驱动板后,需要注意的是:还需要一个5V的电源,给矩阵本身供电,树莓派做不到,计算功率,乘以所有链式矩阵的宽度* 0.12 安培:一个 32 像素宽的矩阵最终可以消耗 32*0.12 = 3.85A,因此使用 5V 4A 电源。LED 矩阵面板需要 5V 电源而且很多!至少 5V 2A,您很容易需要 5V 4A 或 5V 10A 电源用于大面积面板!

每个矩阵一次点亮 64 个像素(16x32 或 32x32 面板)或 128 个像素(对于 32x64 面板)。如果全白,每个像素最多可消耗 0.06 安培。因此,每个面板的总最大电流为 64 * 0.06 = 3.95 安培或 128 * 0.06 = 7.68 安培。如果所有 LED 都同时亮起,这不太可能 - 但至少有一半用于电源是好的万一你变亮了。

安装库

在本节中,我们将简要说明如何安装hzeller 库根据hzeller推荐:推荐使用Raspbian Lite发行版。

安装先决条件

sudo apt-get install -y --force-yespython2.7-dev python-pillow python3-dev python3-pillow libgraphicsmagick++-devlibwebp-dev

安装库

git clone https://github.com/hzeller/rpi-rgb-led-matrix.git
cd rpi-rgb-led-matrix
make all
make build-python
make install-python

为 RTC 启用 I2C

要在 Raspberry Pi 中启用 I2C,请使用以下教程:

https://learn.sparkfun.com/tutorials/raspberry-pi-spi-and-i2c-tutorial#i2c-on-pi

将矩阵面板安装到 RPi

有多种类型的显示器都带有相同的 Hub75 连接器。它们在多路复用发生的方式上有所不同。矩阵面板与驱动板的连接需要IDC线。这些可以通过将一个面板的输出连接到下一个面板的输入来链接。你可以把很多链接在一起。

 
pYYBAGO0HMCAWlkLAAC1wwZa1s0473.png
支持的面板列表。
 

64x64 矩阵通常有两种类型:具有 5 条地址线(A、B、C、D、E)或(A、B)。所谓的“户外面板”通常更亮,并且在相同尺寸下允许更快的刷新率,但在内部进行了一些多路复用,其中有几种类型;可以使用--led-multiplexing参数选择它们。

通常,较高的扫描速率(例如 1:8),即室外面板通常允许更快的刷新率,但如果所提供的三个之一不起作用,您可能需要弄清楚多路复用映射。

 
poYBAGO0HMKAebzeAAB8-k4jUoY143.png
创建链
 

正如您在下图中看到的,您只能将 3 个矩阵面板排成一排连接到驱动板。(这是由于 Raspberry Pi GPIO 的限制。)

 
poYBAGO0HL6AFuveAAXYxGkKrDc840.jpg
只能同时控制三个面板(成行)。
 

如果您连接了多个矩阵面板,在这种情况下,有必要运行带有参数的示例,请参阅hzeller 说明

在本教程中,我将两个矩阵面板 32x32 和 64x64(分别)连接到驱动板。如果地址行少于 5,则无需更改。(例如:32x32 和更小的面板)。但如前所述,对于 64x64 面板,引脚 8 应连接到驱动板上的引脚 E。

 
pYYBAGO0HMmAVgTeAANpWE-AMBY309.jpg
使用 64x64 面板时,应连接这两个引脚。
 

最好选择C、C++语言,执行速度快。

 

示例 #1:使用 Python 滚动新闻

在这个例子中,一个站点的新闻(RSS 提要)被下载并显示在矩阵面板上。这个例子是用 Python 写的。要运行,您必须将三个文件(其中一个文件是附在底部的 ttf 字体)传输到Python samples 文件夹

scroll.py文件 :

#!/usr/bin/env python
# -*- encoding:utf8 -*-
# By: Ramin Sangesari
import time
import argparse
import sys
import os
import random
import feedparser
from PIL import Image
from PIL import ImageFont
from PIL import Image
from PIL import ImageDraw
from logging import getLogger, StreamHandler, DEBUG
logger = getLogger(__name__)
handler = StreamHandler()
handler.setLevel(DEBUG)
logger.setLevel(DEBUG)
logger.addHandler(handler)
logger.propagate = False
sys.path.append(os.path.abspath(os.path.dirname(__file__) + '/..'))
from rgbmatrix import RGBMatrix, RGBMatrixOptions
def run(image, matrix):
   print("Running...")
   image.resize((matrix.width, matrix.height), Image.ANTIALIAS)
   double_buffer = matrix.CreateFrameCanvas()
   img_width, img_height = image.size
   xpos = 0
   while True:
       xpos += 1
       if (xpos > img_width):
           xpos = 0
           break
       double_buffer.SetImage(image, -xpos)
       double_buffer.SetImage(image, -xpos + img_width)
       double_buffer = matrix.SwapOnVSync(double_buffer)
       time.sleep(0.04)
def prepareMatrix(parser):
   args    = parser.parse_args()
   options = RGBMatrixOptions()
   if args.led_gpio_mapping != None:
     options.hardware_mapping = args.led_gpio_mapping
   options.rows = args.led_rows
   options.cols = args.led_cols
   options.chain_length = args.led_chain
   options.parallel = args.led_parallel
   options.pwm_bits = args.led_pwm_bits
   options.brightness = args.led_brightness
   options.pwm_lsb_nanoseconds = args.led_pwm_lsb_nanoseconds
   options.multiplexing = args.led_multiplexing
   if args.led_show_refresh:
     options.show_refresh_rate = 1
   if args.led_slowdown_gpio != None:
       options.gpio_slowdown = args.led_slowdown_gpio
   if args.led_no_hardware_pulse:
     options.disable_hardware_pulsing = True
   return RGBMatrix(options = options)
def getImageFromFile(path):
   image = Image.open(path).convert('RGB')
   return image
parser = argparse.ArgumentParser()
parser.add_argument("-r", "--led-rows", action="store", help="Display rows. 16 for 16x32, 32 for 32x32. Default: 32", default=32, type=int)
parser.add_argument("-t", "--led-cols", action="store", help="Display rows. 16 for 16x32, 32 for 32x32. Default: 32", default=32, type=int)
parser.add_argument("-c", "--led-chain", action="store", help="Daisy-chained boards. Default: 1.", default=1, type=int)
parser.add_argument("-P", "--led-parallel", action="store", help="For Plus-models or RPi2: parallel chains. 1..3. Default: 1", default=1, type=int)
parser.add_argument("-p", "--led-pwm-bits", action="store", help="Bits used for PWM. Something between 1..11. Default: 11", default=11, type=int)
parser.add_argument("-b", "--led-brightness", action="store", help="Sets brightness level. Default: 100. Range: 1..100", default=10, type=int)
parser.add_argument("-m", "--led-gpio-mapping", help="Hardware Mapping: regular, adafruit-hat, adafruit-hat-pwm" , choices=['regular', 'adafruit-hat', 'adafruit-hat-pwm'], type=str)
parser.add_argument("--led-scan-mode", action="store", help="Progressive or interlaced scan. 0 Progressive, 1 Interlaced (default)", default=1, choices=range(2), type=int)
parser.add_argument("--led-pwm-lsb-nanoseconds", action="store", help="Base time-unit for the on-time in the lowest significant bit in nanoseconds. Default: 130", default=130, type=int)
parser.add_argument("--led-show-refresh", action="store_true", help="Shows the current refresh rate of the LED panel")
parser.add_argument("--led-slowdown-gpio", action="store", help="Slow down writing to GPIO. Range: 1..100. Default: 1", choices=range(3), type=int)
parser.add_argument("--led-no-hardware-pulse", action="store", help="Don't use hardware pin-pulse generation")
parser.add_argument("--led-multiplexing", action="store", help="Multiplexing type: 0=direct; 1=strip; 2=checker; 3=spiral (Default: 0)", default=2, type=int)
parser.add_argument("-i", "--image", help="The image to display", default="./news.ppm")
imgdir = os.path.abspath(os.path.dirname(__file__)) + "/newsimg"
matrix = prepareMatrix(parser)
if not os.path.isdir(imgdir):
   print("Error: no img to display, no such directory.")
   sys.exit(0)
else:
   while True:
       files = os.listdir(imgdir)
       if len(files)==0:
           print("Warning: no img to display, I am going to wait news to come.")
           time.sleep(5.0)
       else:
           frnd = random.sample(files,len(files))
           for f in frnd:
               if f[-4:] == '.ppm':
                   f = os.path.join(imgdir, f)
                   try:
                       if os.path.exists(f):
                           run(getImageFromFile(f), matrix)
                       else:
                           print("Warning: no such file, next please...")
                   except IOError:
                       print("Warning: no such file, next please...")
                   except KeyboardInterrupt:
                       print("Exiting\n")
                       sys.exit(0)
               else:
                   printf("Warning: Please do not include non-ppm files.")
                   sys.exit(0)

rss.py文件:

#!/usr/bin/env python
# -*- coding: utf-8 -*-
# By : Ramin Sangesari
import datetime
import time
import argparse
import sys
import os
import random
import feedparser
import hashlib
from glob import glob
from PIL import Image
from PIL import ImageFont
from PIL import ImageDraw
import urllib2
from bs4 import BeautifulSoup
from logging import getLogger, StreamHandler, DEBUG
logger = getLogger(__name__)
handler = StreamHandler()
handler.setLevel(DEBUG)
logger.setLevel(DEBUG)
logger.addHandler(handler)
logger.propagate = False
sys.path.append(os.path.abspath(os.path.dirname(__file__) + '/..'))
Imgformat = '.ppm'
def isOkToCrawl():
    crawl_interval = 5 #sec.
    crawl_interval_file = "./lastcrawl"
    now = time.time()
    if os.path.isfile(crawl_interval_file):
        if os.stat(crawl_interval_file).st_mtime > now - crawl_interval:
            return False
    
    f = open(crawl_interval_file, 'w')
    f.write(str(now) + "\n")
    f.close()
    return True
	
def getImageFromFile(path):
    image = Image.open(path).convert('RGB')
    return image
	
def saveImgFromText(text, imgdir, fontsize):
    path = os.path.abspath(os.path.dirname(__file__))
    print path
    if fontsize == 20:
        font  = [ImageFont.truetype(path + '/VERDANA.TTF', fontsize),2]
    color  = [(255,0,255),
             (0,255,255),
             (255,255,0),
             (0,255,0),
             (255,255,255)]
    width, ignore = font[0].getsize(text)
    im = Image.new("RGB", (width + 40, fontsize+40), "black")
    draw = ImageDraw.Draw(im)
    draw.text((0, font[1]), text, random.choice(color), font=font[0])
    imgname = imgdir+"/"+str(fontsize)+str(hashlib.md5(text.encode('utf_8')).hexdigest())+Imgformat
    if not os.path.exists(imgname):
        im.save(imgname)
		
		
def removeOldImg(imgdir):
    #remove ppm files more than 1 days before.
    if not(imgdir=="") and not(imgdir=="/")and not(imgdir=="."): 
        now = time.time()
        for f in os.listdir(imgdir):
            if f[-4:] == '.ppm':
                f = os.path.join(imgdir, f)
                if os.stat(f).st_mtime < now - 0.5 * 86400:
                    if os.path.isfile(f):
                        os.remove(f)
						
						
def getNewsFromFeed():
    news  = []
    url = ['http://www.france24.com/en/top-stories/rss']
    for tg in url:
        fd = feedparser.parse(tg)
        for ent in fd.entries:
            news.append(u"          "+unicode(ent.title))
    return news
	
			
parser = argparse.ArgumentParser()
if isOkToCrawl():
    
    imgdir = os.path.abspath(os.path.dirname(__file__)) + "/newsimg"
    print imgdir
    if not os.path.isdir(imgdir):
        os.mkdir(imgdir)
    #clean up old news
    removeOldImg(imgdir)
    #get from RSS feed
    for text in getNewsFromFeed():
        saveImgFromText(text, imgdir, 20)
else:
    print ("You need to wait for 1min before next crawl.")

现在运行以下命令:

python rss.py & sudo python scroll.py

 

示例 #2:使用 C 显示随机效应

下面是 C 语言的例子。打开examples-api-use目录minimal-example.cc中的文件并复制以下代码。

// Small example how to use the library.
// By: Ramin Sangesari
#include "led-matrix.h"
#include 
#include 
#include 
#include 
using rgb_matrix::GPIO;
using rgb_matrix::RGBMatrix;
using rgb_matrix::Canvas;
uint8_t buffer[64][64][3] = { 0 };
unsigned long step = 0;
volatile bool interrupt_received = false;
static void InterruptHandler(int signo) {
 interrupt_received = true;
}
static void setPixelp(uint8_t x, uint8_t y, float r, float g, float b) {
 buffer[y][x][0] = uint8_t(std::max(0, std::min(255, int(r))));
 buffer[y][x][1] = uint8_t(std::max(0, std::min(255, int(g))));
 buffer[y][x][2] = uint8_t(std::max(0, std::min(255, int(b))));
}
static void HSVtoRGB(float& r, float& g, float& b, float h, float s, float v) {
 if (s == 0.0) {
   r = v;
   g = v;
   b = v;
 }
 int i = int(h * 6.0);
 float f = (h * 6.0) - i;
 float p = v * (1.0 - s);
 float q = v * (1.0 - s * f);
 float t = v * (1.0 - s * (1.0 - f));
 i = i % 6;
 if (i == 0) {
   r = v; g = t; b = p; return; // v, t, p  
 }
 if (i == 1) {
   r = q; g = v; b = p; return; // q, v, p
 }
 if (i == 2) {
   r = p; g = v; b = t; return; // p, v, t
 }
 if (i == 3) {
   r = p; g = q; b = v; return; // p, q, v
 }
 if (i == 4) {
   r = t; g = p; b = v; return; // t, p, v
 }
 if (i == 5) {
   r = v; g = p; b = q; return; // v, p, q
 }
}
void swirl(uint8_t x, uint8_t y, unsigned long step) {
 float fx = x - 31.5;
 float fy = y - 31.5;
 float dist = sqrt(fx * fx + fy * fy) * 0.5;
 float angle = (step * 0.1) + (dist * 1.5);
 float s = sin(angle);
 float c = cos(angle);
 float xs = x * c - y * s;
 float ys = x * s + y * c;
 float r = abs(xs + ys) * 12.0 - 20;
 float g = r + (s * 130);
 float b = r + (c * 130);
 setPixelp(x, y,
   r,
   g,
   b
 );
}
void setPixelU(uint8_t x, uint8_t y, uint8_t r, uint8_t g, uint8_t b) {
 buffer[y][x][0] = r;
 buffer[y][x][1] = g;
 buffer[y][x][2] = b;
}
void gradient(uint8_t x, uint8_t  y, unsigned long  step) {
 uint8_t g = x * 64;
 uint8_t b = y * 64;
 uint8_t r = 255 - (x * 64);  
 setPixelU(x, y, r, g, b);
}
void rainbowSearch(uint8_t x, uint8_t y, unsigned long step) {
 float xs = sin((step) * 0.01) * 20.0;
 float ys = cos((step) * 0.01) * 20.0;
 float scale = ((sin(step / 60.0) + 1.0) * 0.2) + 0.2;
 float r = sin((x + xs) * scale) + cos((y + xs) * scale);
 float g = sin((x + xs) * scale) + cos((y + ys) * scale);
 float b = sin((x + ys) * scale) + cos((y + ys) * scale);
 setPixelp(x, y,
   r * 255,
   g * 255,
   b * 255
 );
}
void checker(uint8_t _x, uint8_t _y, unsigned long step) {
 //float x = _x - 8;
 //float y = _y - 8;
 float x = _x - 32;
 float y = _y - 32;
 float angle = step / 5.0;
 float s = sin(angle);
 float c = cos(angle);
 float xs = x * c - y * s;
 float ys = x * s + y * c;
 xs -= sin(step / 200.0) * 40.0;
 ys -= cos(step / 200.0) * 40.0;
 float scale = step % 20;
 scale /= 20.0;
 scale = (sin(step / 50.0) / 8.0) + 0.25;
 xs *= scale;
 ys *= scale;
 float xo = abs(xs) - int(abs(xs));
 float yo = abs(ys) - int(abs(ys));
 //  l = 0 if @ else 1 if xo > .1 and  else .5
 float l = int(floor(xs) + floor(ys)) % 2 ? 0 : (xo > 0.1 && yo > .1 ? 1 : 0.5);
 float r, g, b;
 HSVtoRGB(r, g, b, (step % 255) / 255.0, 10, 121);
 setPixelU(_x, _y,
   r * (l * 255),
   g * (l * 255),
   b * (l * 255)
 );
}
static void DrawOnCanvas2(Canvas *canvas) {
 /*
  * Let's create a simple animation. We use the canvas to draw
  * pixels. We wait between each step to have a slower animation.
  */
while (true)  {
 for (uint8_t x = 0; x < 64; x++) {
   for (uint8_t y = 0; y < 64; y++) {
     rainbowSearch(x, y, step);
   }
 }
 for (int x = 0; x < 64; x++) {
   for (int y = 0; y < 64; y++) {
     for (int c = 0; c < 3; c++) {  
			canvas->SetPixel(x, y, buffer[x][y][c], buffer[x][y][c], buffer[x][y][c]);  
     }
   }
 }
 step++;
}
}
int main(int argc, char *argv[]) {
 RGBMatrix::Options defaults;
 defaults.hardware_mapping = "regular";  // or e.g. "adafruit-hat"
 defaults.rows = 64;
 defaults.chain_length = 1;
 defaults.parallel = 1;
 defaults.show_refresh_rate = true;
 Canvas *canvas = rgb_matrix::CreateMatrixFromFlags(&argc, &argv, &defaults);
 if (canvas == NULL)
   return 1;
 // It is always good to set up a signal handler to cleanly exit when we
 // receive a CTRL-C for instance. The DrawOnCanvas() routine is looking
 // for that.
 signal(SIGTERM, InterruptHandler);
 signal(SIGINT, InterruptHandler);
 DrawOnCanvas2(canvas);    // Using the canvas.
 // Animation finished. Shut down the RGB matrix.
 canvas->Clear();
 delete canvas;
 return 0;
} 

保存文件并使用make命令编译它。要运行演示,请运行以下命令:

sudo ./minimal-example

 


下载该资料的人也在下载 下载该资料的人还在阅读
更多 >

评论

查看更多

下载排行

本周

  1. 1山景DSP芯片AP8248A2数据手册
  2. 1.06 MB  |  532次下载  |  免费
  3. 2RK3399完整板原理图(支持平板,盒子VR)
  4. 3.28 MB  |  339次下载  |  免费
  5. 3TC358743XBG评估板参考手册
  6. 1.36 MB  |  330次下载  |  免费
  7. 4DFM软件使用教程
  8. 0.84 MB  |  295次下载  |  免费
  9. 5元宇宙深度解析—未来的未来-风口还是泡沫
  10. 6.40 MB  |  227次下载  |  免费
  11. 6迪文DGUS开发指南
  12. 31.67 MB  |  194次下载  |  免费
  13. 7元宇宙底层硬件系列报告
  14. 13.42 MB  |  182次下载  |  免费
  15. 8FP5207XR-G1中文应用手册
  16. 1.09 MB  |  178次下载  |  免费

本月

  1. 1OrCAD10.5下载OrCAD10.5中文版软件
  2. 0.00 MB  |  234315次下载  |  免费
  3. 2555集成电路应用800例(新编版)
  4. 0.00 MB  |  33566次下载  |  免费
  5. 3接口电路图大全
  6. 未知  |  30323次下载  |  免费
  7. 4开关电源设计实例指南
  8. 未知  |  21549次下载  |  免费
  9. 5电气工程师手册免费下载(新编第二版pdf电子书)
  10. 0.00 MB  |  15349次下载  |  免费
  11. 6数字电路基础pdf(下载)
  12. 未知  |  13750次下载  |  免费
  13. 7电子制作实例集锦 下载
  14. 未知  |  8113次下载  |  免费
  15. 8《LED驱动电路设计》 温德尔著
  16. 0.00 MB  |  6656次下载  |  免费

总榜

  1. 1matlab软件下载入口
  2. 未知  |  935054次下载  |  免费
  3. 2protel99se软件下载(可英文版转中文版)
  4. 78.1 MB  |  537798次下载  |  免费
  5. 3MATLAB 7.1 下载 (含软件介绍)
  6. 未知  |  420027次下载  |  免费
  7. 4OrCAD10.5下载OrCAD10.5中文版软件
  8. 0.00 MB  |  234315次下载  |  免费
  9. 5Altium DXP2002下载入口
  10. 未知  |  233046次下载  |  免费
  11. 6电路仿真软件multisim 10.0免费下载
  12. 340992  |  191187次下载  |  免费
  13. 7十天学会AVR单片机与C语言视频教程 下载
  14. 158M  |  183279次下载  |  免费
  15. 8proe5.0野火版下载(中文版免费下载)
  16. 未知  |  138040次下载  |  免费