ねこにコベイン

にゃーにゃーにゃー

Raspberry Piにaitendoの3桁7セグLED表示器(SPI)を載せてIPアドレスを表示させる話

事の起こり

aitendoで欲しいものがあってもなかなか通販の最低取り扱い価格のラインである1,000円*1は超えないのが実情だったりして、そういう場合は*2、特売品の小物を漁ったり、ムシャクシャした日にひたすらはんだ付けする用に、欲しくもない白色LEDを買いまくったり、色々すると思います。

そんな中、特売品に3桁7セグLED表示器(SPI)というものを見つけました。


★特売品★3桁7セグLED表示器(SPI) - aitendo
https://www.aitendo.com/product/16510

秋月電子にも同じようなものが売っていますが、

赤色7セグメントLEDシリアルドライバモジュール 完成品: ディスプレイ・表示器 秋月電子通商-電子部品・ネット通販
https://akizukidenshi.com/catalog/g/gM-12642/

SPI制御というシリアル制御で7セグメントのLEDを信号3つで何桁でも制御できちゃうのです。

しかも特売品で198円。
まあ、とりあえず買いますよね。

7セグが3桁あったなら

そりゃあ、IPアドレスを表示しますよね。
特にディスプレイなし運用ラズパイのIPアドレスが分かったら、簡単にSSHで繋げられて良いと思うのです。

ラズパイに物理的に繋げる

ググって次の方のページを見つけました。ページから拝借してきた下の表のとおり繋げます。

Raspberry Pi 4 + Python3入門 (2) 7セグメントLED 74HC595 その2 4桁 | 電子工作の環境向上
https://www.denshi.club/pc/python/raspberry-pi-4-python3-2-7led-74hc595-1-4.html

7セグ ラズパイ
VCC 17番ピン
SDI 19番ピン
GND 20番ピン
SCLK 23番ピン
LOAD 24番ピン

はんだ付けでピンヘッダ立てて、ジャンパでラズパイに繋げます。
ラズパイ側は17~24番ピンと密集しているので、2x5のコネクタ用ハウジングに差し込みました。
コネクタ用ハウジング 2×5 (10P): パーツ一般 秋月電子通商-電子部品・ネット通販
https://akizukidenshi.com/catalog/g/gC-12437/

ラズパイをconfigする

ラズパイでSPI通信を有効にするにはどうすればいい? | 自分でつくる。自宅で野菜を水耕栽培
https://jitaku-yasai.com/home-made/rasp-spi-setting/

# raspi-config

で、Interfaces内のSPIをenableにしておいてください。
もしくは上記ページに従い/boot/config.txtを編集する手もあるようです。
とまれ、これを忘れるとなんにも動きません。

ラズパイのIPアドレスを表示させる

たまたま、電子工作の環境向上のサンプルがPython3で書かれていたのでIPアドレス表示のプログラムはPython3で書くことにします。

なお、7セグはspi制御なのでspidevというやつをpip3でインストールします。

また、IPアドレスを取得してくるところは、Pythonで書いてもbashで書いても面倒くさいところなのですが、*3。今回はググって見つけたipgetというやつを使います。

ipget · PyPI
https://pypi.org/project/ipget/

何も考えずにインターフェイス名を引数に食わせるだけでIPアドレスを吐いてくれるのは素敵ですが、該当のインターフェイスIP reachableじゃない時はエラー吐いて止まったり、微妙にプリミティブな感じです。まあいいんですけど。

# apt install python3-pip
# pip3 install spidev
# pip3 install ipget

適当に、電子工作の環境向上のサンプルをつぎはぎして作ったIPアドレス表示のスクリプトがこちら。

$ nano 7seg.py

(...)

$chmod +x 7seg.py
$ cat 7seg.py

#!/usr/bin/python3
import spidev, time, ipget

spi = spidev.SpiDev()
spi.open(0,0) # CE0
spi.max_speed_hz = 1000000 # 1MHz

#         gfedcba LED segment
dot = ~0b10000000
blank = ~0b00000000
data = [ 0b00111111, 0b00000110, 0b01011011, 0b01001111, 0b01100110,
         0b01101101, 0b01111101, 0b00000111, 0b01111111, 0b01100111 ]

def disp7seg(tempData):
    dispTempData = list(tempData)[::-1] # reversed
    dotFlag =0

    for x in dispTempData:
        if x != '.':
            if dotFlag == 1:
                spi.xfer([~data[int(x)] & dot])
                dotFlag = 0
                continue
            spi.xfer([~data[int(x)]])
            dotFlag = 0
        else: # find dot
            dotFlag = 1

disp7seg("000")

while True:

    try:
        disp7seg(ipget.ipget().ipaddr("eth0").split('.')[0].split('/')[0].zfill(3) + ".")
        time.sleep(1)
        disp7seg(ipget.ipget().ipaddr("eth0").split('.')[1].split('/')[0].zfill(3) + ".")
        time.sleep(1)
        disp7seg(ipget.ipget().ipaddr("eth0").split('.')[2].split('/')[0].zfill(3) + ".")
        time.sleep(1)
        disp7seg(ipget.ipget().ipaddr("eth0").split('.')[3].split('/')[0].zfill(3))
        time.sleep(1)

    except:
        disp7seg("000")
        time.sleep(5)

実行すると、1秒おきにオクテットごと3桁表示されます。第4オクテットだけはピリオドがつかない。
インターフェイスIPアドレスがなければ「000」が表示されます。

うーん、最後の無限ループ内*4がこうやって見るとかなり残念な書きぶりですが、動いてるんでまあいいか。

eth0以外のインターフェイスを表示したいときはここを書き換えてください。

うちのラズパイB+だとtopで見た時のCPU使用率が2%程度。…重いですかね?

サービスにぶち込む。

上記スクリプトが動いたら、適当に/opt配下にでもコピーしてrootに持ち主を替えてみます。
その上でSystemdデーモン化します。ググって参考、もとい丸パクリしたページは次の2つ。

Python3 のスクリプトを Systemd でデーモン化 - からあげ日記
https://karage-ageta.hatenablog.com/entry/2018/02/19/124155

Systemd メモ書き - Qiita
https://qiita.com/a_yasui/items/f2d8b57aa616e523ede4

# mkdir -p /opt/7seg
# cp ~/7seg.py /opt/7seg/
# chown root:root /opt/7seg/7seg.py
# nano /etc/systemd/system/7seg.service

(...)

# cat /etc/systemd/system/7seg.service
[Unit]
Description=IPAddr to 7SEG Script

[Service]
Type=simple
KillMode=control-group
ExecStart=/usr/bin/python3 /opt/7seg/7seg.py
Restart=on-failure
User=root
Group=root

[Install]
WantedBy=multi-user.target

# systemctl start 7seg.service
# systemctl enable 7seg.service
# reboot

これでサービスとして電源ON後しばらくしてから7セグがチャカチャカ変わり始めるはずです。
LANケーブルを引っこ抜くと「000」になって5秒ほどフリーズします。

*1:制限がなくなった。https://www.aitendo.com/news#whatnew_data231

*2:aitendoあるあるですが

*3:そう聞いています

*4:唯一自分で書いた部分