トグルスイッチでのLEDの点灯を制御したいのですが、
下記のようなソースで割り込みの箇所
pi.wiringPiISRの関数で、トグルスイッチを押すとプログラムが終了してしまいます。
本来は、無限ループなので、プログラムが終了することはないのですが。
原因が、わかりません。
import time, wiringpi as pi
led_pin = 23
bt_pin = 17
counter = 0
pi.wiringPiSetupGpio()
pi.pinMode( bt_pin, 0 )
pi.pullUpDnControl( bt_pin, 2)
pi.pinMode( led_pin, 1 )
def Warikomi():
global counter
if ( pi.digitalRead( bt_pin ) == 0 ):
counter = counter + 1
try:
ret = pi.wiringPiISR( bt_pin, pi.INT_EDGE_BOTH , Warikomi )
while True:
if ( counter % 2 == 0 ):
pi.digitalWrite( led_pin, 1 )
time.sleep(0.5)
pi.digitalWrite( led_pin, 0 )
time.sleep(0.1)
except KeyboardInterrupt:
pi.pinMode( led_pin, 0 )
finally :
pi.pinMode( led_pin, 0 )
動作としては、プログラムが開始すると、LEDが点滅します。
ボタンを押して、LEDの点滅を止めようとすると、プログラムが終了(正常終了?異常終了?)してしまいます。
下記は、その時の結果(添付画像が何故かさかさまになります。すみません。)
問題を単純化してみたのが次のコードです。
global counter
bt_pin = 17
counter = 0
pi.wiringPiSetupGpio()
def Warikomi():
print( "割り込み関数通過" )
try:
ret = pi.wiringPiISR( bt_pin, pi.INT_EDGE_RISING , Warikomi )
while True:
time.sleep(0.5)
counter = counter + 1
print( counter )
time.sleep(0.5)
except KeyboardInterrupt:
print ("except通過" )
finally :
print ("finally通過" )
このプログラムが開始すると、ディスプレイに1ずつカウントアップされ、
ボタンが押されたときにプログラムが終了(正常終了?異常終了?)してしまいます。
finally句は通りません。Warikomi関数も実行されません。
-
気になる質問をクリップする
クリップした質問は、後からいつでもマイページで確認できます。
またクリップした質問に回答があった際、通知やメールを受け取ることができます。
クリップを取り消します
-
良い質問の評価を上げる
以下のような質問は評価を上げましょう
- 質問内容が明確
- 自分も答えを知りたい
- 質問者以外のユーザにも役立つ
評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。
質問の評価を上げたことを取り消します
-
評価を下げられる数の上限に達しました
評価を下げることができません
- 1日5回まで評価を下げられます
- 1日に1ユーザに対して2回まで評価を下げられます
質問の評価を下げる
teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。
- プログラミングに関係のない質問
- やってほしいことだけを記載した丸投げの質問
- 問題・課題が含まれていない質問
- 意図的に内容が抹消された質問
- 過去に投稿した質問と同じ内容の質問
- 広告と受け取られるような投稿
評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。
質問の評価を下げたことを取り消します
この機能は開放されていません
評価を下げる条件を満たしてません
質問の評価を下げる機能の利用条件
この機能を利用するためには、以下の事項を行う必要があります。
- 質問回答など一定の行動
-
メールアドレスの認証
メールアドレスの認証
-
質問評価に関するヘルプページの閲覧
質問評価に関するヘルプページの閲覧
checkベストアンサー
+3
とりあえず、 time.sleep
の代わりに pi.delay
とWiringPIで用意されている関数を使用することで動作するようです。
examples でも delay を使っているので何か理由があるのだとは思います。
投稿
-
回答の評価を上げる
以下のような回答は評価を上げましょう
- 正しい回答
- わかりやすい回答
- ためになる回答
評価が高い回答ほどページの上位に表示されます。
-
回答の評価を下げる
下記のような回答は推奨されていません。
- 間違っている回答
- 質問の回答になっていない投稿
- スパムや攻撃的な表現を用いた投稿
評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。
+1
PythonもWiringPiも使用していないので的外れかもしれませんが…
ret = pi.wiringPiISR( bt_pin, pi.INT_EDGE_BOTH , Warikomi() )
の Warikomi()
の ()
はいるのですか?
割り込み用の関数登録だと他の言語では括弧なしで関数自体の登録になるのでは?
(Pythonは知りません)
投稿
-
回答の評価を上げる
以下のような回答は評価を上げましょう
- 正しい回答
- わかりやすい回答
- ためになる回答
評価が高い回答ほどページの上位に表示されます。
-
回答の評価を下げる
下記のような回答は推奨されていません。
- 間違っている回答
- 質問の回答になっていない投稿
- スパムや攻撃的な表現を用いた投稿
評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。
+1
(Raspberry Piに興味はありますが、まだ触ったことがないので)確証はありませんが、
Re: wiringPi interrupts crashingのGordonさんによれば、
全体が書いてないからいまいちわからないけれど、wiringPiISR()をループの中で呼び出していないかい?どうもそうっぽいんだけど。プログラム全体の中で、モニターしたいPINごとにただの一回だけ呼び出すようにするべきだよ。
だそうです。こちらの対応でダメであればもう少し調べてみます。
投稿
-
回答の評価を上げる
以下のような回答は評価を上げましょう
- 正しい回答
- わかりやすい回答
- ためになる回答
評価が高い回答ほどページの上位に表示されます。
-
回答の評価を下げる
下記のような回答は推奨されていません。
- 間違っている回答
- 質問の回答になっていない投稿
- スパムや攻撃的な表現を用いた投稿
評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。
+1
def Warikomi():
が何も返さないのがエラーの原因かもしれません。
怪しいと思って調べたところ、StackOverflowのnickzamさんによれば、
Cについて造詣はないけれども、オレがソースを見るにこのコード(関数がVOIDを返したりエラーが起きるかどうかチェックする)が原因だと思う。だからオレは、
my_int()
の中で明示的にTrue
を返すようにするか、1
を返すようにすることを勧める。
今Pythonの関数の中ではNone
を返しているし、それで(Cのソース中の)関数の末端に来るけれども、(Cのソースによれば)何も返せないってことでしょ。
多分以下のコードで対応できます。
def Warikomi():
print( "割り込み関数通過" )
# wiringPiISR requires value
return True
投稿
-
回答の評価を上げる
以下のような回答は評価を上げましょう
- 正しい回答
- わかりやすい回答
- ためになる回答
評価が高い回答ほどページの上位に表示されます。
-
回答の評価を下げる
下記のような回答は推奨されていません。
- 間違っている回答
- 質問の回答になっていない投稿
- スパムや攻撃的な表現を用いた投稿
評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。
+1
解決としていいのか少々疑問なのですが、
(やりたいことが出来たからよしとします。とりあえず。)
WiringPiの「wiringPiISR」ではダメなのかと思い、
pigpioの「callback」を使用しました。
結果、思い通りの動きをしてくれました。
ご意見、ご指摘をくださった方々、大変ありがとうございました。
出来れば、WiringPiで行いたかったのですが、(pigpioが、現時点で、あまりよくわかっていないため。)
もし何かありましたら連絡ください。
以下のコードは、問題を単純化してみた時のコードをpigpioで書いてみました。
(こう見ると、wiringPiISRの引数にあるwarikomiの関数の引数に問題があるのかといろいろ試しましたが関係なさそうです。)
import pigpio
import time
bt_pin = 17
counter = 0
pi = pigpio.pi()
def warikomi(gpio, level, tick):
print( "割り込み関数通過" )
cb = pi.callback(bt_pin, pigpio.RISING_EDGE, warikomi)
try:
while True:
time.sleep(0.5)
counter = counter + 1
print( counter )
time.sleep(0.5)
except KeyboardInterrupt:
print ("except通過" )
finally :
pi.stop()
print ("finally通過" )
投稿
-
回答の評価を上げる
以下のような回答は評価を上げましょう
- 正しい回答
- わかりやすい回答
- ためになる回答
評価が高い回答ほどページの上位に表示されます。
-
回答の評価を下げる
下記のような回答は推奨されていません。
- 間違っている回答
- 質問の回答になっていない投稿
- スパムや攻撃的な表現を用いた投稿
評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。
0
終了するのは?ですが、warikomi発動しないのはわかります。
exampleと比較して:
ret = pi.wiringPiISR( bt_pin, pi.INT_EDGE_RISING , Warikomi )
ret
に束縛してるのみで実行されていないのでは? つまり登録されていない。
ret =
がいらないのでは。
投稿
-
回答の評価を上げる
以下のような回答は評価を上げましょう
- 正しい回答
- わかりやすい回答
- ためになる回答
評価が高い回答ほどページの上位に表示されます。
-
回答の評価を下げる
下記のような回答は推奨されていません。
- 間違っている回答
- 質問の回答になっていない投稿
- スパムや攻撃的な表現を用いた投稿
評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。
15分調べてもわからないことは、teratailで質問しよう!
- ただいまの回答率 88.20%
- 質問をまとめることで、思考を整理して素早く解決
- テンプレート機能で、簡単に質問をまとめられる
質問への追記・修正、ベストアンサー選択の依頼
退会済みユーザー
2017/09/06 06:52
try:を外すとエラーの起きる箇所で止まってしかも「エラー:何行目の関数○○で××が起きました」と出そうなのですが、こちら試されましたか?
myu
2017/09/06 09:38
ご意見ありがとうございます。try句を外しても、同様の結果になってしまいます。エラーメッセージなどは出ず、単純にプログラムが終了してしまいます。
myu
2017/09/06 09:41
ちなみに、while True:の文節をpi.wiringPiISRの関数とtime.sleepにしても同様です。なので、wiringPiISRの関数の動きがネットで見る情報と違うような気がします
can110
2017/09/07 18:33
念のために確認です。プログラム開始するとLEDは点滅するが、スイッチ押したとたんにプログラム終了するということでしょうか?
myu
2017/09/07 18:36
はい。その通りです。LEDは点灯しっぱなしの状態(100%この状態です。)でプログラムが終了します。詳しい現象を書いていないのでわかりづらいですよね。
can110
2017/09/07 18:42
すなわちexcept,finally内に処理がいっていない可能性が高いですね。左記の場所にprint文を入れて何らか出力されるか確認ください(本来は出力されるはず)。
myu
2017/09/07 18:49
ご意見ありがとうございます。そうなのです。print文が入っているのですが、finally句を通らないのです。添付画像がさかさまで見づらいと思いますが、finally句にwiringPiISR関数の戻り値retを出力しているのですが、printされません。
myu
2017/09/07 18:54
もう少し、情報を付け加えますと、キーボードからの割り込み終了(Ctrl+c)をすると、except KeyboardInterruptを通り(当たり前ですよね)、finally句を通って、関数の戻り値が返ってきます(「None」と返ってきました)
can110
2017/09/07 18:55
やはり通っていませんね。了解です。ちょっと勘なので回答ではなくこちらに記載しますがWarikomi関数の「if ( pi.digitalRead( bt_pin ) == 0 ):」行を取り除いてみてください。
can110
2017/09/07 18:56
キーボード割り込みは正常に動作しているということですね。やはり割り込み処理部分が怪しそうですね。
myu
2017/09/07 19:04
ご意見ありがとうございます。「if ( pi.digitalRead( bt_pin ) == 0 ):」行を取り除いてみましたが、同様の結果でした。
can110
2017/09/07 19:06
確認ありがとうございます。割り込み中にdigitalReadしてよいものか疑問だったので。調べてみて何か分かれば回答できればと思います。
mituha
2017/09/07 22:14
ラズパイの種類、OSやWiringPlのバージョンなども記載していただけますでしょうか?
myu
2017/09/07 22:37
ラズパイですが、zero wです。OSは、Raspbianです。WiringPlは、2.44.4です。よろしくお願いします。
退会済みユーザー
2017/09/08 06:56
WiringPlとWiringPl2があるんですね。紛らわしいですが違いがよくわからず。importでWiringPl(最終更新2017-08)の人とWiringPl2(最終更新2016-03)の人が居ました。 https://pypi.python.org/pypi?%3Aaction=search&term=wiringpi&submit=search
mituha
2017/09/08 08:25
Package Ownerの違いでバージョンへの追従具合が違うだけに見えますね。実際どうなんだろ?
myu
2017/09/08 11:27
なるほど。勉強になります。slashさんのリンクしているサイトからwiringPi.cを確認しているのですが、(Raspbianの中のwiringPi.cが現在、探せていません。)正直、怪しいところにprintfを入れて確認したいのですが、それをコンパイルする方法(技量がない)がわからないので、(本題からそれてる気がします)調査中です。