🎄teratailクリスマスプレゼントキャンペーン2024🎄』開催中!

\teratail特別グッズやAmazonギフトカード最大2,000円分が当たる!/

詳細はこちら
Raspbian

Raspbianは、DebianベースのRaspberry Pi用ディストリビューション。ハードウェア浮動小数点演算を有効にすることが可能で、Webブラウズなどの速度を向上できます。

Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

Raspberry Pi

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

Python

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

Q&A

解決済

3回答

2071閲覧

[ラズパイ電子工作]_ラズパイに負荷がかかり過ぎているのでしょうか...?

ysk_snn

総合スコア21

Raspbian

Raspbianは、DebianベースのRaspberry Pi用ディストリビューション。ハードウェア浮動小数点演算を有効にすることが可能で、Webブラウズなどの速度を向上できます。

Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

Raspberry Pi

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

Python

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

0グッド

0クリップ

投稿2019/12/19 07:36

編集2019/12/23 00:27

プログラム、電子工作ともに初心者です。

1つの出力のオンオフを、3つのセンサ(ready, trigger, stop)で管理しようと考えています。
出力をオンにするためには、[readyセンサ → triggerセンサ] の順に短時間で反応させる必要があり、
出力をオフにするためには、stopセンサを反応させる必要があります。
現在は出力の代わりに緑LEDを点灯させます。
また、不意の誤作動を防ぐために、2つのスイッチによってロック・ロック解除を行います。
現在はロック時は黄LED、ロック解除時は赤LEDを点灯させます。

プログラムを作動させると、

・ロックを示す黄LEDと、出力を示す緑LEDとが同時に点灯する_(本来は黄LEDのみ)
・ロック解除のトグルスイッチを押すと、黄LEDが消えるが、ロック解除を示す赤LEDが点灯しないときがある
→しかし、ready・triggerセンサ、stopセンサは反応して出力が切り替わる
・出力時にロックをかけようとすると、無視される_(本来は出力中にロックをかけると、出力もオフ)
→これは頻発します

のような状態が発生します。
しかし、このような状態は発生したりしなかったりです。

コードが間違っているのか、回路が間違っているのか分かりません。
GPIO.outputが内包されているJobSwitch()をwhile Trueで動かしている辺りが怪しいと思っているのですが...

以下、コードと回路です。
どうかよろしくお願いいたします。

python3

1from gpiozero import MCP3208 2import RPi.GPIO as GPIO 3import time 4GPIO.setmode(GPIO.BCM) 5GPIO.setup(20, GPIO.IN) #output_check 6GPIO.setup(21, GPIO.OUT) #output 7GPIO.setup(23, GPIO.OUT) #red_signal 8GPIO.setup(24, GPIO.OUT) #yellow_signal 9 10ch0 = MCP3208(channel = 0) #stop_sensor___<0.5_stop 11ch1 = MCP3208(channel = 1) #ready_sensor 12ch2 = MCP3208(channel = 2) #trigger_sensor 13ch3 = MCP3208(channel = 3) #yellow_signal 14ch4 = MCP3208(channel = 4) #red_signal 15 16#sensor's_threthold 17ch1th = 0.1 18ch2th = 0.1 19 20def CurrentStatus(st):#st = 0, 1 21 status = {0:'waiting',1:'sensing'} 22 return status[st] 23 24def YellowSignal(): 25 if ch3.value > 0.2: 26 global CS 27 print('sensing') 28 CS = CurrentStatus(1)#to_sense 29 else: 30 pass 31def RedSignal(): 32 if ch4.value > 0.2: 33 global CS 34 print('waiting') 35 CS = CurrentStatus(0)#to_wait 36 GPIO.output(21,GPIO.LOW) 37 else: 38 pass 39 40def ControlOutput(): 41 global t1,t2,tsub 42 #outputting_or_waiting 43 #outputting 44 while GPIO.input(20) == GPIO.HIGH: 45 if ch0.value > 0.5: 46 GPIO.output(21,GPIO.LOW) 47 else: 48 pass 49 #waiting 50 else: 51 try: 52 #ready_sensor 53 if ch1.value > ch1th and ch2.value < ch2th: 54 t1 = time.time() 55 else: 56 pass 57 #trigger_sensor 58 if ch1.value < ch1th and ch2.value > ch2th: 59 t2 = time.time() 60 tsub = t2- t1 61 if 0.0001 < tsub < 0.1: 62 print('start_injectioning___' + str(tsub)) 63 GPIO.output(21,GPIO.HIGH) 64 del t1,t2,tsub 65 else: 66 time.sleep(0.1) 67 print('out_of_range_error___' + str(tsub)) 68 print('reset,_now_not_ready') 69 del t1,t2,tsub 70 #neither_sensor_is_on__or_each_sensor_is_on 71 else: 72 pass 73 except NameError: 74 pass 75 76def JobSwitch(): 77 #print(CS) 78 if CS == 'waiting': 79 GPIO.output(24,GPIO.HIGH) 80 time.sleep(0.0001)#buffer 81 GPIO.output(23,GPIO.LOW) 82 YellowSignal() 83 elif CS == 'sensing': 84 GPIO.output(23,GPIO.HIGH) 85 time.sleep(0.0001)#buffer 86 GPIO.output(24,GPIO.LOW) 87 RedSignal() 88 ControlOutput() 89 else: 90 pass 91 92#wait_start 93CS = CurrentStatus(0) 94 95while True: 96 try: 97 JobSwitch() 98 except KeyboardInterrupt: 99 GPIO.cleanup() 100 print('cleanup')

