AlwaysLearningJean
Posts: 15
Joined: Mon Jul 01, 2019 1:38 am

Using the 'OR' operator with GPIO and keyboard inputs

Mon Jul 01, 2019 1:50 am

Hi everyone, first i'd like to say that english is not my first language and i'll do my best to write correctly.
I am attempting to use the 'OR' operator in my code and i am not successful. i am using some code found online (no credits to me )
and it is working but not doing as expected.
What i want is that i need to type the good keyword OR activate a button so the code activate a relay.
When i execute the code it does not take the button into consideration only the keyword, can you please tell me what i am doing wrong ?
Thank you for taking of your time to help me.

#!/usr/bin/python
import getpass
import time
from time import sleep
import RPi.GPIO as GPIO
GPIO.setmode(GPIO.BCM)
GPIO.setup(7, GPIO.OUT)
GPIO.setup(8, GPIO.IN)

keywords = ['hello','good','evening','and','welcome']

while 1:
typing = getpass.getpass('Enter a word: ')

if typing in keywords or GPIO.input(8) == 1:
GPIO.output(7, True)
time.sleep(1.5)
GPIO.output(7, False)
print ("Correct spelling!")
else:
GPIO.output(7, False)
print ("Try again.")

pcmanbob
Posts: 6449
Joined: Fri May 31, 2013 9:28 pm
Location: Mansfield UK

Re: Using the 'OR' operator with GPIO and keyboard inputs

Mon Jul 01, 2019 10:42 am

Hi.

Try changing your if statement to include brackets around each thing you want to test that way each will be evaluated and action taken if either one is true.

Code: Select all

#!/usr/bin/python
import getpass
import time
from time import sleep
import RPi.GPIO as GPIO
GPIO.setmode(GPIO.BCM)
GPIO.setup(7, GPIO.OUT)
GPIO.setup(8, GPIO.IN)

keywords = ['hello','good','evening','and','welcome']

while 1:
    typing = getpass.getpass('Enter a word: ')

    if (typing in keywords) or (GPIO.input(8) == 1):
        GPIO.output(7, True)
        time.sleep(1.5)
        GPIO.output(7, False)
        print ("Correct spelling!")
    else:
        GPIO.output(7, False)
        print ("Try again.")


and please when posting code use code tags or the code button to preserve the indentation than python relies on.
We want information… information… information........................no information no help
The use of crystal balls & mind reading are not supported

gordon77
Posts: 4079
Joined: Sun Aug 05, 2012 3:12 pm

Re: Using the 'OR' operator with GPIO and keyboard inputs

Mon Jul 01, 2019 11:31 am

How have you connected the switch?

User avatar
B.Goode
Posts: 8058
Joined: Mon Sep 01, 2014 4:03 pm
Location: UK

Re: Using the 'OR' operator with GPIO and keyboard inputs

Mon Jul 01, 2019 11:52 am

When i execute the code it does not take the button into consideration only the keyword, can you please tell me what i am doing wrong ?

In addition to what has already been suggested..

Maybe you have misunderstood what the Python Boolean comparison operator 'or' does.

It is difficult to explain if English is not easy for you.

In your comparison either one of the conditions being met will result in the comparison being True.

If you need both things to match you might need the comparison to use 'and' ?

AlwaysLearningJean
Posts: 15
Joined: Mon Jul 01, 2019 1:38 am

Re: Using the 'OR' operator with GPIO and keyboard inputs

Mon Jul 01, 2019 6:03 pm

pcmanbob wrote:
Mon Jul 01, 2019 10:42 am
Hi.

Try changing your if statement to include brackets around each thing you want to test that way each will be evaluated and action taken if either one is true.

Code: Select all

#!/usr/bin/python
import getpass
import time
from time import sleep
import RPi.GPIO as GPIO
GPIO.setmode(GPIO.BCM)
GPIO.setup(7, GPIO.OUT)
GPIO.setup(8, GPIO.IN)

keywords = ['hello','good','evening','and','welcome']

while 1:
    typing = getpass.getpass('Enter a word: ')

    if (typing in keywords) or (GPIO.input(8) == 1):
        GPIO.output(7, True)
        time.sleep(1.5)
        GPIO.output(7, False)
        print ("Correct spelling!")
    else:
        GPIO.output(7, False)
        print ("Try again.")


