Raspberry: GPIOs+Buttons - Same code, different effects - python

I got a problem which I simply can't solve on my own.
Maybe one of you knows more?
I wrote a code which handles my buttons. The first Button on my GPIO2
works fine. However the GPIO21 is buggy. It continues to print the
message, which is originally preserved for the pressing of the button, directly
without stopping. It doesn't matter, if the if-condition says
elif GPIO.input(21) == True, or elif GPIO.input(21) == GPIO.LOW, or even
elif GPIO.input(21) == GPIO.HIGH.
It seems like the code doesn't care about the condition of the GPIO.
I tried it with different GPIOs but the result stayed the same.
anyone an idea?
import RPi.GPIO as GPIO
import time
import urllib
GPIO.setwarnings(False)
GPIO.setmode(GPIO.BCM)
GPIO.setup(2, GPIO.IN, pull_up_down=GPIO.PUD_DOWN)
GPIO.setup(21, GPIO.IN)
try:
while True:
if GPIO.input(2) == GPIO.LOW:
print("Forward works")
time.sleep(1)
elif GPIO.input(21) == True:
print("Backward works")
time.sleep(1)
except:
GPIO.cleanup()

Related

How can I set a variable in python on button press

I would like to stop a loop with a button press in python on my raspberry pi.
I came with this code:
import RPi.GPIO as GPIO
import time
GPIO.setmode(GPIO.BCM)
GPIO.setup(14, GPIO.OUT)
GPIO.setup(2,GPIO.OUT)
GPIO.setup(21,GPIO.IN)
break_prog=False
def key_press(key):
print("BREAK")
break_prog=True
GPIO.add_event_detect(21,GPIO.FALLING,callback=key_press,bouncetime=300)
for i in range(5):
if break_prog:
print("STOP THE LOOP")
break
else:
print("VERT")
GPIO.output(2,True)
GPIO.output(14,False)
time.sleep(3)
print("ROUGE")
GPIO.output(2,False)
GPIO.output(14,True)
time.sleep(6)
GPIO.cleanup()
When I press the button, 'BREAK' text clearly appears, but in my loop, the if break_prog part is not called, like the variable hasn't been set.
Any idea what I am doing wrong?

Subprocess always automatically starts when running python script

I'm trying to make a python script that starts mdk3 when a switch is flipped on (LOW) and kills it when it's switched off (HIGH). However, the mdk3 command always starts when the script is started, regardless of the switch's position. Starting the script with the switch in the ON position and then switching it OFF while it's running kills the command, as expected. However, it does not begin running again when switching it back ON. Interestingly, the text set to print functions exactly as would be expected. My code is as follows:
import RPi.GPIO as GPIO
import time
import subprocess
import os
import signal
FSU = 'sudo mdk3 mon0 d'
pro = 'subprocess.Popen(FSU, stdout=subprocess.PIPE, shell=True, preexec_fn=os.setsid)'
# tell the GPIO module that we want to use the chip's numbering scheme
GPIO.setmode(GPIO.BCM)
# Set up GPIO16 as an input with internal pull-up resistor to hold it HIGH until it is pulled down to GND by the connected switch
GPIO.setup(16, GPIO.IN, pull_up_down=GPIO.PUD_UP)
running = False
while True:
if GPIO.input(16) == GPIO.LOW:
if running == False:
print('Button was pushed!')
pro
running = True
time.sleep(0.1)
elif running == True:
print('The process is running.')
time.sleep(0.1)
elif GPIO.input(16) == GPIO.HIGH and running == True:
os.killpg(os.getpgid(pro.pid), signal.SIGTERM)
print('Process killed.')
running = False
time.sleep(0.1)
elif running == False:
print('The process is not running.')
time.sleep(0.1)
else:
print('Critical error.')
time.sleep(0.1)
The reason I'm using my own loop to poll the GPIO pins instead of the event detection built-in in the RPi.GPIO library is because it has caused me nothing but problems and doing it myself seemed simpler. Any help would be appreciated.
Edit: I'm not sure why I didn't think of putting that call into quotes. Now it doesn't run on script start, but it only runs once. As in: I start the script with the switch OFF, and it doesn't run (as expected). I switch it ON and it runs. I switch it back OFF and it successfully kills the script. However, switching it back ON doesn't restart the script. Sorry if this is a bad explanation.
subprocess.Popen() starts the process as soon as it is called and also returns the process.
So, you can simply start the process again in the loop when it needs to be running by calling the same function again.
Slightly modifying your code:
import RPi.GPIO as GPIO
import time
import subprocess
import os
import signal
proc = subprocess.Popen(FSU, stdout=subprocess.PIPE, shell=True, preexec_fn=os.setsid)
FSU = 'sudo mdk3 mon0 d'
# tell the GPIO module that we want to use the chip's numbering scheme
GPIO.setmode(GPIO.BCM)
# Set up GPIO16 as an input with internal pull-up resistor to hold it HIGH until it is pulled down to GND by the connected switch
GPIO.setup(16, GPIO.IN, pull_up_down=GPIO.PUD_UP)
running = False
while True:
if GPIO.input(16) == GPIO.LOW:
if running == False:
print('Button was pushed!')
# declare the proc variabe again and also start the process
proc = subprocess.Popen(FSU, stdout=subprocess.PIPE, shell=True, preexec_fn=os.setsid)
running = True
time.sleep(0.1)
elif running == True:
print('The process is running.')
time.sleep(0.1)
elif GPIO.input(16) == GPIO.HIGH and running == True:
os.killpg(os.getpgid(pro.pid), signal.SIGTERM)
print('Process killed.')
running = False
time.sleep(0.1)
elif running == False:
print('The process is not running.')
time.sleep(0.1)
else:
print('Critical error.')
time.sleep(0.1)
More on subprocess