イメージ説明

#2019/12/20_追記

以下のようにコードを書き直したら、おおむね良好に動いてくれています。

しかし、ときどき動作が不安定になります。
MCP3208 の入力であるch4.valueをみてみると、スイッチを押したときに大きな入力が出てきて良いのですが、
その後、入力が0付近に戻りきらないことがあるようでした。

そのほかにもラズパイに負荷をかけるようなコードになっているのかもしれません。
どなたか教えてくださいませんでしょうか。

python3

1from gpiozero import MCP3208 2import RPi.GPIO as GPIO 3import time 4 5GPIO.setmode(GPIO.BCM) 6GPIO.setup(20, GPIO.IN) #output_check 7GPIO.setup(21, GPIO.OUT) #output 8GPIO.setup(23, GPIO.OUT) #red_signal 9GPIO.setup(24, GPIO.OUT) #yellow_signal 10 11ch0 = MCP3208(channel = 0) #stop_sensor___<0.5_stop 12ch1 = MCP3208(channel = 1) #ready_sensor 13ch2 = MCP3208(channel = 2) #trigger_sensor 14ch3 = MCP3208(channel = 3) #yellow_signal 15ch4 = MCP3208(channel = 4) #red_signal 16 17#sensor's_threthold 18ch1th = 0.1 19ch2th = 0.1 20 21def CurrentStatus(st):#st = 0, 1 22 status = {0:'waiting',1:'sensing'} 23 return status[st] 24 25def YellowSignal(): 26 if ch3.value > 0.2: 27 global CS 28 print('sensing') 29 CS = CurrentStatus(1)#to_sense 30 else: 31 pass 32 33def RedSignal(): 34 if ch4.value > 0.2: 35 global CS 36 print('waiting') 37 CS = CurrentStatus(0)#to_wait 38 else: 39 pass 40 41def SignalSwitch():#continue 42 if CS == 'waiting': 43 YellowSignal() 44 elif CS == 'sensing': 45 RedSignal() 46 47def ControlOutput(): 48 global t1,t2,tsub 49 #outputting_or_waiting 50 #outputting 51 if GPIO.input(20) == GPIO.HIGH: 52 if ch0.value > 0.5: 53 GPIO.output(21,GPIO.LOW) 54 else: 55 pass 56 #waiting 57 elif GPIO.input(20) == GPIO.LOW: 58 try: 59 #ready_sensor 60 if ch1.value > ch1th and ch2.value < ch2th: 61 t1 = time.time() 62 else: 63 pass 64 #trigger_sensor 65 if ch1.value < ch1th and ch2.value > ch2th: 66 t2 = time.time() 67 tsub = t2- t1 68 if 0.0001 < tsub < 0.1: 69 print('start_injectioning___' + str(tsub)) 70 GPIO.output(21,GPIO.HIGH) 71 del t1,t2,tsub 72 else: 73 time.sleep(0.1) 74 print('out_of_range_error___' + str(tsub)) 75 print('reset,_now_not_ready') 76 del t1,t2,tsub 77 #neither_sensor_is_on__or_each_sensor_is_on 78 else: 79 pass 80 except NameError: 81 pass 82 83def WorkSwitch():#continue 84 if CS == 'waiting': 85 pass 86 elif CS == 'sensing': 87 ControlOutput() 88 89def GPIOSwitch():#once 90 #print(CS) 91 if CS == 'waiting': 92 GPIO.output(23,GPIO.LOW)#RedLED 93 GPIO.output(21,GPIO.LOW)#output 94 time.sleep(0.0001)#buffer 95 GPIO.output(24,GPIO.HIGH)#YellowLED 96 elif CS == 'sensing': 97 GPIO.output(24,GPIO.LOW) 98 time.sleep(0.0001)#buffer 99 GPIO.output(23,GPIO.HIGH) 100 101if __name__ == '__main__': 102 #initial 103 CS = CurrentStatus(0) 104 105 while True: 106 try: 107 if CS == 'waiting': 108 GPIOSwitch() 109 print('switch_wait') 110 while CS == 'waiting': 111 SignalSwitch() 112 WorkSwitch() 113 elif CS == 'sensing': 114 GPIOSwitch() 115 print('switch_sense') 116 while CS == 'sensing': 117 SignalSwitch() 118 WorkSwitch() 119 except KeyboardInterrupt: 120 GPIO.cleanup() 121 print('cleanup')

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

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

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

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

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