and please when posting code use code tags or the code button to preserve the indentation than python relies on.
Hi, i have tested your solution and it did the same thing the button is still not doing anything, i am wondering if it may be a problem with the wiring ? My button is connected to GPIO 8 and the other wire is 3.3 +V. Do you think that this is the problem ?
(Sorry for the code tag, i did not know, thanks to you now i do ! )

AlwaysLearningJean
Posts: 15
Joined: Mon Jul 01, 2019 1:38 am

Re: Using the 'OR' operator with GPIO and keyboard inputs

Mon Jul 01, 2019 6:04 pm

gordon77 wrote:
Mon Jul 01, 2019 11:31 am
How have you connected the switch?
Yes i did, on GPIO 8 and the other wire is 3.3 +V, is it correct ?

AlwaysLearningJean
Posts: 15
Joined: Mon Jul 01, 2019 1:38 am

Re: Using the 'OR' operator with GPIO and keyboard inputs

Mon Jul 01, 2019 6:10 pm

B.Goode wrote:
Mon Jul 01, 2019 11:52 am
When i execute the code it does not take the button into consideration only the keyword, can you please tell me what i am doing wrong ?

In addition to what has already been suggested..

Maybe you have misunderstood what the Python Boolean comparison operator 'or' does.

It is difficult to explain if English is not easy for you.

In your comparison either one of the conditions being met will result in the comparison being True.

If you need both things to match you might need the comparison to use 'and' ?
I am able to understand everything well, therefore i always make mistake when i write because i do not know every rules of the english language.
What i really is really either one of the two to activate GPIO 7
The keyboard is outside my room for unlocking the door and the button is for me to get out of the room without having two keyboard.

User avatar
Douglas6
Posts: 4715
Joined: Sat Mar 16, 2013 5:34 am
Location: Chicago, IL

Re: Using the 'OR' operator with GPIO and keyboard inputs

Mon Jul 01, 2019 6:15 pm

The getpass() function is blocking, right? That means your code will wait for keyboard input before ever testing for a button press. Have you tried holding down the button while entering an invalid password? That should prove that your problem is not with the if statement.

gordon77
Posts: 4079
Joined: Sun Aug 05, 2012 3:12 pm

Re: Using the 'OR' operator with GPIO and keyboard inputs

Mon Jul 01, 2019 6:34 pm

AlwaysLearningJean wrote:
Mon Jul 01, 2019 6:04 pm
gordon77 wrote:
Mon Jul 01, 2019 11:31 am
How have you connected the switch?
Yes i did, on GPIO 8 and the other wire is 3.3 +V, is it correct ?
Yes as long as you used physical pin 24.

AlwaysLearningJean
Posts: 15
Joined: Mon Jul 01, 2019 1:38 am

Re: Using the 'OR' operator with GPIO and keyboard inputs

Mon Jul 01, 2019 6:54 pm

AlwaysLearningJean wrote:
Mon Jul 01, 2019 6:03 pm
pcmanbob wrote:
Mon Jul 01, 2019 10:42 am
Hi.

Try changing your if statement to include brackets around each thing you want to test that way each will be evaluated and action taken if either one is true.

Code: Select all

#!/usr/bin/python
import getpass
import time
from time import sleep
import RPi.GPIO as GPIO
GPIO.setmode(GPIO.BCM)
GPIO.setup(7, GPIO.OUT)
GPIO.setup(8, GPIO.IN)

keywords = ['hello','good','evening','and','welcome']

while 1:
    typing = getpass.getpass('Enter a word: ')

    if (typing in keywords) or (GPIO.input(8) == 1):
        GPIO.output(7, True)
        time.sleep(1.5)
        GPIO.output(7, False)
        print ("Correct spelling!")
    else:
        GPIO.output(7, False)
        print ("Try again.")


and please when posting code use code tags or the code button to preserve the indentation than python relies on.
Hi, i have tested your solution and it did the same thing the button is still not doing anything, i am wondering if it may be a problem with the wiring ? My button is connected to GPIO 8 and the other wire is 3.3 +V. Do you think that this is the problem ?
(Sorry for the code tag, i did not know, thanks to you now i do ! )
update* i have just observe that now whatever i type, the code is accepting it so the relay is activating even if it's wrong, i have tried with the button unpluged to be sure that it was not a bad component. To be honest i am really not sure as why it does that, could that be the brackets ?

