проблема с RPIO PWM
-
Здравствуйте!
Имеется Raspberry PI, Сервомашинка и кулер комповый 4пин(ШИМ)
2 скрипта отвечающих за:- управление сервой при помощи 2 кнопок
#!/usr/bin/python import time from RPIO import PWM PWM.setup() PWM.init_channel(1) servo = PWM.Servo() servo.set_servo(7, 1500) from RPi import GPIO button1Pin = 18 button2Pin = 15 GPIO.setmode(GPIO.BCM) GPIO.setup(button1Pin, GPIO.IN) GPIO.setup(button2Pin, GPIO.IN) try: while True: if not GPIO.input(button1Pin): servo.set_servo(7, 1800) time.sleep(1) elif not GPIO.input(button2Pin): servo.set_servo(7, 1200) time.sleep(1) else: servo.stop_servo(7) time.sleep(1) except KeyboardInterrupt: servo.stop_servo(7) PWM.clear_channel_gpio(1, 7)
- управление скоростью вращения кулера в зависимости от температуры
#!/usr/bin/python # _*_ coding: cp1251 _*_ from RPIO import PWM import time import datetime #time on HOUR_OFF = 0 #MIN_ON = 59 #time off HOUR_ON =7 #MIN_OFF = 25 # Setup PWM and DMA channel 0 PWM.setup() PWM.init_channel(1) # Add some pulses to the subcycle PWM.add_channel_pulse(1, 25, 0, 0) try: while True: tf=open("/sys/bus/w1/devices/28-000003352199/w1_slave") tt=tf.read() tf.close() td=tt.split("\n")[1].split(" ") [9] t=float(td[2:]) now = datetime.datetime.now() if (HOUR_ON <= now.hour) : # 8 <= 11 if (t >= 27500) and (t <= 28000): PWM.add_channel_pulse(1, 25, 0, 200) elif (t >= 28010) and (t <= 28500): PWM.add_channel_pulse(1, 25, 0, 400) elif (t >= 28510) and (t <= 29000): PWM.add_channel_pulse(1, 25, 0, 600) elif (t >= 29010) and (t <= 29500): PWM.add_channel_pulse(1, 25, 0, 800) elif (t >= 29510) and (t <= 30000): PWM.add_channel_pulse(1, 25, 0, 1000) elif (t >= 30010): PWM.add_channel_pulse(1, 25, 0, 1600) else: PWM.add_channel_pulse(1, 25, 0, 0) #print "on", (t/1000) #print now.hour time.sleep(1) else: PWM.add_channel_pulse(1, 25, 0, 0) time.sleep(1) #print "off", (t/1000) #print now.hour except KeyboardInterrupt: PWM.clear_channel_gpio(1, 25) PWM.cleanup()
Проблема заключается в то что по отдельности каждый скрипт работает отлично. Но при одновременной работе обоих скриптов, серва ведет себя некорректно, а именно крутится только в одну сторону независимо от того какую кнопку нажать. Хотя при этом вывод в консоли отображает что команды серве подаются правильные.
Помогите пожалуйста разобраться в проблеме. У меня подозрение что нормально работает только первый запущенный скрипт, второй же запускается нормально без ошибок но на деле не работает( -
Действительно… проблема.
Дело в том, что Питон — это интерпретатор, и он отрабатывает циклы ожидания, пытаясь их оптимизировать. В Вашем случае 2 цикла «накладываются» друг на друга.
Предлагаю объединить два скрипта с циклами «while True» в один скрипт с одним циклом и немного оптимизировать программу следующим образом:Строку:
tf=open("sys/bus/w1/devices/28-000003352199/w1_slave")
вынести из цикла ДО его начала, а в цикле оставить только:
tt=tf.read()
Строку:
tf.close()
тоже вынести из цикла в конец программы, но она при этом, конечно, не будет никогда выполнена — да и пусть.
Должно работать «как надо».
А по-хорошему это всё дело надо бы написать на Си в виде демона, используя библиотеку BCM 2835. При этом PWM лучше использовать встроенный аппаратный, а не программный. Тогда и нагрузка на процессор будет минимальна. Но для экспериментов Питон — самое оно. -
К сожалению я в си полный ноль. Спасибо за совет, но он не помог((
я объединил оба скрипта в один при выносе tf=open("/sys/bus/w1/devices/28-000003352199/w1_slave") до цикла, скрипт запускаться не захотел, в итоге вернул его на место
после чего начал экспериментировать с каналами.
Итог если все посадить на 0 канал то вроде бы работает но через раз, кулер при запуске скрипта временами крутится на полных оборотах, невзирая на условия температуры.
потом методом тыка пришел к тому что нужно указать задержку (если я правильно все понял) PWM.add_channel_pulse(0, 25, 100, 0)
после этого все заработало.#!/usr/bin/python # _*_ coding: cp1251 _*_ from RPIO import PWM from RPi import GPIO import time import datetime #time on HOUR_ON =7 button1Pin = 18 button2Pin = 15 GPIO.setmode(GPIO.BCM) GPIO.setup(button1Pin, GPIO.IN) GPIO.setup(button2Pin, GPIO.IN) PWM.setup() PWM.init_channel(0) PWM.add_channel_pulse(0, 25, 100, 0) time.sleep(5) servo = PWM.Servo() servo.set_servo(7, 1500) try: while True: tf=open("/sys/bus/w1/devices/28-000003352199/w1_slave") tt=tf.read() td=tt.split("\n")[1].split(" ") [9] t=float(td[2:]) now = datetime.datetime.now() if (HOUR_ON <= now.hour) : if (t >= 27500) and (t <= 28000): PWM.add_channel_pulse(0, 25, 0, 200) elif (t >= 28010) and (t <= 28500): PWM.add_channel_pulse(0, 25, 0, 400) elif (t >= 28510) and (t <= 29000): PWM.add_channel_pulse(0, 25, 0, 600) elif (t >= 29010) and (t <= 29500): PWM.add_channel_pulse(0, 25, 0, 800) elif (t >= 29510) and (t <= 30000): PWM.add_channel_pulse(0, 25, 0, 1000) elif (t >= 30010): PWM.add_channel_pulse(0, 25, 0, 1600) else: PWM.add_channel_pulse(0, 25, 0, 0) time.sleep(1) if not GPIO.input(button1Pin): servo.set_servo(7, 1800) time.sleep(1) elif not GPIO.input(button2Pin): servo.set_servo(7, 1200) time.sleep(1) else: servo.stop_servo(7) time.sleep(1) except KeyboardInterrupt: servo.stop_servo(7) PWM.cleanup() tf.close()
Стабильно или нет покажет время. В любом случае большое спасибо Вам за наводку))