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円。
まあ、とりあえず買いますよね。
ラズパイに物理的に繋げる
ググって次の方のページを見つけました。ページから拝借してきた下の表のとおり繋げます。
Raspberry Pi 4 + Python3入門
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:唯一自分で書いた部分