AlwaysLearningJean
Posts: 15
Joined: Mon Jul 01, 2019 1:38 am

Re: Using the 'OR' operator with GPIO and keyboard inputs

Mon Jul 01, 2019 6:55 pm

gordon77 wrote:
Mon Jul 01, 2019 6:34 pm
AlwaysLearningJean wrote:
Mon Jul 01, 2019 6:04 pm
gordon77 wrote:
Mon Jul 01, 2019 11:31 am
How have you connected the switch?
Yes i did, on GPIO 8 and the other wire is 3.3 +V, is it correct ?
Yes as long as you used physical pin 24.
It is ! i've just check to be sure.

AlwaysLearningJean
Posts: 15
Joined: Mon Jul 01, 2019 1:38 am

Re: Using the 'OR' operator with GPIO and keyboard inputs

Mon Jul 01, 2019 7:01 pm

AlwaysLearningJean wrote:
Mon Jul 01, 2019 6:54 pm
AlwaysLearningJean wrote:
Mon Jul 01, 2019 6:03 pm
pcmanbob wrote:
Mon Jul 01, 2019 10:42 am
Hi.

Try changing your if statement to include brackets around each thing you want to test that way each will be evaluated and action taken if either one is true.

Code: Select all

#!/usr/bin/python
import getpass
import time
from time import sleep
import RPi.GPIO as GPIO
GPIO.setmode(GPIO.BCM)
GPIO.setup(7, GPIO.OUT)
GPIO.setup(8, GPIO.IN)

keywords = ['hello','good','evening','and','welcome']

while 1:
    typing = getpass.getpass('Enter a word: ')

    if (typing in keywords) or (GPIO.input(8) == 1):
        GPIO.output(7, True)
        time.sleep(1.5)
        GPIO.output(7, False)
        print ("Correct spelling!")
    else:
        GPIO.output(7, False)
        print ("Try again.")


and please when posting code use code tags or the code button to preserve the indentation than python relies on.
Hi, i have tested your solution and it did the same thing the button is still not doing anything, i am wondering if it may be a problem with the wiring ? My button is connected to GPIO 8 and the other wire is 3.3 +V. Do you think that this is the problem ?
(Sorry for the code tag, i did not know, thanks to you now i do ! )
update* i have just observe that now whatever i type, the code is accepting it so the relay is activating even if it's wrong, i have tried with the button unpluged to be sure that it was not a bad component. To be honest i am really not sure as why it does that, could that be the brackets ?
Sorry for Reupdating again, when i totally remove the

Code: Select all

 (GPIO.input(8) == 1 )
my code is only accepting the predetermined keywords, but when i add it, it will accept everything, i did not see that before my bad

gordon77
Posts: 4079
Joined: Sun Aug 05, 2012 3:12 pm

Re: Using the 'OR' operator with GPIO and keyboard inputs

Mon Jul 01, 2019 7:02 pm

Try adding a pull down to your gpio.

GPIO.setup(8, GPIO.IN, pull_up_down=GPIO.PUD_DOWN)

AlwaysLearningJean
Posts: 15
Joined: Mon Jul 01, 2019 1:38 am

Re: Using the 'OR' operator with GPIO and keyboard inputs

Mon Jul 01, 2019 7:04 pm

Douglas6 wrote:
Mon Jul 01, 2019 6:15 pm
The getpass() function is blocking, right? That means your code will wait for keyboard input before ever testing for a button press. Have you tried holding down the button while entering an invalid password? That should prove that your problem is not with the if statement.
This would make sense but like i have said below to another reply, when i add GPIO.input(8) ==1 (with and without brakets) my code start accepting whatever i type, even if i totally unplug the button.

AlwaysLearningJean
Posts: 15
Joined: Mon Jul 01, 2019 1:38 am

Re: Using the 'OR' operator with GPIO and keyboard inputs

Mon Jul 01, 2019 7:09 pm

gordon77 wrote:
Mon Jul 01, 2019 7:02 pm
Try adding a pull down to your gpio.

GPIO.setup(8, GPIO.IN, pull_up_down=GPIO.PUD_DOWN)
Yes with this it worked ! but i still have to type something while holding the button, if i type something wrong without holding the button it print : Try again. as expected !

so now i have to figure out how to remove the need to type something for this to work !

AlwaysLearningJean
Posts: 15
Joined: Mon Jul 01, 2019 1:38 am

