ラズパイ:タクトスイッチでPythonプログラムを動作させる

ラズパイ:タクトスイッチでPythonプログラムを動作させる Python

ラズパイにブレッドボードでタクトスイッチをつなげて、ボタンを押したらPythonプログラムやシェルスクリプトを実行するプログラムです。

上記写真では、4つのタクトスイッチをラズパイにつなげて使っています。
掲載したプログラムも4つのタクトスイッチに対応したプログラムとなっています。
一応配線の色に気を使ってみた。(つもり)

作ったきっかけと利用例

アマゾンでタクトスイッチを買ったら600円ほどで100個も入ってきたので、ブレッドボードと組み合わせてボタンを押したら時刻や天気予報などスピーカから流れたら面白い(ちょっとしたスマートスピーカ?!)と思い、ボタンクリックでPythonのプログラムやシェルスクリプトなどを呼び出すようにした。

利用例としては、現在時刻をしゃべるボタンを作ったり、天気予報をしゃべるボタンなど。

ちなみにわたしは、好きな曲をラズパイに保存してボタンを押したらランダムで曲を再生するような感じで使っています。

天気予報や曲再生などは以下の記事のプログラムを使っています。参考にどうぞ。

配線について

GIPOのピン番号は、連番で指定しています。(GPIO.BOARDで指定)

ラズパイ:タクトスイッチでPythonプログラムを動作させる
上記写真では、右から

ボタン名プログラム上の変数
水色ボタン1pin1/button1
ボタン2pin2/button2
黄色ボタン3pin3/button3
ボタン4pin4/button4

といった感じで配線しています。

アースについて
アース(GND)は、39番を使用しています。
上記写真の緑と黄色のジャンパーワイヤ(線)はすべて39番につながっている形になります。

ラズパイ本体はこんな感じ。
ラズパイ:タクトスイッチでPythonプログラムを動作させる

プログラム

33,37,41,45行目のコマンド文字列はあくまで例ですので、ご自分の環境にあわせて使ってください。

例えば /home/pi にある hoge.py というプログラムを実行したいなら

sudo python3 /home/pi/hoge.py

とすればOKです。

また、 /home/pi にあるhoge.mp3という曲を再生したいなら、

cmd = "omxplayer -o local /home/pi/hoge.mp3"

という感じです。

言語:Python3

tactrun.py

# -*- coding: utf-8 -*-

import RPi.GPIO as GPIO
import time
import sys, os

# ボタンを押したらプログラムを呼び出す
if __name__ == "__main__":
	# GPIOピン番号設定
	pin1 = 15
	pin2 = 21
	pin3 = 29
	pin4 = 35

	GPIO.setmode(GPIO.BOARD)
	GPIO.setup(pin1, GPIO.IN, pull_up_down = GPIO.PUD_UP)
	GPIO.setup(pin2, GPIO.IN, pull_up_down = GPIO.PUD_UP)
	GPIO.setup(pin3, GPIO.IN, pull_up_down = GPIO.PUD_UP)
	GPIO.setup(pin4, GPIO.IN, pull_up_down = GPIO.PUD_UP)

	# ボタンクリック待機中
	print("ボタン待機中...")

	while True:
		button1 = GPIO.input(pin1)
		button2 = GPIO.input(pin2)
		button3 = GPIO.input(pin3)
		button4 = GPIO.input(pin4)

		cmd = ""
		if button1 == False:
			# ボタン1の処理
			cmd = "sudo python3 /home/pi/button1.py"	# 例です

		elif button2 == False:
			# ボタン2の処理
			cmd = "sudo python3 /home/pi/button2.py"	# 例です

		elif button3 == False:
			# ボタン3の処理
			cmd = "sudo python3 /home/pi/button3.py"	# 例です

		elif button4 == False:
			# ボタン4の処理
			cmd = "sudo python3 /home/pi/button4.py"	# 例です

		# 実行
		if cmd != "":
			ret = os.popen(cmd).readline().strip()
			print(ret)
			time.sleep(1)	# ボタンを押した後のチャタリング防止のため

		time.sleep(0.1)

	GPIO.cleanup()

