質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Raspberry Pi

Raspberry Piは、ラズベリーパイ財団が開発した、名刺サイズのLinuxコンピュータです。 学校で基本的なコンピュータ科学の教育を促進することを意図しています。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

Q&A

解決済

2回答

786閲覧

pythonで処理を停止させずに分岐処理を行う

YMD_kts

総合スコア23

Raspberry Pi

Raspberry Piは、ラズベリーパイ財団が開発した、名刺サイズのLinuxコンピュータです。 学校で基本的なコンピュータ科学の教育を促進することを意図しています。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

0グッド

0クリップ

投稿2018/07/09 14:52

編集2018/07/10 02:29

こちらのサイトのソースコードを参考に、複数のLEDを光らせる間に一定以上の音が鳴った場合音が鳴った回数を記録するというプログラムを組もうとしました。
しかし、複数のLEDを2秒ごとに切り替えるのですが、切り替えのプログラムをwhile構文で書いているため、一定以上の音が鳴った回数の記録とLEDの切り替えが同時に行えません。これを、一定以上の音が鳴った回数の記録を常時行いながらLEDを切り替えたいです。
動作環境はRaspberry Pi3 TypeBです。

ソースコードが現在手元に無いため機能を別のものに差し替えたコードで説明します。

python

1import time 2import random 3 4cnt = 0 5i =0 6rdm = 0 7score = 0 8while True: 9 rdm = random.randint(0, 15) 10 while i < 5: 11 print("LED_Change") 12 time.sleep(0.5) 13 i += 1 14 15 if rdm > 9: 16 score += 1 17 print("score=" + str(score)) 18 print(rdm) 19 20 #cnt += 1 21 #if cnt > 10: 22 # break 23

今、**randomint()**で常時整数を生成します。これが上記で言う録音とします。
そして、以下のコードが一定以上の音量が鳴った回数の記録としています。

python

1if rdm > 9: 2 score += 1 3 print("score=" + str(score)) 4

**print("LED_Change")**がLEDの切り替えで、5回行います。

この時結果が

LED_Change LED_Change LED_Change LED_Change LED_Change 8 5 8 score 1 13 3 score 2 13 8 score 3 11 2 score 4 12 score 5 11

このようになり、LEDの切り替えを先に行ってしまいます。
なのLED_Changeの0.5秒の待ち時間中にもランダム数字の生成を行うようにするにはどうすればいいでしょうか。

実際のコードがなく、分かりづらい説明になってしまいましたがどうか回答お願いいたします。

追記
ソースコードがある状況なので、こちらのコードを参照ください。全体の動作に関しては上記のものと変わりません
threadingを用いてマルチスレッドで動かすことにしました。
こちらを参考に上記の機能を関数化して以下のコードで実効しました。

python

1import threading 2import elcFunc as ef 3import judgeFunction as jf 4 5ef.initAll() 6 7if __name__ == "__main__": 8 thread1 = threading.Thread(target = jf.judgeFunc()) 9 thread2 = threading.Thread(target = ef.noteStart()) 10 11 thread1.start() 12 thread2.start() 13 14 jf.judgeEnd()

jf.judgeFunc()一定以上の音量が鳴った回数を保存する、ef.noteStart()がLEDを起動して切り替える関数となっています
このコードの実行結果は、並行に関数を実行せずにただただ一定以上の音を監視する関数が続いてしまいました。原因がわかりません...

judgeFunc()

python

1def judgeFunc(): 2 while True: 3 global score 4 data = stream.read(CHUNK) 5 x = np.frombuffer(data, dtype="int16") / 32768.0 6 if x.max() > threshold: 7 score += 1 8 print(score) 9

noteStart()

python

1def noteStart(): 2 global a,i 3 4 while a == True: 5 print("Start") 6 wiringpi.digitalWrite(GPIO26, LOW) 7 wiringpi.digitalWrite(GPIO21, LOW) 8 9 lf.noteLeft(random.randint(0, 15)) 10 suc = rf.noteRight(random.randint(0, 15)) 11 time.sleep(2) 12 13 while i < 28: 14 lf.noteLeft(suc) 15 suc = rf.noteRight(random.randint(0, 15)) 16 time.sleep(2) 17 i = i+1 18 19 wiringpi.digitalWrite(GPIO21, HIGH) 20 rf.endRight() 21 22 lf.noteLeft(suc) 23 time.sleep(2) 24 25 wiringpi.digitalWrite(GPIO26, HIGH) 26 lf.endLeft() 27 28 a = False

よろしくお願いします。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

ベストアンサー

ちょっと考え方を変えないといけないです。以下の二つを同時に実行(マルチタスキング)したいというのが問題の本質なので、まずはそれぞれを独立した関数にします。

  1. 常時録音処理を続ける関数
  2. 0.5秒置きにLEDの切り替え処理を続ける関数

独立したこれら二つの関数ができればそれをthreading.Threadで並列に実行すれば問題解決です。

投稿2018/07/09 15:04

YouheiSakurai

総合スコア6142

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

YMD_kts

2018/07/10 02:27

threading を用いてコードを書いたのですが、また問題が発生してしまいました。 よろしければ解決にお力をおかしください。 本文の方に追記しております。
YouheiSakurai

2018/07/10 02:59

targetには実行したい関数そのものを渡します。つまりtarget = jf.judgeFunc()やtarget = ef.noteStart()ではなくtarget = jf.judgeFuncやtarget = ef.noteStartです。
YMD_kts

2018/07/11 04:39

ありがとうございます! 関数を渡すと書かれてて勘違いしてしまいました。
guest

0

やろうとおもえば、マルチスレッドとか使わずとも実現することは可能です
タイムアウト関数を作りましょう。現在時よりn秒過ぎているかを判定して、過ぎていればTRUE、過ぎていなければFALSEを返す関数を作っておけば、メインループの中で、sleep を使わずにそれぞれ判定して処理することが可能です
sleepを使うとそれで処理が止まってしまうため、それを使わずに処理するというのがポイントとなりますねー

投稿2018/07/09 15:18

y_waiwai

総合スコア87747

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

YouheiSakurai

2018/07/09 16:05

I/Oはブロックする可能性がありますよ。それを回避するためにはノンブロッキングI/O。
YMD_kts

2018/07/10 02:26

今回はthreadingを用いようと思います。 解答有難うございます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問