プログラム、電子工作ともに初心者です。
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')
回答3件
あなたの回答
tips
プレビュー