スクロールサイネージ（Raspberry Pi Zero W、カラーLED 32x32dot）



[![カラーLEDマトリクスパネル（Raspberry Pi Zero W、32x32dot）](http://img.youtube.com/vi/3H-lxXOf_OA/0.jpg)](http://www.youtube.com/watch?v=3H-lxXOf_OA)

YouTube　スクロールサイネージ動画　(http://www.youtube.com/watch?v=3H-lxXOf_OA)

# はじめに
本文書は、Adafruit 社（ https://www.adafruit.com/ ）の、LEDマトリクスパネルで、画像のスクロールサイネージをした際の情報をまとめたものです。

（１）Raspberry Pi Zero W
（２）Adafruit RGB Matrix Bonnet for Raspberry Pi
の組み合わせは制御部が小さく、全体がコンパクトになります。
展示会ブース等でデジタルサイネージを、小さなスペースで行えます。

本文書の続編では カラーLED 64x64dot も動かしています。
スクロールサイネージ（カラーLED 64x64dot、Raspberry Pi Zero W）
https://qiita.com/tshimizu8/items/daa4bbbbb81c9ffaae41

# ハードウェア
## Raspberry Pi Zero W　(66.0x30.5x5.0 mm)　$10.00
![image.png](https://qiita-image-store.s3.amazonaws.com/0/78212/c03cbc8a-d801-f2ec-9db5-dc2ca75bc0c3.png)
 Raspberry Pi Zero W　画像　(Adafruit　https://www.adafruit.com/product/3400)

## Adafruit RGB Matrix Bonnet for Raspberry Pi　(66.2x30.7x17.2 mm)　$14.95
![image.png](https://qiita-image-store.s3.amazonaws.com/0/78212/4644f268-1075-8c15-478c-02acb6cd1540.png)
Adafruit RGB Matrix Bonnet for Raspberry Pi　画像　(Adafruit　https://www.adafruit.com/product/3211)

マニュアル　Adafruit RGB Matrix Bonnet for Raspberry Pi 24ページ
https://cdn-learn.adafruit.com/downloads/pdf/adafruit-rgb-matrix-bonnet-for-raspberry-pi.pdf?timestamp=1541830799

pin アサイン

| LED-Panel       |       Raspberry Pi  |    
|:-----------------|------------------:|
|GND            |              ground |            
|R1 (Red 1st bank)         |GPIO 17 |        
|G1 (Green 1st bank)       |GPIO 18 |          
|B1 (Blue 1st bank)        |GPIO 22 |            
|R2 (Red 2nd bank)         |GPIO 23 |         
|G2 (Green 2nd bank)       |GPIO 24 |          
|B2 (Blue 2nd bank)        |GPIO 25 |           
|A, B, C, D (Row address)  | GPIO 7, 8, 9, 10 |          
|OE- (neg. Output enable) |GPIO 2 (Rev 2 RPi) or GPIO 0 (Rev 1 RPi) |            |
|CLK (Serial clock)|GPIO 3 (Rev 2 RPi) or GPIO 1 (Rev 1 RPi)|
|STR (Strobe row data) | GPIO 4          |

## 32x32 RGB LED Matrix Panel - 5mm Pitch　(167.6x167.6 mm)　$44.95

![image.png](https://qiita-image-store.s3.amazonaws.com/0/78212/e7791ac4-e696-725a-b635-ee8d2aa38145.png)
![image.png](https://qiita-image-store.s3.amazonaws.com/0/78212/5bdac698-c65c-ef1d-aeac-3b30881cb02f.png)
32x32 RGB LED Matrix Panel 表裏 画像　(Adafruit　https://www.adafruit.com/product/2026)




### LEDマトリクスパネルの種類（Adafruit） 2018/11
#### 32x16  
|  Size(led)|       Pitch(mm)|      Price($)|   Remarks|    Url| 
|:-----------------:|------------------:|------------------:|------------------:|:------------------:|
| 32x16              |                6|         24.95        |192x96mm|https://www.adafruit.com/product/420

#### 32x32  
|  Size(led)|       Pitch(mm)|      Price($)|   Remarks|    Url| 
|:-----------------:|------------------:|------------------:|------------------:|:------------------:|
| 32x32            |              4 |       49.95       |128x128mm|https://www.adafruit.com/product/607
| 32x32            |              5 |        44.95      |167.6x167.6mm|https://www.adafruit.com/product/2026
| 32x32            |              6 |         39.95      |190.5x190.5mm|https://www.adafruit.com/product/1484


#### 64x32  
|  Size(led)|       Pitch(mm)|      Price($)|   Remarks|    Url| 
|:-----------------:|------------------:|------------------:|------------------:|:------------------:|
| 64x32            |              3 |        89.95        ||https://www.adafruit.com/product/2279
| 64x32            |              4 |        79.95      ||https://www.adafruit.com/product/2278
| 64x32            |              5 |        79.95        ||https://www.adafruit.com/product/2277
| 64x32            |              6 |        84.95        ||https://www.adafruit.com/product/2276
| 64x32            |              4 |        99.95     | Flexible|https://www.adafruit.com/product/3826
| 64x32            |              5 |        109.95       | Flexible|https://www.adafruit.com/product/3803


#### 64x64 

|  Size(led)|       Pitch(mm)|      Price($)|   Remarks|    Url| 
|:-----------------:|------------------:|------------------:|------------------:|:------------------:|
| 64x64             |              2.5 |        74.95        |160x160mm,1/32s|https://www.adafruit.com/product/3649

## ＡＣアダプター　
５Ｖ６．２Ａ　ＬＴＥ３６ＥＳ－Ｓ１－３０１　[LTE36ES-S1-301]　￥1,600　秋月電子
プラグ寸法：２．１Φｘ５．５ｘ９．５ｍｍ、コネクタ：フォーク形　http://akizukidenshi.com/catalog/g/gM-11105/

# ソフトウェア

「Adafruit RGB Matrix Bonnet for Raspberry Pi」マニュアルに従い作業をすると、つぎのデモプログラムとPythonサンプルプログラムがインストールされます。

## デモプログラム　メニュー
Controlling RGB LED display with Raspberry Pi GPIO
https://github.com/adafruit/rpi-rgb-led-matrix

 Demos, choosen with -D
     0  - some rotating square
     1  - forward scrolling an image
     2  - backward scrolling an image
     3  - test image: a square
     4  - Pulsing color
     5  - Grayscale Block
     6  - Abelian sandpile model (-m <time-step-ms>)
     7  - Conway's game of life (-m <time-step-ms>)
     8  - Langton's ant (-m <time-step-ms>)
     9  - Volume bars (-m <time-step-ms>)

## Python サンプルプログラム（main）

```Python:image-scroller.py
#!/usr/bin/env python
import time
from samplebase import SampleBase
from PIL import Image


class ImageScroller(SampleBase):
    def __init__(self, *args, **kwargs):
        super(ImageScroller, self).__init__(*args, **kwargs)
        self.parser.add_argument("-i", "--image", help="The image to display", default="../../../examples-api-use/runtext.ppm")

    def run(self):
        if not 'image' in self.__dict__:
            self.image = Image.open(self.args.image).convert('RGB')
        self.image.resize((self.matrix.width, self.matrix.height), Image.ANTIALIAS)

        double_buffer = self.matrix.CreateFrameCanvas()
        img_width, img_height = self.image.size

        # let's scroll
        xpos = 0
        while True:
            xpos += 1
            if (xpos > img_width):
                xpos = 0

            double_buffer.SetImage(self.image, -xpos)
            double_buffer.SetImage(self.image, -xpos + img_width)

            double_buffer = self.matrix.SwapOnVSync(double_buffer)
            time.sleep(0.01)

# Main function
# e.g. call with
#  sudo ./image-scroller.py --chain=4
# if you have a chain of four
if __name__ == "__main__":
    image_scroller = ImageScroller()
    if (not image_scroller.process()):
        image_scroller.print_help()
```

## Python サンプルプログラム（library）

```Python:samplebase.py
import argparse
import time
import sys
import os

sys.path.append(os.path.abspath(os.path.dirname(__file__) + '/..'))
from rgbmatrix import RGBMatrix, RGBMatrixOptions


class SampleBase(object):
    def __init__(self, *args, **kwargs):
        self.parser = argparse.ArgumentParser()

        self.parser.add_argument("-r", "--led-rows", action="store", help="Display rows. 16 for 16x32, 32 for 32x32. Default: 32", default=32, type=int)
        self.parser.add_argument("--led-cols", action="store", help="Panel columns. Typically 32 or 64. (Default: 32)", default=32, type=int)
        self.parser.add_argument("-c", "--led-chain", action="store", help="Daisy-chained boards. Default: 1.", default=1, type=int)
        self.parser.add_argument("-P", "--led-parallel", action="store", help="For Plus-models or RPi2: parallel chains. 1..3. Default: 1", default=1, type=int)
        self.parser.add_argument("-p", "--led-pwm-bits", action="store", help="Bits used for PWM. Something between 1..11. Default: 11", default=11, type=int)
        self.parser.add_argument("-b", "--led-brightness", action="store", help="Sets brightness level. Default: 100. Range: 1..100", default=100, type=int)
        self.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)
        self.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)
        self.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)
        self.parser.add_argument("--led-show-refresh", action="store_true", help="Shows the current refresh rate of the LED panel")
        self.parser.add_argument("--led-slowdown-gpio", action="store", help="Slow down writing to GPIO. Range: 1..100. Default: 1", choices=range(3), type=int)
        self.parser.add_argument("--led-no-hardware-pulse", action="store", help="Don't use hardware pin-pulse generation")
        self.parser.add_argument("--led-rgb-sequence", action="store", help="Switch if your matrix has led colors swapped. Default: RGB", default="RGB", type=str)
        self.parser.add_argument("--led-pixel-mapper", action="store", help="Apply pixel mappers. e.g \"Rotate:90\"", default="", type=str)
        self.parser.add_argument("--led-row-addr-type", action="store", help="0 = default; 1=AB-addressed panels;2=row direct", default=0, type=int, choices=[0,1,2])
        self.parser.add_argument("--led-multiplexing", action="store", help="Multiplexing type: 0=direct; 1=strip; 2=checker; 3=spiral; 4=ZStripe; 5=ZnMirrorZStripe; 6=coreman; 7=Kaler2Scan; 8=ZStripeUneven (Default: 0)", default=0, type=int)

    def usleep(self, value):
        time.sleep(value / 1000000.0)

    def run(self):
        print("Running")

    def process(self):
        self.args = self.parser.parse_args()

        options = RGBMatrixOptions()

        if self.args.led_gpio_mapping != None:
          options.hardware_mapping = self.args.led_gpio_mapping
        options.rows = self.args.led_rows
        options.cols = self.args.led_cols
        options.chain_length = self.args.led_chain
        options.parallel = self.args.led_parallel
        options.row_address_type = self.args.led_row_addr_type
        options.multiplexing = self.args.led_multiplexing
        options.pwm_bits = self.args.led_pwm_bits
        options.brightness = self.args.led_brightness
        options.pwm_lsb_nanoseconds = self.args.led_pwm_lsb_nanoseconds
        options.led_rgb_sequence = self.args.led_rgb_sequence
        options.pixel_mapper_config = self.args.led_pixel_mapper
        if self.args.led_show_refresh:
          options.show_refresh_rate = 1

        if self.args.led_slowdown_gpio != None:
            options.gpio_slowdown = self.args.led_slowdown_gpio
        if self.args.led_no_hardware_pulse:
          options.disable_hardware_pulsing = True

        self.matrix = RGBMatrix(options = options)

        try:
            # Start loop
            print("Press CTRL-C to stop sample")
            self.run()
        except KeyboardInterrupt:
            print("Exiting\n")
            sys.exit(0)

        return True
```
ここで「from rgbmatrix import RGBMatrix, RGBMatrixOptions」
の「RGBMatrix」は、C++「core.cpp」で定義されています。

# 参考情報　
共立エレショップ　32×32 RGB LEDマトリックス　KP-3232D　取扱説明書
http://www.kyohritsu.jp/eclib/PROD/MANUAL/kp3232d.pdf
http://eleshop.jp/shop/g/g402304/

ラズパイ2でLED電光掲示板を作る
https://www.buildinsider.net/small/raspisinage/01