coco_bauer

2019/12/20 07:37

追記の中に『MCP3208 の出力であるch4.value』と書かれていますが、MCP3208は8チャネル12bit A/Dコンバータで、ch0~ch7はアナログ入力なのではないのですか? A/D変換した結果は12bitの2進数で、"0.2"というような実数と比較できないのではないのでしょうか。 すみませんが、回路の全体像が想像できないです。
ysk_snn

2019/12/23 00:36

ご指摘ありがとうございます! >ch0~ch7はアナログ入力なのではないのですか?  出力 → 入力 でした。紛らわしいことを書いてすみません。修正しました。 >A/D変換した結果は12bitの2進数で、"0.2"というような実数と比較できないのではないのでしょうか  from gpiozero import MCP3208で各チャネルの入力をみるとき、.valueという関数を使うと入力電流を0-1の間でフロート値にしてくれるみたいです。
guest

回答3

0

線色が全部同じ実体配線図なんてとても追っかける気にならないですけれど、「センサー」というのはどういうものですか? ADCの入力電位がハイインピーダンスになったりはしないようになっていますか。
負荷がかかるとかいうなんだかわけのわからないことより、設計ミスによるハード的な不安定さのほうが疑わしいと思います。

投稿2019/12/21 09:51

thkana

総合スコア7703

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

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

ysk_snn

2019/12/23 00:23

線色を分けるという発想すらなかったです... 人に伝えるなら必要な工夫だったと反省しています... センサは近接センサです。 とにかく触り始めたところで、動けば良いかな?という気持ちだったので、正直ハイインピーダンスという言葉も知りませんでした。 基礎的な勉強からし直します。コメントありがとうございます!
guest

0

ベストアンサー

とりあえずぱっと見て変だったところ:

黄色LED部分の回路図(赤色も一緒)


質問文の画像から読み取ったもの


(スイッチのon/offはデジタルなんだからわざわざADCに突っ込まなくてもGPIOに入れればいいじゃんとか置いといて)
普通はこうするって回路(スイッチ側の抵抗は10kとか)

LED部分回路図

投稿2019/12/20 06:48

ozwk

総合スコア13551

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

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

ysk_snn

2019/12/23 00:43

ご指摘ありがとうございます! GPIOピンは節約して使ったほうがいいのかな、という発想で余計な工夫をしてしまいました... 他の方のご指摘も、明らかに私に基本的な知識すらないことが原因です... 具体的に改善策をいただけてすごく嬉しかったです。 普通はこうする、という内容を真似することからはじめたいと思います!
guest

0

以下のように書き直してみたところ、おおむね予定していたとおりに動くようになりました!

しかし、やはりときどき動作が不安定になります。
ラズパイに負荷をかけすぎるようなコードになっているのでしょうか。

python3

