前回、pico → ラズパイの通信に成功したので
第2回のプログラムと組み合わせて、双方向通信に挑戦
ラズパイ側の送信部分は第2回のものとほぼ同じですが
ボタンを押し続けたとき、離し続けた時に通信が連続的に行われないよう
少しだけコードを追加 (38-40行、49-52行)
それ以外はほぼ、第2回と第3回のコードの組み合わせです
"""
*** コメントの大半は Github Copilot によって生成されたものです ***
ラズパイとPicoの間でUARTを使って双方向通信
ラズパイ(リモコン)側プログラム
ラズパイにつないだボタンの状態をPicoに送り、Picoからの応答を受け取って表示する
"""
import serial
import fcntl
import RPi.GPIO as GPIO
from gpiozero import Button
import time
# ===== 定数定義 =====
BAUD_RATE = 9600
UART_TIMEOUT = 1.0 # シリアル受信のタイムアウト時間(秒)
LOOP_INTERVAL = 0.01 # メインループの実行間隔(秒)
BUTTON_INPUT_PIN = 17 # ボタン入力ピン(GPIO 17 = Raspberry Pi pin 11)
# ===== ボタン状態の定義 =====
STATUS_ON = 1 # ボタンが押された状態
STATUS_OFF = 0 # ボタンが離された状態
prev_onoff_status = STATUS_OFF # 前回のボタン状態
# ===== GPIO 初期化 =====
GPIO.setmode(GPIO.BCM)
button = Button(BUTTON_INPUT_PIN)
# ===== シリアルポート初期化 =====
lock = open('/tmp/ttyS0.lock', 'w') # シリアルポート用ロックファイルを開く
fcntl.flock(lock, fcntl.LOCK_EX) # 排他ロックを取得(他のプロセスからのアクセスを防止)
ser = serial.Serial('/dev/serial0', BAUD_RATE, timeout=UART_TIMEOUT)
try:
while True:
if button.is_pressed:
# ボタンが押されし続けた場合に1を送り続けないようにする
if prev_onoff_status == STATUS_OFF:
prev_onoff_status = STATUS_ON
ser.write(b'1')
# Picoからの応答を受信
received_data = ser.readline()
print_data = received_data.decode('utf-8').rstrip('\n')
print(f"pico から受信: {print_data}")
else:
# ボタンが離され続けた場合に0を送り続けないようにする
if prev_onoff_status == STATUS_ON:
prev_onoff_status = STATUS_OFF
ser.write(b'0')
time.sleep(LOOP_INTERVAL)
finally:
# ===== 終了処理 =====
ser.close()
fcntl.flock(lock, fcntl.LOCK_UN) # ロックファイルのロックを解除
lock.close()
pico 側のプログラムも、ほぼ第2回と第3回の組み合わせです
"""
*** コメントの大半は Github Copilot によって生成されたものです ***
ラズパイとPicoの間でUARTを使って双方向通信
pico(本体)側プログラム
ラズパイにつないだボタンの状態をPicoで受け取り、'1' を受け取った回数をラズパイに送る
"""
from machine import UART, Pin
import time
# ===== 定数定義 =====
BAUD_RATE = 9600 # シリアル通信のボーレート
UART_TIMEOUT = 1.0 # UART受信のタイムアウト時間(秒)
LOOP_INTERVAL = 0.05 # メインループの実行間隔(秒)
LED_PIN = 15 # GPIO 15 = RP-pico pin 20
# ===== LED初期化 =====
led = Pin(LED_PIN, Pin.OUT)
# ===== LED状態とカウンター =====
LED_ON = 1
LED_OFF = 0
on_count = 0 # Picoが受け取った'1'の総数
# ===== UART通信初期化 =====
uart = UART(0, baudrate=BAUD_RATE, tx=Pin(0), rx=Pin(1))
# ===== メインループ =====
while True:
if uart.any():
data = uart.read(1)
if data == b'1': # Raspberry Pi側のボタンが押された場合
led.value(LED_ON)
# 現在のカウンター値をRaspberry Piに送信
uart.write(f"count: {on_count}\n".encode('utf-8'))
on_count += 1
if data == b'0': # Raspberry Pi側のボタンが離された場合
led.value(LED_OFF)
time.sleep(LOOP_INTERVAL)
つづいてタクトスイッチのチャタリング対策で
ラズパイ側のLOOP_INTERVAL値の調整
の予定だったのですが、インターバル 10ms でチャタリングが見られませんでした
ちょっと驚き
ここまでで解った事。
ラズパイはOSが動いているので、受信がちょっと難しい
ラズパイ zero W を使ってリモコンを作る事を考えていました
リモコンから送信だけなら、それでも問題なさそうですが
pico の電池残量をリモコンに表示したいので
双方向通信が欲しい
なので、ラズパイ zero W をリモコンにする予定を変更
リモコンも pico で作る事にしました
次回は pico と pico で双方向通信に挑戦です。

コメント