GPIO in Rapberry Pi no Turn Off

Write this code with python3. But don't work. Only the relay comes on but it does not turn off.
I need this turn on and after 3 seconds to turn off.
This is my code:
import RPi.GPIO as GPIO
import time
channel = 23
# GPIO setup
GPIO.setmode(GPIO.BCM)
GPIO.setup(channel, GPIO.OUT)
def motor_on(pin):
GPIO.output(pin, GPIO.HIGH) # Turn motor on
def motor_off(pin):
GPIO.output(pin, GPIO.LOW) # Turn motor off
if __name__ == '__main__':
try:
motor_on(channel)
time.sleep(2)
motor_off(channel)
time.sleep(2)
GPIO.cleanup()
motor_on(channel)
time.sleep(2)
motor_off(channel)
time.sleep(2)
GPIO.cleanup()
except KeyboardInterrupt:
GPIO.cleanup()
There are a couple problems with your code in general -- the indentation at the end should be like this
try:
motor_on(channel)
time.sleep(2)
motor_off(channel)
time.sleep(2)
GPIO.cleanup()
motor_on(channel)
time.sleep(2)
motor_off(channel)
time.sleep(2)
GPIO.cleanup()
except KeyboardInterrupt:
GPIO.cleanup()
and as above, running motor_on() and motor_off() after GPIO.cleanup() will give you errors if you don't run GPIO.setmode() and GPIO.setup() again first -- but with those things fixed, your code works perfectly fine to turn an LED on and off, so there may be a problem with your circuit.

Thread doesn't run like I say it should with GPIOs in Python on RPi

