今回は、前回実現した、スイッチ押下時に LED 点灯、に加えて OLED ディスプレイに文字やプログレスバーを表示させます。
その前に、OLED ディスプレイ用の Python ライブラリ(拡張)を準備し、それに合わせて VS code の設定を少し調整する手順も紹介します。
- 目次 -
Python ライブラリと仮想環境(venv)の準備
Python ライブラリって?
Python もそうですが、一から全ての機能をプログラミングするのはとても大変なことです。そこで、大抵のプログラミング言語には「ライブラリ」とか「モジュール」とかの呼び名で、よく使う機能、特定の電子パーツに特化した機能等を関数化してまとめた「拡張」が用意されています。
難しいですね(笑)。でも、実は前回作成したコードに、すでにこの仕組みを使っています。例えば
# タイマー用時刻取得拡張
import time
の部分で、既に OS にインストール済みである「time」というライブラリを使いますよ、と宣言しています。この宣言が無いと、素の Python では
# LED1点灯
LEDPIN1.on()
time.sleep(1)
の「time.sleep(1)」でエラーになります。
venv 仮想環境準備と OLED ディスプレイ制御用ライブラリのインストール
前回「git clone」でホームディレクトリ直下 OLED ディレクトリにクローンした、購入した「汎用 UI 基板」のサンプルスクリプトに混じって「説明図書」のディレクトリがあります。
その中の「インストール_Bookworm.txt」を読んでみましょう。
……難しいですね(笑)。要は Python でライブラリを新しくインストールするには「pip」コマンドを使うのですが、そのまま実行するとライブラリの依存関係が壊れたりするので、専用の「仮想環境」を作って、その中で安全にインストールするよう、Python の仕様が変わった、ということらしいです。
と言うわけで、早速作ってみましょう。説明書では「V_OLED」という名前で仮想環境を作っていますが、今回は「V_CAM」という名前で作ります。
LXTerminal を立ち上げて、
python3 -m venv V_CAM
source V_CAM/bin/activate
pip3 install luma.core
pip3 install luma.oled
と進めます。
と「インストール_Bookworm.txt」にはここまでしか書いていませんが、前回のコードを思い出して下さい。
# ボタンスイッチ用 gpio 拡張
from gpiozero import Button
と「gpiozero」という拡張も読み込んでいました。
なので続けて、
pip3 install gpiozero
pip3 install lgpio
も実行しておきます。
これで一応 Python 仮想環境の構築は終わりましたので仮想環境を抜けます。
deactivate
後は OLED ディスプレイ表示用フォントのインストールです。
sudo apt-get install fonts-dejavu
sudo apt-get install fonts-ipafont
試しに早速、OLED ディスプレイのサンプルスクリプトを実行して見ましょう。
cd OLED
../V_CAM/bin/python OLED_03.py
なんと、プログレスバー的な表示が含まれてますね。これは使えそう(笑)。
VS code の設定を調整
上記サンプルスクリプトの実行例から分かるとおり、仮想環境中の Python を使用する必要がありますので、そのことを VS code に設定しなければなりません。
デフォルトの設定をいじるのはちょっと……という方は「プロファイル」機能を利用しましょう。
左下の歯車アイコンから「プロファイル」→「プロファイルの作成」を選び、コピー元として「規定」を選びます。プロファイル名は「CAM」にしました。
次に、新しいプロファイルで「設定」→「拡張機能」→「Default Interprinter Path」で「python」になっているのを、「/home/pi/V_CAM/bin/python3」にしておきます。
今日の開発
まずはスクリプトファイルのコピー
前回書いたスクリプトにそのまま書き足していっても良いのですが、訳が分からなくなったときにいつでも手戻りできるよう、「cam_02.py」というファイル名でコピーを作り、そこに書き足していきます。
コーディング
今回の成果物です。
#!/home/pi/V_CAM/bin/python3
"""
###########################################################################
カメラで静止画、動画を撮影する。
#Filename :cam.py
#Update :2024/07/15
2024/07/15 Ver. α 0.02 OLED に文字、プログレスバー表示
2024/07/06 Ver. α 0.01 SW ブッシュ で LED 点灯
############################################################################
"""
# タイマー用時刻取得拡張
import time
# ボタンスイッチ用 gpio 拡張
from gpiozero import Button
# ボタンスイッチ初期設定
SW_1 = Button(5,pull_up=False)
SW_2 = Button(6,pull_up=False)
# LED 用拡張
from gpiozero import LED
# LED 初期設定
LEDPIN1 = LED(17)
LEDPIN2 = LED(27)
# OLED ディスプレイ用拡張
from luma.core.interface.serial import i2c
from luma.core.render import canvas
from luma.oled.device import ssd1306
# OLED ディスプレイ用初期設定
# Raspberry Pi 4以降の場合、port=1を指定
serial = i2c(port=1, address=0x3C)
# その他の初期化パラメータを設定(必要に応じて)
device = ssd1306(serial, width=128, height=32) # 必要に応じ64
from PIL import ImageFont
def oled_text(text,size):
# フォントを指定
font = ImageFont.truetype("fonts-japanese-gothic.ttf", size)
with canvas(device) as draw:
draw.text((0, 0), text, font=font, fill="white")
def oled_square(x1,y1,x2,y2,color):
if color == 0:
#矩形の描画:
with canvas(device) as draw:
draw.rectangle((x1,y1,x2,y2), outline="white",fill="black")
if color == 1:
#矩形の描画:
with canvas(device) as draw:
draw.rectangle((x1,y1,x2,y2), outline="white",fill="white")
#print message at the begining ---custom function
def print_message():
print ('|********************************|')
print ('| カメラ撮影(Still & Movie) |')
print ('|********************************|\n')
print ('Program is running...')
print ('Press Green Switch = Still')
print ('Press Red Switch = Movie')
print ('Please press Ctrl+C to end the program...')
# Switch 状態把握
#read SW_PI_1's level
def ReadSW_1():
if SW_1.is_pressed:
sw_ = 'on'
else:
sw_ = 'off'
return sw_
#read SW_PI_2's level
def ReadSW_2():
if SW_2.is_pressed:
sw_ = 'on'
else:
sw_ = 'off'
return sw_
#main function
def main():
loop_n = 0
# Switch状態初期化
sw_ = 'off'
# 初期メッセージ表示
print_message()
# ループ処理開始
while True:
# スイッチ1状態取得
sw_ = ReadSW_1()
# スイッチ1プッシュ時
if sw_ =='on':
# LED1点灯
LEDPIN1.on()
# OLED ディスプレイ文字出力
text = "静止画撮影!"
oled_text(text,22)
time.sleep(1)
# LED1消灯
LEDPIN1.off()
# 1秒待って OLED ディスプレイクリア
time.sleep(1)
device.clear()
# break
# スイッチ2状態取得
sw_ = ReadSW_2()
# スイッチ2プッシュ時
if sw_ =='on':
# LED2点灯
LEDPIN2.on()
# プログレスバー描画
for x in range(0,127,1):
oled_square(0, 10, x, 21,1)
time.sleep(0.1)
# time.sleep( rec_time )
# OLED ディスプレイクリア
device.clear()
# LED2消灯
LEDPIN2.off()
# break
pass
# ループ処理ここまで
#
# if run this script directly ,do:
if __name__ == '__main__':
try:
main()
#when 'Ctrl+C' is pressed,child program destroy() will be executed.
except KeyboardInterrupt:
pass
except ValueError as e:
print(e)
基本は、サンプルコード OLED_01.py、OLED_03.py を参考にしています。
OLED ディスプレイ回りの初期設定が少し難しいですね。
さて次回は、いよいよカメラモジュールの接続です。