1from gpiozero import MCP3208 2import RPi.GPIO as GPIO 3import time 4 5GPIO.setmode(GPIO.BCM) 6GPIO.setup(20, GPIO.IN) #output_check 7GPIO.setup(21, GPIO.OUT) #output 8GPIO.setup(23, GPIO.OUT) #red_signal 9GPIO.setup(24, GPIO.OUT) #yellow_signal 10 11ch0 = MCP3208(channel = 0) #stop_sensor___<0.5_stop 12ch1 = MCP3208(channel = 1) #ready_sensor 13ch2 = MCP3208(channel = 2) #trigger_sensor 14ch3 = MCP3208(channel = 3) #yellow_signal 15ch4 = MCP3208(channel = 4) #red_signal 16 17#sensor's_threthold 18ch1th = 0.1 19ch2th = 0.1 20 21def CurrentStatus(st):#st = 0, 1 22 status = {0:'waiting',1:'sensing'} 23 return status[st] 24 25def YellowSignal(): 26 if ch3.value > 0.2: 27 global CS 28 print('sensing') 29 CS = CurrentStatus(1)#to_sense 30 else: 31 pass 32 33def RedSignal(): 34 if ch4.value > 0.2: 35 global CS 36 print('waiting') 37 CS = CurrentStatus(0)#to_wait 38 else: 39 pass 40 41def SignalSwitch():#continue 42 if CS == 'waiting': 43 YellowSignal() 44 elif CS == 'sensing': 45 RedSignal() 46 47def ControlOutput(): 48 global t1,t2,tsub 49 #outputting_or_waiting 50 #outputting 51 if GPIO.input(20) == GPIO.HIGH: 52 if ch0.value > 0.5: 53 GPIO.output(21,GPIO.LOW) 54 else: 55 pass 56 #waiting 57 elif GPIO.input(20) == GPIO.LOW: 58 try: 59 #ready_sensor 60 if ch1.value > ch1th and ch2.value < ch2th: 61 t1 = time.time() 62 else: 63 pass 64 #trigger_sensor 65 if ch1.value < ch1th and ch2.value > ch2th: 66 t2 = time.time() 67 tsub = t2- t1 68 if 0.0001 < tsub < 0.1: 69 print('start_injectioning___' + str(tsub)) 70 GPIO.output(21,GPIO.HIGH) 71 del t1,t2,tsub 72 else: 73 time.sleep(0.1) 74 print('out_of_range_error___' + str(tsub)) 75 print('reset,_now_not_ready') 76 del t1,t2,tsub 77 #neither_sensor_is_on__or_each_sensor_is_on 78 else: 79 pass 80 except NameError: 81 pass 82 83def WorkSwitch():#continue 84 if CS == 'waiting': 85 pass 86 elif CS == 'sensing': 87 ControlOutput() 88 89def GPIOSwitch():#once 90 #print(CS) 91 if CS == 'waiting': 92 GPIO.output(23,GPIO.LOW)#RedLED 93 GPIO.output(21,GPIO.LOW)#output 94 time.sleep(0.0001)#buffer 95 GPIO.output(24,GPIO.HIGH)#YellowLED 96 elif CS == 'sensing': 97 GPIO.output(24,GPIO.LOW) 98 time.sleep(0.0001)#buffer 99 GPIO.output(23,GPIO.HIGH) 100 101if __name__ == '__main__': 102 #initial 103 CS = CurrentStatus(0) 104 105 while True: 106 try: 107 if CS == 'waiting': 108 GPIOSwitch() 109 print('switch_wait') 110 while CS == 'waiting': 111 SignalSwitch() 112 WorkSwitch() 113 elif CS == 'sensing': 114 GPIOSwitch() 115 print('switch_sense') 116 while CS == 'sensing': 117 SignalSwitch() 118 WorkSwitch() 119 except KeyboardInterrupt: 120 GPIO.cleanup() 121 print('cleanup')

投稿2019/12/20 05:29

ysk_snn

総合スコア21

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

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

thkana

2019/12/21 09:52

追加情報ということなら質問を編集して下さい。
ysk_snn

2019/12/23 00:16

マナーを理解できておらずすみません、削除依頼申請しました... 次回から質問を編集します。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.36%

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

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

質問する

関連した質問