I am writing a python script, that will show the status of a raspberry pi's gpio input pins in a web browser. This script is just for the backend testing:
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)
My output crazily spams the screen with the number until the input switch is turned off. How can I prevent the same consecutive line from repeating immediately? Thanks!
You could modify your code to work with an 'on change' type logic:
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()
I don't have access to your libraries so this code is untested but should be logically correct.
How about printing only when the input states actually change? Something like this (untested):
# 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
So to explain what this new loop code is doing:
old_input_states
is created which contains three None
entries. This will be used to remember the last state of the three GPIOs.GPIO.input(n)
function is called, for n
being 37, 32 and 29 for the three GPIOs. The resulting list input_states
now contains the three GPIO states.old_input_states
list and if they differ, it will do the following:
name
in 'One'
, 'Two'
and 'Three'
(which are enumerated by n
, ie 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
to match input_states
so in the next loop, it will only check (and potentially print) again if the input_states
changed.EDIT
Note that the code will output all GPIOs which are currently False
at the point where a change is detected. To only print the ones going from True
to False
, you should be able to use the following code for the section starting with the # New loop
comment:
# 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
EDIT 2
As indicated by the OP, the preferred output is in list-form anyway. Also there appeared to be some bouncing happening on the switch inputs to the GPIOs, which could be improved by using the time.sleep
calls. Further, the output should be inverted. The final code of the while
loop looks like this:
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
Disclaimer: For better debouncing reliability of switches I'd use different code, but that is beyond the scope of this question
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.