Re: Using the 'OR' operator with GPIO and keyboard inputs

Mon Jul 01, 2019 7:11 pm

AlwaysLearningJean wrote:
Mon Jul 01, 2019 7:04 pm
Douglas6 wrote:
Mon Jul 01, 2019 6:15 pm
The getpass() function is blocking, right? That means your code will wait for keyboard input before ever testing for a button press. Have you tried holding down the button while entering an invalid password? That should prove that your problem is not with the if statement.
This would make sense but like i have said below to another reply, when i add GPIO.input(8) ==1 (with and without brakets) my code start accepting whatever i type, even if i totally unplug the button.
update Gordon77 told me to add

Code: Select all

 GPIO.setup(8, GPIO.IN, pull_up_down=GPIO.PUD_DOWN) 
it did work with it and now i am obligated to type something while holding the button as you said, any idea on how i could bypass the need to type something before ?

gordon77
Posts: 4079
Joined: Sun Aug 05, 2012 3:12 pm

Re: Using the 'OR' operator with GPIO and keyboard inputs

Mon Jul 01, 2019 7:56 pm

AlwaysLearningJean wrote:
Mon Jul 01, 2019 7:09 pm
gordon77 wrote:
Mon Jul 01, 2019 7:02 pm
Try adding a pull down to your gpio.

GPIO.setup(8, GPIO.IN, pull_up_down=GPIO.PUD_DOWN)
Yes with this it worked ! but i still have to type something while holding the button, if i type something wrong without holding the button it print : Try again. as expected !

so now i have to figure out how to remove the need to type something for this to work !
Do you mean you Don't want to type anything? If so just use

if GPIO.input(8) == 1:

AlwaysLearningJean
Posts: 15
Joined: Mon Jul 01, 2019 1:38 am

Re: Using the 'OR' operator with GPIO and keyboard inputs

Mon Jul 01, 2019 8:27 pm

gordon77 wrote:
Mon Jul 01, 2019 7:56 pm
AlwaysLearningJean wrote:
Mon Jul 01, 2019 7:09 pm
gordon77 wrote:
Mon Jul 01, 2019 7:02 pm
Try adding a pull down to your gpio.

GPIO.setup(8, GPIO.IN, pull_up_down=GPIO.PUD_DOWN)
Yes with this it worked ! but i still have to type something while holding the button, if i type something wrong without holding the button it print : Try again. as expected !

so now i have to figure out how to remove the need to type something for this to work !
Do you mean you Don't want to type anything? If so just use

if GPIO.input(8) == 1:
As said previously, this code is intended to be for unlocking a door, the keyboard is for the outside to enter and the push button is for exiting the room without having to use two keyboards so, in my code i need either one of the two to be true to activate GPIO 7

User avatar
Douglas6
Posts: 4715
Joined: Sat Mar 16, 2013 5:34 am
Location: Chicago, IL

Re: Using the 'OR' operator with GPIO and keyboard inputs

Mon Jul 01, 2019 8:53 pm

