見出し画像

電子工作ちゃれんじ(とりside)

Twitterのフォロワー、てんななさん(以降えびさん)がなんか色々電子工作で作っているのをみて、『私にもできるかな?』と思って、えびさんのご指導の下、チャレンジしてみた記事です。
えびサイドのnote→EBI電子工作祭り

私の電子工作スキルはほぼゼロ。前回えび家でIchigoJamのLED電子さいころキットを作って遊んだのだけがそれらしい経験です。
あとはRaspberry Pi 3で録画鯖を作って遊んでみたり(結局ほとんど運用しなかった)もありますが、あくまでLinuxサーバーとして運用しただけなので、GPIOを使った本格的な電子工作は今回が初のチャレンジです。

今回の目標は『液晶に自作イラストが表示される電子サイコロを作る』です。結論から言うと、達成できました。やったー!!!(ほとんどえびの力で)

事前準備

・Raspberry Pi Zero W/Hのセットアップ
肝心のPythonコード周りはえびに任せるとして、そのコードを実行する環境を作らないと動かないことはわかっていたので、電子工作会前日に慌ててRaspberry Pi Zero W/Hを開封して、OSのインストールなり、アップデートなりSSHの設定なり諸々しました。ここら辺は遙か昔アンモナイトだった頃の記憶(ラズパイで録画鯖遊び)をしてた時の記憶でなんとかなりました。よかった。
あとはコードを動かす為に、いろいろライブラリとかインストールしたと思うんだけど……正直ここらへんはわかんね!!!
一応自分であれこれググって色々いれてみたのですが、足りないものもあったらしく、それはえびがなんか入れてくれました。ありがとう。
詳細は↓のinstall.sh見ればわかると思う。知らんけど。

・画像の準備
液晶モニタに合わせた画像の仕様に沿って、ランダムに表示される1~6の画像を準備。かわいいニワトリさんの一生です。

さいころ

・パーツの組み立て

結論から言うと、なんとかなりませんでした♡(OLEDディスプレイの配線を間違えて回路を焼いた)
怖いね!電子工作!物理でパーツ(1000円位)が壊れる!!!
今回、半田づけはなしでブスブス電極みたいなのをGPIOに生け花して配線しました。

Pythonコード
俺には何もわからん。えびに聞いてくれ。とぶん投げるのはちょっとアレなので(一応コードの解説も受けたので)復習がてら、えびの書いたコードの自分なりに中身を読んでみる。

# 使用するライブラリの読み込み
from random import choice

from luma.core.interface.serial import i2c
from luma.core.render import canvas
from luma.oled.device import sh1106
from time import sleep
from pathlib import Path
from PIL import Image
from gpiozero import Button

# 変数の定義
BUTTON_GPIO_NUMBER = 18
BACKGROUND_COLOR = "white"

# ↓のURLを参考にしました
# see https://github.com/rm-hull/luma.examples/tree/master/examples

# 画像読み込み
def convert(image_path):
   return Image.open(image_path)

# ランダムに画像を表示する
def display_random_image(image_list, device, button, posn):
   show_image = choice(image_list)
   background = Image.new("RGB", device.size, BACKGROUND_COLOR)
   background.paste(show_image, posn)
   device.display(background.convert(device.mode))

# 液晶周りの設定
def main():
   serial = i2c(port=1, address=0x3C)
   device = sh1106(serial, rotate=2)
   size = [min(*device.size)] * 2
   posn = (0, device.height - size[1])

   # 終了時処理の登録(液晶をクリアする)
   import signal
   def sig_handler(signum, frame) -> None:
       device.cleanup()
       sys.exit(1)
   signal.signal(signal.SIGTERM, sig_handler)
   signal.signal(signal.SIGINT, sig_handler)

   # 画像パスの指定
   current_dir = Path(__file__).parent
   path_list = current_dir.glob('img/*.*')

   image_list = list(map(convert, path_list))

   # ボタンの指定
   button = Button(BUTTON_GPIO_NUMBER)

   # ここがよくわからん(ボタン押された時の処理してるんだと思う)
   with canvas(device) as draw:
       while True:
           while button.is_pressed != True:
               display_random_image(image_list, device, button, posn)
               sleep(0.1)
           display_random_image(image_list, device, button, posn)
           sleep(1)
           button.wait_for_press()
           button.wait_for_release()

if __name__ == "__main__":
   try:
       main()
   except KeyboardInterrupt:
       pass

なるほど。よくわからん。解説してくれたえび先生には申し訳ないですが、また今度、基本的なpythonの文法を学習してから解読したいと思います。

・ボタン長押しで電源を切れるようにしたい

上記の『電子工作で、シャットダウンボタン追加』の項目に従って、実装しました。
新しくシャットダウン用のボタンを追加するのは面倒だったので、サイコロ制御用のボタンを流用。記載されているコードの『GPIO26pin』の部分が『GPIO18pin』になるように変更(26→18と全て置換)しました。
その上で、ラズパイを起動したらシャットダウンプログラムとサイコロプログラムが自動で走るようにしたかったので、以下のように記載。

...

/home/pi/shutdown.py &
python3 /home/pi/lcd-img-random/main.py 

exit 0

/etc/rc.localに以下を記載(/home/pi/shutdown.pyの後に『 &』をつけないと直後のプログラムが走らないので注意)
Raspberry piでOS起動時にPythonのプログラムを実行する方法

そんなこんなで
・電源をいれると自動でサイコロプログラムがはじまり
・ボタンを押すとサイコロが止まり
・もう一度ボタンを押すとサイコロプログラムがはじまり
・ボタンを長押し(5秒)すると、電源が切れる
超高性能(?)心なき冷徹非道なサイコロマシーンが完成しました!!!

やったー!!!!!!!!!!!!!!!!!!!!!!!
次はPythonでGUIを使ったゲームを作るのに挑戦したいです。

この記事が気に入ったらサポートをしてみませんか?