ラズパイ:タクトスイッチで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()
      
タイトルとURLをコピーしました