I am creating a script on my raspberry pi that if you press a button the led on the button need to be flashing till I press the button again.
This is my code:
#!/usr/bin/python
import RPi.GPIO as GPIO
import threading
from time import sleep
GPIO.setmode(GPIO.BCM)
pushbutton = 2
led = 3
GPIO.setup(pushbutton, GPIO.IN)
GPIO.setup(led, GPIO.OUT)
class rpiThread(threading.Thread):
def __init__(self):
self.running = False
super(rpiThread, self).__init__()
def start(self):
self.running = True
super(rpiThread, self).start()
def run(self):
self.running = True
while (self.running == True):
GPIO.output(led, GPIO.HIGH)
print "HIGH"
sleep(0.05)
GPIO.output(led,GPIO.LOW)
print "LOW"
sleep(0.05)
def stop(self):
self.running = False
GPIO.output(led, GPIO.LOW)
def main():
myrpiThread = rpiThread()
pushed = GPIO.input(pushbutton)
try:
while(True):
if(pushed == False):
if(GPIO.input(pushbutton) == False):
sleep(0.5)
if(GPIO.input(pushbutton) == False):
myrpiThread.start()
pushed = True
print "The button is pushed"
else:
if(GPIO.input(pushbutton) == True):
GPIO.output(led, GPIO.LOW)
myrpiThread.stop()
pushed = False
print "The button is not pushed"
except KeyboardInterrupt:
print "QUIT"
main()
Always when I run my script my leds arn't flashing each 0.05 sec. Sometimes it takes 2 seconds before it turns on and sometime it just doesn't flash.
I dont know what I am doing wrong? Can someone please help me to figure out what the problem is?
Is it possible that GPIO pins are not made to use in multithreading?
I followed this tutorial when I needed to use threaded callbacks with GPIO:
how to use interrupts with python on the raspberry pi and rpi gpio. It also has a good discussion in the comments about how to avoid using global variables to pass a value back from the threads.
It would be helpful to know exactly how you have your button wired, and what type of button you are using so that I could answer your problem more specifically.
I wrote the following example code assuming that you have the button wired from GPIO 2 to +3.3v
If you have it wired to ground use "pull_up_down=GPIO.PUD_DOWN" and "GPIO.FALLING"
It also assumes you have a momentary push button. When the button push is detected it flips a global boolean value. That value is checked in the main loop, and the blink(led) function is called if pushed = True.
import RPi.GPIO as GPIO
from time import sleep
GPIO.setmode(GPIO.BCM)
pushbutton = 2
led = 3
GPIO.setup(pushbutton, GPIO.IN, pull_up_down=GPIO.PUD_DOWN)
GPIO.setup(led, GPIO.OUT)
pushed = False
# this will run in another thread when the button is pushed
def button_callback(channel):
pushed = not pushed
GPIO.add_event_detect(pushbutton, GPIO.RISING, callback=button_callback)
while True:
if pushed:
blink(led)
def blink(led):
GPIO.output(led, True)
sleep(0.5)
GPIO.output(led, False)
I don't have a raspberry Pi in front of me right now to test this code, but I will check it later. You may have to modify this for your specific set up, but hopefully it gets you in the right direction.

RuntimeWarnings with GPIO.setup and GPIO.cleanup not work with KeyboardInterrupt

I have a problem with my code working with raspberry pi.
I just started with python so i need some help.
This is the code:
import RPi.GPIO as GPIO
import time
GPIO.setmode(GPIO.BCM)
led1=22
led2=17
GPIO.setup(led1, GPIO.OUT)
GPIO.setup(led2, GPIO.OUT)
def blink():
GPIO.output(led1, 1)
time.sleep(1)
GPIO.output(led1, 0)
GPIO.output(led2, 1)
time.sleep(1)
GPIO.output(led2, 0)
while(blink):
blink()
try:
main()
except KeyboardInterrupt:
GPIO.cleanup()
when I run this error appear in the console:
RuntimeWarning: This channel is already in use, continuing anyway. Use
GPIO.setwarnings(False) to disable warnings. GPIO.setup(led1,
GPIO.OUT) and:
RuntimeWarning: This channel is already in use, continuing anyway. Use
GPIO.setwarnings(False) to disable warnings. GPIO.setup(led2,
GPIO.OUT)
If I understand correctly the command GPIO.cleanup() should reset all pin of GPIO port and turn off the led.
but this in not happening in fact one of the led remain on.
How can change my code to resolve this issue?
Here is a little help, how to effectively separate your functions, and make them more general. Although this is a working Python script I provided, I didn't tested it on my raspi, but I think it will work -- anyway, let me know if there were any problems!
import RPi.GPIO as GPIO
import time
# Module level constants
LED1 = 22
LED2 = 17
# Sets up pins as outputs
def setup(*leds):
GPIO.cleanup()
GPIO.setmode(GPIO.BCM)
for led in leds:
GPIO.setup(led, GPIO.OUT)
GPIO.output(led, GPIO.LOW)
# Turn on and off the leds
def blink(*leds):
# Blink all leds passed
for led in leds:
GPIO.output(led, GPIO.HIGH)
time.sleep(1)
GPIO.output(led, GPIO.LOW)
if __name__ == '__main__':
# Setup leds
setup(LED1, LED2)
# Run blinking forever
try:
while True:
blink(LED1, LED2)
# Stop on Ctrl+C and clean up
except KeyboardInterrupt:
GPIO.cleanup()
A friendly recommendation:
There is a dedicated Raspberry Pi StackExchange site too: https://raspberrypi.stackexchange.com/
You don't seem to have included main in your question. However the problem may occur if the programs exits for some reason other than KeyboardInterrupt. It's better to free the resource in a finally block
try:
main()
except KeyboardInterrupt:
pass
finally:
GPIO.cleanup()
You are calling main() function but it's not declared (defined), you are using while(blink). So You need to delete the "main()" and put the "Try" before your main function which is the while(blink) loop. Don't forget the proper tabs there.

Categories

Resources