kakepro’s blog

プログラムとかPC周りのことを書いていきます

【RaspberryPi】ボタン入力をしてみる

はじめに

・環境
Raspberrypi 4 B+
Linux raspberrypi 5.10.103-v8+
Distributor ID: Debian
Description: Debian GNU/Linux 10 (buster)
Release: 10
Codename: buster

・やろうと思ったこと
ラズパイで卓上の装置を作ろうとしたときに、GUIではなく
物理的なボタンで運転開始や停止、動作切り替えが出来るようにしたかった
とりあえずラズパイのGPIOピンとタクトスイッチを何個か接続し、
押したボタンごとに異なる動作をさせられるか確認することにした

配線

用意するのは以下の部品
・ラズパイ本体
・ジャンパーワイヤ(オスーメス)×4
・ジャンパーワイヤ(オスーオス)×3
・ブレッドボード
・タクトスイッチ×3

配線図は以下の通り

配線図

使うGPIOピンはGPIO17、18、22とGND

ソースコード

import time
import RPi.GPIO as GPIO

# Callback function
def callback(pin):
  print("callback")

# GPIO No.
SW1       = 18
SW2       = 17
SW3       = 22

# initital setup
GPIO.setmode(GPIO.BCM)
GPIO.setup(SW1, GPIO.IN, pull_up_down=GPIO.PUD_UP)
GPIO.setup(SW2, GPIO.IN, pull_up_down=GPIO.PUD_UP)
GPIO.setup(SW3, GPIO.IN, pull_up_down=GPIO.PUD_UP)

GPIO.add_event_detect(SW3, GPIO.FALLING, bouncetime=200)
GPIO.add_event_callback(SW3, callback=callback)

# MAIN PROGRAM*********************************************
try:
  print("Start program")
  while True:
    sw_status_1 = GPIO.input(SW1)
    sw_status_2 = GPIO.input(SW2)

    if sw_status_1 == 0:
      print("switch 1 is pressed!")
    elif sw_status_2 == 0:
      print("switch 2 is pressed!")

    time.sleep(0.1)

finally:
  print("cleanup")
  GPIO.cleanup()

解説

・GPIOピン17、18、22をそれぞれ入力ピンとして設定
・内部プルアップ抵抗を有効化
 上手の回路ではスイッチを押すとGNDと導通するので0Vに落ちるが、
 スイッチを押していないときはどこにも繋がっていない不定状態となるため、
 安定化させるためにプルアップ抵抗で3.3V側に引張ってやる
チャタリング対策として、whileループの中にsleep関数、割込み処理にbouncetimeを設定
 

ハマったところ

ラズパイは結構使っているので楽勝中の楽勝だと思っていたが、最初
sw_status_1 = GPIO.input(SW1)
sw_status_2 = GPIO.input(SW2)
の2文をwhileループの外に置いていたところ全く意図したとおりに動かず
30分くらい「???」状態だった
参考のページを見てようやく気が付いた