コメント

  1. 名無し より:

    これで実行したプログラムを、別のボタンで終了させたい時はどのようになりますか?

    • shuichi より:

      名無しさんへ
      管理人です。該当のプログラムではos.popenメソッドでプロセスを起動させています。ラズパイの場合Linuxなのでボタンを押したときに実行したコマンドのプロセスIDが取得できればそのプロセスIDを使ってkillさせて終了することができます。
      ちょっと調べてみたのですが、どうもわたしの作成したプログラムで使っているos.openでは終了させるためのプロセスIDが取得できなそうです。

      subprocessというモジュールの機能を使えばプロセスIDの取得ができそうなので、とりあえず参考になるURLをお伝えしておきます。

      参考
      python でコマンド実行。サブプロセスの終了待ち・強制終了・親プロセスと一緒に殺す

    • shuichi より:

      subprocessモジュールを利用して終了ボタン機能を作ってみたので試してみてください。

      os.popenの代わりにsubprocess.Popenを使ってボタンを押したときに実行しているプロセスIDを取得しています。
      終了にはos.killpgというコマンドで出来ました。

      サンプルです。(ボタン4が終了ボタンの場合です)

      # -*- coding: utf-8 -*-
      
      import RPi.GPIO as GPIO
      import time
      import os
      import signal
      import subprocess
      
      # ボタンを押したらプログラムを呼び出す
      if __name__ == "__main__":
      	# GPIOピン番号設定
      	pin1 = 15
      	pin2 = 21
      	pin3 = 29
      	pin4 = 35
      
      	GPIO.setmode(GPIO.BOARD)
      	GPIO.setup(pin1, GPIO.IN, pull_up_down = GPIO.PUD_UP)
      	GPIO.setup(pin2, GPIO.IN, pull_up_down = GPIO.PUD_UP)
      	GPIO.setup(pin3, GPIO.IN, pull_up_down = GPIO.PUD_UP)
      	GPIO.setup(pin4, GPIO.IN, pull_up_down = GPIO.PUD_UP)
      
      	# ボタンクリック待機中
      	print("ボタン待機中...")
      	proc = None
      	while True:
      		button1 = GPIO.input(pin1)
      		button2 = GPIO.input(pin2)
      		button3 = GPIO.input(pin3)
      		button4 = GPIO.input(pin4)
      
      		cmd = ""
      		if button1 == False:
      			# ボタン1の処理
      			cmd = "sudo python3 /home/pi/button1.py"	# 例です
      
      		elif button2 == False:
      			# ボタン2の処理
      			cmd = "sudo python3 /home/pi/button2.py"	# 例です
      
      		elif button3 == False:
      			# ボタン3の処理
      			cmd = "sudo python3 /home/pi/button3.py"	# 例です
      
      		elif button4 == False:
      			# ボタン4の処理(これが終了ボタンの場合)
      			cmd = ""
      			if proc != None:
      				os.killpg(os.getpgid(proc.pid), signal.SIGTERM)	# プロセスを終了
      				proc = None
      
      		# 実行
      		if cmd != "":
      			proc = subprocess.Popen(cmd, stdout=subprocess.PIPE, shell=True, preexec_fn=os.setsid)
      			print("PID = {}".format(proc.pid))		# 実行中のプロセスIDを表示
      			
      			time.sleep(1)	# ボタンを押した後のチャタリング防止のため
      
      		time.sleep(0.1)
      
      	GPIO.cleanup()
      
  2. 匿名 より:

    質問なのですが、タクトスイッチには抵抗はいらないのでしょうか?
    自分はラズベリーパイ初心者で、あまり理解してないです。
    他の記事やサイトを見ていると、抵抗を使っているものと使ってないものがあり、混乱しています。

    • shuichi より:

      匿名さん、おはようございます。管理人です。
      わたしは電子回路初心者です(笑)

      知っている範囲でお伝えします。
      通常のタクトスイッチを利用する電子回路であれば抵抗は必要です。
      ただし、ラズパイの場合、抵抗の役割をプログラムを使ってラズパイに担わせることができます。
      つまり抵抗を電子回路に入れなくても抵抗を入れた回路として扱うこともが出来るということです。

      わたしは抵抗を入れる回路を作るのが面倒なので、プログラム側で設定してしまいます。

      該当の記事ではtactrun.pyの

      GPIO.setup(pin1, GPIO.IN, pull_up_down = GPIO.PUD_UP)
      GPIO.setup(pin2, GPIO.IN, pull_up_down = GPIO.PUD_UP)
      GPIO.setup(pin3, GPIO.IN, pull_up_down = GPIO.PUD_UP)
      GPIO.setup(pin4, GPIO.IN, pull_up_down = GPIO.PUD_UP)

      の部分です。
      プルアップ抵抗を各ボタンに割り当てています。
      この場合、ボタンを押していない時、電源が流れている状態となるのでボタンを押した時の判定は

      if button1 == False:
      # ボタン1の処理

      などとなっています。
      プルダウンやプルアップに関してはすいませんが、わたしもよく分かっていませんので調べてみてください。

      • 匿名 より:

        早速のご返答ありがとうございます。
        抵抗の役割を持つプログラムがあるなんて知らなかったのですごく勉強になりました。
        ありがとうございます。

        • shuichi より:

          良かったです。
          ネット検索だと断片的な解説が多いので確かに迷うことは多いですよね。このブログも含めて(笑)

タイトルとURLをコピーしました