Я пишу скрипт на Python, который будет показывать статус входных контактов gpio Raspberry Pi в веб-браузере. Этот скрипт предназначен только для внутреннего тестирования:
import RPi.GPIO as GPIO
import time
import os
os.system('clear')
GPIO.setmode(GPIO.BOARD)
GPIO.setup(29, GPIO.IN, pull_up_down=GPIO.PUD_UP)
GPIO.setup(32, GPIO.IN, pull_up_down=GPIO.PUD_UP)
GPIO.setup(37, GPIO.IN, pull_up_down=GPIO.PUD_UP)
while True:
input_state = GPIO.input(37)
if input_state == False:
print('One')
time.sleep(0.2)
input_state = GPIO.input(32)
if input_state == False:
print('Two')
time.sleep(0.2)
input_state = GPIO.input(29)
if input_state == False:
print('Three')
time.sleep(.02)
Мой вывод безумно спамит экран номером, пока не выключится входной переключатель. Как я могу предотвратить немедленное повторение одной и той же последовательной строки? Спасибо!
Ответ 1 · рейтинг 1 · FriendFX
Как насчет печати только тогда, когда состояния ввода действительно меняются? Что-то вроде этого (не проверено):
# Your code to initialise everything:
import RPi.GPIO as GPIO
import time
import os
os.system('clear')
GPIO.setmode(GPIO.BOARD)
GPIO.setup(29, GPIO.IN, pull_up_down=GPIO.PUD_UP)
GPIO.setup(32, GPIO.IN, pull_up_down=GPIO.PUD_UP)
GPIO.setup(37, GPIO.IN, pull_up_down=GPIO.PUD_UP)
# New loop keeping track of the previous ("old") input states:
old_input_states = [None] * 3
while True:
input_states = [GPIO.input(n) for n in (37, 32, 29)]
if input_states != old_input_states:
for n, name in enumerate(['One', 'Two', 'Three']):
if input_states[n] == False:
print name
old_input_states = input_states
Итак, чтобы объяснить, что делает этот новый код цикла:
- Сначала создается список
old_input_states, содержащий три записи None. Это будет использоваться для запоминания последнего состояния трех GPIO.
- Затем в начале цикла вызывается функция
GPIO.input(n), где n равно 37, 32 и 29 для трех GPIO. Результирующий список input_states теперь содержит три состояния GPIO.
- Then this list is compared against the
old_input_states list and if they differ, it will do the following:
- For each
name in 'One', 'Two' and 'Three' (which are enumerated by n, i.e. for 'One' it is 0, 1 for 'Two' and 2 for 'Three'), it checks the value of that input_states[n] to see if it is False and if it is, it prints the name which should match the corresponding GPIO.
- Затем он обновляет
old_input_states, чтобы он соответствовал input_states, поэтому в следующем цикле он будет проверять (и, возможно, печатать) снова, только если input_states изменился.
ИЗМЕНИТЬ
Обратите внимание, что код выведет все GPIO, которые в настоящее время имеют значение False в точке обнаружения изменения. Чтобы напечатать только те, которые идут от True до False, вы должны иметь возможность использовать следующий код для раздела, начинающегося с комментария # New loop:
# New loop keeping track of the previous ("old") input states:
old_input_states = [None] * 3
while True:
input_states = [GPIO.input(n) for n in (37, 32, 29)]
for n, name in enumerate(['One', 'Two', 'Three']):
if input_states[n] != old_input_states[n] and input_states[n] == False:
print name
old_input_states = input_states
ИЗМЕНИТЬ 2
Как указано в ОП, предпочтительный вывод в любом случае находится в форме списка. Кроме того, на входах переключателя к GPIO происходили некоторые дребезги, которые можно было бы улучшить с помощью вызовов time.sleep. Далее выход следует инвертировать. Окончательный код цикла while выглядит так:
old_input_states = [None] * 3
while True:
input_states = [GPIO.input(n) for n in (37, 32, 29)]
if input_states != old_input_states:
inverted_input_states = [1 - i for i in input_states]
print inverted_input_states
time.sleep(0.2)
old_input_states = input_states
Отказ от ответственности: для повышения надежности устранения дребезга коммутаторов я бы использовал другой код, но это выходит за рамки данного вопроса
Ответ 2 · рейтинг 1 · Serdalis
Вы можете изменить свой код для работы с логикой типа "при изменении":
import RPi.GPIO as GPIO
import time
import os
os.system('clear')
GPIO.setmode(GPIO.BOARD)
# allows you to rename the io ports
io_names = [ 'One', 'Two', 'Three' ]
class IOMonitor():
def __init__( self, num , io, pud ):
self.num = num
GPIO.setup(self.num, io, pull_up_down=pud)
self.last_state = GPIO.input(self.num)
def poll( self ):
# detect current state
current_state = GPIO.input(self.num)
# compare with old state
if( current_state != self.last_state ):
# set new last state
self.last_state = current_state
# print name of io that changed
print( io_names[self.num] )
ioMonitors = [
IOMonitor(29, GPIO.IN, GPIO.PUD_UP),
IOMonitor(32, GPIO.IN, GPIO.PUD_UP),
IOMonitor(37, GPIO.IN, GPIO.PUD_UP)
]
def main():
while True:
for io in ioMonitors:
io.poll()
time.sleep(0.2)
main()
У меня нет доступа к вашим библиотекам, поэтому этот код не проверен, но должен быть логически правильным.