Non-blocking keyboard input in Python is a little tricky, but using gpiozero (https://gpiozero.readthedocs.io/en/stable/) instead of RPI.GPIO, you can setup a callback function for when a button is pressed, even if the program is waiting on the keyboard (I think).

ghp
Posts: 1395
Joined: Wed Jun 12, 2013 12:41 pm
Location: Stuttgart Germany
Contact: Website

Re: Using the 'OR' operator with GPIO and keyboard inputs

Mon Jul 01, 2019 9:02 pm

Let me propose a solution which might look complex, but hopefully solves the problem.
Make three thread, each responsible for one task only.
- thread_keyboard, read in the keyboard, check for correct word and putting 'unlock' to a queue.
- thread_gpio, just read the gpio pin and put 'unlock' to a queue
- thread_unlock, reading the queue and unlocking .

Code: Select all

#!/usr/bin/python3
import threading
import queue
import time
import getpass

# check library import and if not available, then switch to a test mode
# here I check code usually on a laptop, which is more convenient as on pi
try:
    import RPi.GPIO as GPIO
    test_mode = False
except Exception:
    test_mode = True
    
if not test_mode:
    GPIO.setmode(GPIO.BCM)

keywords = ['hello','good','evening','and','welcome']

events_queue = queue.Queue()


def thread_run_keyboard():
    while True:
        typing = getpass.getpass('Enter a word: ')
        if typing in keywords:
            events_queue.put("unlock")
    
def thread_run_gpio():
    if test_mode:
        while True:
            # random input simulation
            time.sleep(10)
            events_queue.put("unlock")
    else:
                
        GPIO.setup(8, GPIO.IN, pull_up_down=GPIO.PUD_DOWN) 
        while True:
            if GPIO.input(8) == 1:
                events_queue.put("unlock")
            # prevent bouncing
            time.sleep(0.1)
            # wait for button released
            while GPIO.input(8) == 1:
                pass
            time.sleep(0.1)

def thread_run_unlock():
    if test_mode:
        while True:
            e = events_queue.get()
            if e == 'unlock':
                print("eventreceived: ", e)
                time.sleep(1.5)
    else:    
        GPIO.setup(7, GPIO.OUT)
        while True:
            e = events_queue.get()
            if e == 'unlock':
                GPIO.output(7, True)
                time.sleep(1.5)
                GPIO.output(7, False)
        
thread_keyboard = threading.Thread(target=thread_run_keyboard)
thread_keyboard.start()

gpio_thread = threading.Thread(target=thread_run_gpio)
gpio_thread.start()

thread_unlock = threading.Thread(target=thread_run_unlock)
thread_unlock.start()

event=threading.Event()
try:
    event.wait()
except KeyboardInterrupt:
    pass

if not test_mode:
    GPIO.clear()

There are a few problems left for training your coding skills:
- how to graceful terminate the code.
- what happens if multiple 'unlock' are on the queue, should these result in may 1.5 open intervals or being processed only once.

AlwaysLearningJean
Posts: 15
Joined: Mon Jul 01, 2019 1:38 am

Re: Using the 'OR' operator with GPIO and keyboard inputs

Tue Jul 02, 2019 1:03 am

Douglas6 wrote:
Mon Jul 01, 2019 8:53 pm
Non-blocking keyboard input in Python is a little tricky, but using gpiozero (https://gpiozero.readthedocs.io/en/stable/) instead of RPI.GPIO, you can setup a callback function for when a button is pressed, even if the program is waiting on the keyboard (I think).
thank you, i will take a look at that !

AlwaysLearningJean
Posts: 15
Joined: Mon Jul 01, 2019 1:38 am

Re: Using the 'OR' operator with GPIO and keyboard inputs

Tue Jul 02, 2019 1:15 am

ghp wrote:
Mon Jul 01, 2019 9:02 pm
Let me propose a solution which might look complex, but hopefully solves the problem.
Make three thread, each responsible for one task only.
- thread_keyboard, read in the keyboard, check for correct word and putting 'unlock' to a queue.
- thread_gpio, just read the gpio pin and put 'unlock' to a queue
- thread_unlock, reading the queue and unlocking .

Code: Select all

#!/usr/bin/python3
import threading
import queue
import time
import getpass

# check library import and if not available, then switch to a test mode
# here I check code usually on a laptop, which is more convenient as on pi
try:
    import RPi.GPIO as GPIO
    test_mode = False
except Exception:
    test_mode = True
    
if not test_mode:
    GPIO.setmode(GPIO.BCM)

keywords = ['hello','good','evening','and','welcome']

events_queue = queue.Queue()


def thread_run_keyboard():
    while True:
        typing = getpass.getpass('Enter a word: ')
        if typing in keywords:
            events_queue.put("unlock")
    
def thread_run_gpio():
    if test_mode:
        while True:
            # random input simulation
            time.sleep(10)
            events_queue.put("unlock")
    else:
                
        GPIO.setup(8, GPIO.IN, pull_up_down=GPIO.PUD_DOWN) 
        while True:
            if GPIO.input(8) == 1:
                events_queue.put("unlock")
            # prevent bouncing
            time.sleep(0.1)
            # wait for button released
            while GPIO.input(8) == 1:
                pass
            time.sleep(0.1)

def thread_run_unlock():
    if test_mode:
        while True:
            e = events_queue.get()
            if e == 'unlock':
                print("eventreceived: ", e)
                time.sleep(1.5)
    else:    
        GPIO.setup(7, GPIO.OUT)
        while True:
            e = events_queue.get()
            if e == 'unlock':
                GPIO.output(7, True)
                time.sleep(1.5)
                GPIO.output(7, False)
        
thread_keyboard = threading.Thread(target=thread_run_keyboard)
thread_keyboard.start()

gpio_thread = threading.Thread(target=thread_run_gpio)
gpio_thread.start()

thread_unlock = threading.Thread(target=thread_run_unlock)
thread_unlock.start()

event=threading.Event()
try:
    event.wait()
except KeyboardInterrupt:
    pass

if not test_mode:
    GPIO.clear()

There are a few problems left for training your coding skills:
- how to graceful terminate the code.
- what happens if multiple 'unlock' are on the queue, should these result in may 1.5 open intervals or being processed only once.
i will try it right now ! I love learning knew ways to do things, i did not even know that we could write it that way.
It surely is more complex than what i am used to, but since you did make most of it i am confident that i can at
least find whats left by myself. Thank you, i'll keep you updated !

AlwaysLearningJean
Posts: 15
Joined: Mon Jul 01, 2019 1:38 am

Re: Using the 'OR' operator with GPIO and keyboard inputs

Tue Jul 02, 2019 1:18 am

AlwaysLearningJean wrote:
Tue Jul 02, 2019 1:15 am
ghp wrote:
Mon Jul 01, 2019 9:02 pm
Let me propose a solution which might look complex, but hopefully solves the problem.
Make three thread, each responsible for one task only.
- thread_keyboard, read in the keyboard, check for correct word and putting 'unlock' to a queue.
- thread_gpio, just read the gpio pin and put 'unlock' to a queue
- thread_unlock, reading the queue and unlocking .

Code: Select all

#!/usr/bin/python3
import threading
import queue
import time
import getpass

# check library import and if not available, then switch to a test mode
# here I check code usually on a laptop, which is more convenient as on pi
try:
    import RPi.GPIO as GPIO
    test_mode = False
except Exception:
    test_mode = True
    
if not test_mode:
    GPIO.setmode(GPIO.BCM)

keywords = ['hello','good','evening','and','welcome']

events_queue = queue.Queue()


def thread_run_keyboard():
    while True:
        typing = getpass.getpass('Enter a word: ')
        if typing in keywords:
            events_queue.put("unlock")
    
def thread_run_gpio():
    if test_mode:
        while True:
            # random input simulation
            time.sleep(10)
            events_queue.put("unlock")
    else:
                
        GPIO.setup(8, GPIO.IN, pull_up_down=GPIO.PUD_DOWN) 
        while True:
            if GPIO.input(8) == 1:
                events_queue.put("unlock")
            # prevent bouncing
            time.sleep(0.1)
            # wait for button released
            while GPIO.input(8) == 1:
                pass
            time.sleep(0.1)

def thread_run_unlock():
    if test_mode:
        while True:
            e = events_queue.get()
            if e == 'unlock':
                print("eventreceived: ", e)
                time.sleep(1.5)
    else:    
        GPIO.setup(7, GPIO.OUT)
        while True:
            e = events_queue.get()
            if e == 'unlock':
                GPIO.output(7, True)
                time.sleep(1.5)
                GPIO.output(7, False)
        
thread_keyboard = threading.Thread(target=thread_run_keyboard)
thread_keyboard.start()

gpio_thread = threading.Thread(target=thread_run_gpio)
gpio_thread.start()

thread_unlock = threading.Thread(target=thread_run_unlock)
thread_unlock.start()

event=threading.Event()
try:
    event.wait()
except KeyboardInterrupt:
    pass

if not test_mode:
    GPIO.clear()

There are a few problems left for training your coding skills:
- how to graceful terminate the code.
- what happens if multiple 'unlock' are on the queue, should these result in may 1.5 open intervals or being processed only once.
i will try it right now ! I love learning knew ways to do things, i did not even know that we could write it that way.
It surely is more complex than what i am used to, but since you did make most of it i am confident that i can at
least find whats left by myself. Thank you, i'll keep you updated !
*Update : It is working like a charm on the first try, i am very happy ! Thank you !

gordon77
Posts: 4079
Joined: Sun Aug 05, 2012 3:12 pm

Re: Using the 'OR' operator with GPIO and keyboard inputs

Tue Jul 02, 2019 9:00 am

I was interested to see if this could be done without threads, and after some googling and experimenting managed this...

after an incorrect keyboard entry it will clear after 5 seconds.

Note it won't run from IDLE, use python3 filename.py

Based on https://stackoverflow.com/questions/986 ... nts-in-osx

Code: Select all

import termios, fcntl, sys, os
import time
#from time import sleep
import RPi.GPIO as GPIO
GPIO.setwarnings(False)
GPIO.setmode(GPIO.BCM)
GPIO.setup(7, GPIO.OUT)
GPIO.setup(8, GPIO.IN, pull_up_down=GPIO.PUD_DOWN)

# read keyboard setup
fd = sys.stdin.fileno()
oldterm = termios.tcgetattr(fd)
newattr = termios.tcgetattr(fd)
newattr[3] = newattr[3] & ~termios.ICANON & ~termios.ECHO
termios.tcsetattr(fd, termios.TCSANOW, newattr)
oldflags = fcntl.fcntl(fd, fcntl.F_GETFL)
fcntl.fcntl(fd, fcntl.F_SETFL, oldflags | os.O_NONBLOCK)

keywords = ['hello','good','evening','and','welcome']

keyinput =""
start = time.time()

try:
    while 1:
        try:
            # read keyboard
            c = sys.stdin.read(1)
            # add key to keyinput string
            if c != '':
               keyinput = keyinput + c
               start = time.time()
            # check string against keywords or check button press      
            if keyinput in keywords or GPIO.input(8) == 1:
               print ("LOCK OPEN")
               keyinput =""
               GPIO.output(7, True)
               time.sleep(1.5)
               print ("LOCK CLOSED")
               GPIO.output(7, False)
            # clear incorrect keyinput string after 5 seconds   
            if time.time() - start > 5 and keyinput !="":
               start = time.time()
               keyinput =""
               print ("KEYINPUT CLEARED")

        except IOError: pass
finally:
    termios.tcsetattr(fd, termios.TCSAFLUSH, oldterm)
    fcntl.fcntl(fd, fcntl.F_SETFL, oldflags)

AlwaysLearningJean
Posts: 15
Joined: Mon Jul 01, 2019 1:38 am

Re: Using the 'OR' operator with GPIO and keyboard inputs

Tue Jul 02, 2019 2:38 pm

gordon77 wrote:
Tue Jul 02, 2019 9:00 am
I was interested to see if this could be done without threads, and after some googling and experimenting managed this...

after an incorrect keyboard entry it will clear after 5 seconds.

Note it won't run from IDLE, use python3 filename.py

Based on https://stackoverflow.com/questions/986 ... nts-in-osx

Code: Select all

import termios, fcntl, sys, os
import time
#from time import sleep
import RPi.GPIO as GPIO
GPIO.setwarnings(False)
GPIO.setmode(GPIO.BCM)
GPIO.setup(7, GPIO.OUT)
GPIO.setup(8, GPIO.IN, pull_up_down=GPIO.PUD_DOWN)

# read keyboard setup
fd = sys.stdin.fileno()
oldterm = termios.tcgetattr(fd)
newattr = termios.tcgetattr(fd)
newattr[3] = newattr[3] & ~termios.ICANON & ~termios.ECHO
termios.tcsetattr(fd, termios.TCSANOW, newattr)
oldflags = fcntl.fcntl(fd, fcntl.F_GETFL)
fcntl.fcntl(fd, fcntl.F_SETFL, oldflags | os.O_NONBLOCK)

keywords = ['hello','good','evening','and','welcome']

keyinput =""
start = time.time()

try:
    while 1:
        try:
            # read keyboard
            c = sys.stdin.read(1)
            # add key to keyinput string
            if c != '':
               keyinput = keyinput + c
               start = time.time()
            # check string against keywords or check button press      
            if keyinput in keywords or GPIO.input(8) == 1:
               print ("LOCK OPEN")
               keyinput =""
               GPIO.output(7, True)
               time.sleep(1.5)
               print ("LOCK CLOSED")
               GPIO.output(7, False)
            # clear incorrect keyinput string after 5 seconds   
            if time.time() - start > 5 and keyinput !="":
               start = time.time()
               keyinput =""
               print ("KEYINPUT CLEARED")

        except IOError: pass
finally:
    termios.tcsetattr(fd, termios.TCSAFLUSH, oldterm)
    fcntl.fcntl(fd, fcntl.F_SETFL, oldflags)
Yes it's working really great on the first time!! Also it's easier for me to understand the code that what, i think this could be the final solution
thanks a lot for putting time and effort into this, i really appreciate !

Return to “Python”