GPIO output initially on and GPIO.output - python

I'm new to python and am attempting to control solenoid valves using a relay, RPi, PIR sensor and python script. I found a script posted online I used as a base and modified it a bit to switch my relay. Everything seems to be working as expected overall, but I've noticed the following:
As soon as I run the script in terminal, the relay switches are on. After first trigger , they will stay off until the following trigger. Why are they intially on?
In my code I'm using GPIO.output(<variable>,False) to switch on and GPIO.output(<variable>,True) to turn off which seems backward. Shouldn't the False argument turn the switch off and True turn on?
Code below. Any pointers or insight would be appreciated! Thanks!
# Import required Python libraries
import RPi.GPIO as GPIO
import time
import random
# Use BCM GPIO references
# instead of physical pin numbers
GPIO.setmode(GPIO.BCM)
# Define GPIO to use on Pi
pir = 17
arm_one = 23
arm_two = 24
print "PIR Module Test (CTRL-C to exit)"
# Set pin as input
GPIO.setup(pir,GPIO.IN)
GPIO.setup(arm_one,GPIO.OUT)
GPIO.setup(arm_two,GPIO.OUT)
current_state = 0
previous_state = 0
def getRandomNum():
random_sleep=random.uniform(0,1)
return random_sleep;
try:
print "Waiting for PIR to settle ..."
# Loop until PIR output is 0
while GPIO.input(pir)==1:
current_state = 0
print " Ready"
# Loop until users quits with CTRL-C
while True:
# Read PIR state
current_state = GPIO.input(pir)
if current_state==1 and previous_state==0:
# PIR is triggered
print " Motion detected!"
for i in range(5):
GPIO.output(arm_one,False)
GPIO.output(arm_two,False)
time.sleep(1)
GPIO.output(arm_one,True)
time.sleep(getRandomNum())
GPIO.output(arm_two,True)
time.sleep(getRandomNum())
GPIO.output(arm_one,False)
time.sleep(getRandomNum())
GPIO.output(arm_one,True)
GPIO.output(arm_two,False)
time.sleep(getRandomNum())
GPIO.output(arm_two,True)
# Record previous state
previous_state=1
elif current_state==0 and previous_state==1:
# PIR has returned to ready state
print " Ready"
GPIO.output(arm_one,True)
GPIO.output(arm_two,True)
previous_state=0
# Wait for 10 milliseconds
time.sleep(0.01)
except KeyboardInterrupt:
print " Quit"
# Reset GPIO settings
GPIO.cleanup()

Related

Multiplexed RFID array not reading

I've got a 4x4 grid of RFID reader/writers. Borrowed circuit from here: RFGRID GitHub
The path for the circuit diagram is: docs/cctSchematics/rfgrid - Modular Array (schematic).svg
I've got the circuit working but my code for reading from it is broken. The readers aren't finding any of the tags I wave in front of them. I'm trying to loop through the multiplexed data and read it from a Raspberry Pi 3. Here's my python script:
import RPi.GPIO as GPIO
import mfrc522 as MFRC522
# Setup GPIO
GPIO.setmode(GPIO.BOARD)
GPIO.setwarnings(False)
GPIO.setup(11, GPIO.OUTPUT) # S0
GPIO.setup(12, GPIO.OUTPUT) # S1
GPIO.setup(15, GPIO.OUTPUT) # S2
GPIO.setup(16, GPIO.OUTPUT) # S3
# Setup address loop
board_state = []
s3_cycle = [0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1]
s2_cycle = [0,0,0,0,1,1,1,1,0,0,0,0,1,1,1,1]
s1_cycle = [0,0,1,1,0,0,1,1,0,0,1,1,0,0,1,1]
s0_cycle = [0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1]
try:
while (True):
board_state_temp = []
# Loop through addresses
for i in range(16):
GPIO.output(11, s0_cycle[i])
GPIO.output(12, s1_cycle[i])
GPIO.output(15, s2_cycle[i])
GPIO.output(16, s3_cycle[i])
# Read at current address
reader = MFRC522.MFRC522()
(status, TagType) = reader.MFRC522_Request(reader.PICC_REQIDL)
(status, uid) = reader.MFRC522_Anticoll()
# If tag is present, add data to temp state
if status == reader.MI_OK:
board_state_temp.append(uid)
reader.MFRC522_SelectTag(uid)
board_state.sort()
board_state_temp.sort()
# If temp state has changed since last loop, update state
if board_state != board_state_temp:
board_state = board_state_temp
# Send data to database/print the data
except KeyboardInterrupt:
GPIO.cleanup()
Currently I know that the 'status' variable is never in a state where it's conditional...
if status == reader.MI_OK:
is entered, hence the board_state is never updated.
Apologies if there's any typos in my code, I've had to retype it over from another machine so if you spot any errors like that, I don't think that would be the issue.
If there's nothing wrong with the code, it could be that my circuitry has errors.

GPIO control in while true:

Hey guys i get all the time the failure:
photo_booth.py:18: RuntimeWarning: This channel is already in use, continuing anyway. Use GPIO.setwarnings(False) to disable warnings.
GPIO.setup(RELAI, GPIO.OUT)
I also try to control al relays with the GPIO 18 but it is not working at all.
I tried it with some others but nothing changed. the relais i all the time on and it is not turning off with the command. what is my problem?
can you please tell me the problem ?
#!/usr/bin/python
import RPi.GPIO as GPIO, time, os, subprocess, signal
# GPIO setup
GPIO.setmode(GPIO.BCM)
SWITCH = 24
GPIO.setup(SWITCH, GPIO.IN)
RESET = 25
GPIO.setup(RESET, GPIO.IN)
RELAI = 19
GPIO.setup(RELAI, GPIO.OUT)
GPIO.output(RELAI, GPIO.LOW)
j = 0
k = 0
def entprellen(schalter):
entprellungs_puffer = 0
schalter_puffer = 0
for i in range(1, 11):
entprellungs_puffer = entprellungs_puffer +1
schalter_puffer = schalter_puffer + schalter
time.sleep(0.05)
if entprellungs_puffer == schalter_puffer:
print("entprellt")
return 1
else:
return 0
while True:
if(GPIO.input(SWITCH)):
j = entprellen(GPIO.input(SWITCH))
if (j):
GPIO.output(RELAI,GPIO.LOW)
time.sleep(0.5)
print("pose!")
print("SNAP")
gpout = subprocess.check_output("gphoto2 --capture-image-and-download --filename /home/pi/photobooth_images/photobooth%H%M%S.jpg", stderr=subprocess.STDOUT, shell=True)
print(gpout)
print("please wait while your photos print...")
subprocess.call("sudo /home/pi/scripts/photobooth/assemble_and_print", shell=True)
time.sleep(10)
print("ready for next round")
GPIO.output(RELAI,GPIO.HIGH)
GPIO.cleanup()
Thanks #stevieb and #johnny Mopp
Yes i understand the diffrence between the BCM ond BOARD mode. actually it was possible to run.
the Problem was : i connect it like here https://www.youtube.com/watch?v=TVR2SCMN8xY but it did not work. then i tried to change form 5 to 3.3V on the pi and it worked. the problem is the relay is not switching properly. i red on many sides very diffrent thinks about the relays. so i dont no really what to do. i bougth now two relays :
this is the first one :
https://www.amazon.de/gp/product/B01G1ENSTS/ref=ppx_yo_dt_b_asin_title_o03__o00_s00?ie=UTF8&psc=1
thats almost the same but diffrent brand:
https://www.amazon.de/gp/product/B00UFW1YNK/ref=ppx_yo_dt_b_asin_title_o01__o00_s00?ie=UTF8&psc=1
i hoped the second one is better because its the same one as shown in the tutorial. but no changes.
now i bought this one :
https://www.ebay.de/itm/252993630298
it has one pin to supply the coil directly with the 5V and the 3.3 is for switching.
do you think it will work or do you have other ideas ????
Thank you for your help!

Python time between x and y run code. And no code if time between xy

Im gonna try and explain to the best of my efforts.
Script im running is below.
I want to include something that will make the pir sensor not do anything between the hours of 24:00 and 05:00. But the button should work at those times regardless.
Also i want to be able to send different colors at certain times of the day.
So that if its between 8pm and 11 pm it will give this code to the lights: {"on":true,"bri":255,"sat":80,"hue":357}
There will be 4 colors in total. I have tried defining the command called with command(): and the colors but im at a standstill here.
Can anyone help me with this? I do really hope i made myself clear here, but fire away if anything is unclear.
import sys
sys.path.append("/home/pi/.local/lib/python2.7/site-packages")
from phue import Bridge
import RPi.GPIO as GPIO
import time
import datetime
print 'Waiting for network...'
time.sleep(30)
print 'The wait is over. It\'s showtime!'
GPIO.setwarnings(False)
GPIO.setmode(GPIO.BCM)
GPIO.setup(4, GPIO.IN) #Read output from PIR motion sensor
GPIO.setup(18, GPIO.IN, pull_up_down=GPIO.PUD_UP) #Read output from button.
b=Bridge('192.168.1.47')
try:
b.connect()
except ImportError:
print "Import error occurred!"
print "Connected to Hue bridge!"
lightson=b.get_light(2, "on")
if lightson: print "Lights are already on."
print 'Entering infinite loop...'
light_on_delay = 15 # time in min for light to stay on when button pressed
button_pressed = 0
while True:
# check for button press
input_state = GPIO.input(18)
if input_state == False:
print('Button Pressed')
end = (light_on_delay * 1) + time.time()
button_pressed = 1
command = {"on" : True, "bri" : 255, "sat" : 0, "hue" : 0}
b.set_group(2, command)
lightson=True
print('Lights are on for 15 minutes')
# check if button has been pressed if it has check to see if time is up
if button_pressed == 1:
if time.time() > end:
button_pressed = 0
else:
i=GPIO.input(4)
timestamp=datetime.datetime.now().time()
if (timestamp < offstarttime and timestamp > offendtime):
if i==0: #When output from motion sensor is LOW
print ('No movement detected - Turning lights off')
b.set_group(2, 'on', False)
lightson=False
print ('Lights are off')
time.sleep(0.1)
else: #When output from motion sensor is HIGH
print ('Movement detected - Turning lights on')
command = {"on" : True, "bri" : 255, "sat" : 0, "hue" : 0}
b.set_group(2, command)
lightson=True
print ('Lights are on.')
time.sleep(5)
# added delay to prevent program using 100% cpu time.
time.sleep(0.5)
You can add a time check using datetime module at the start of each iteration to conditionally set your command dictionary and run your PIR code if between certain hours. The button logic code should be run outside of the if blocks to make sure it always works
from datetime import datetime
while True:
now = datetime.now()
# Check to see if it is 5am or later
if now.hour >= 5:
# PIR sensor code here
print("PIR sensor should work now")
# Check to see if between 8pm and 11pm
if now.hour >= 20 and now.hour <= 23:
# Configure command dictionary for specific hours
command = {"on": True,"bri": 255,"sat": 80,"hue": 357}
else:
# Configure command dictionary for regular hours
command = {"on": False}
# Rest of your code including button logic

Raspberry pi button delay time to a relay

I am new to Raspberry pi and python and am having a bit of trouble with some code
I wish to push a button and have the gpio pin that corresponds to that button trigger a relay to turn on for a given amount of time then turn off. I have it working with the code below but by using the 'time.sleep(my-variable)' it holds up the raspberry pi for the duration of the time and i am unable to do anything else.
What i am after is the ability to push one button and get the relay to act for say 10 seconds and within those 10 seconds be able to press another button to fire another relay and do the same thing without tying up the pi
my code below first checks if input_state_LHS is equel to false, then clears the LCD display, writes text to the LCD on one line then on the next line it write the value of my variable(LHS_feedtime) then fires the relay with the time on the next line time.sleep, this is the bit i wish to be rid of but am unable to figure out the code to do it.
if input_state_LHS == False:
## calls the LCD_Clear function which has to be in the same folder as this file
mylcd.lcd_clear()
mylcd.lcd_display_string("LHS Feedtime",1,2)
mylcd.lcd_display_string(str(round(LHS_feedtime, 2)) + " sec" , 2,5)
GPIO.output(27, GPIO.input(12) )
time.sleep(LHS_feedtime)
mylcd.lcd_clear()
mylcd.lcd_display_string("Flatson Feeding", 1)
mylcd.lcd_display_string("Systems", 2,4)
GPIO.output(27, GPIO.input(12) )
menuitem = 0
thanks for the help
The functionality you need is in the Python standard library class threading.Timer. When you start a timer it launches another thread, which consists of a time delay followed by a call to a function that you specify. In contrast to time.sleep() which stops your main thread at that point, with a Timer your main thread will keep going.
Here is roughly what you want:
from threading import Timer
def turn_off_lcd():
mylcd.lcd_clear()
mylcd.lcd_display_string("Flatson Feeding", 1)
mylcd.lcd_display_string("Systems", 2,4)
GPIO.output(27, GPIO.input(12) )
if input_state_LHS == False:
## calls the LCD_Clear function which has to be in the same folder as this file
mylcd.lcd_clear()
mylcd.lcd_display_string("LHS Feedtime",1,2)
mylcd.lcd_display_string(str(round(LHS_feedtime, 2)) + " sec" , 2,5)
GPIO.output(27, GPIO.input(12) )
t = Timer(LHS_feedtime, turn_off_led)
t.start()
menuitem = 0
Here you go, this will constantly loop the code until the 10 seconds have passed. But it will constantly print "10 seconds havent passed" (you can remove this line.) As you will notice, this code does not use the time.sleep() and so will not hold the script up.
import time
#Get the initial system time
timebuttonpressed = time.strftime("%H%M%S")
elapsedtime = time.strftime("%H%M%S")
while True:
elapsedtime = time.strftime("%H%M%S")
if input_state_LHS == False:
#Get the new system time, but only set timesample2
timebuttonpressed = time.strftime("%H%M%S")
## calls the LCD_Clear function which has to be in the same folder as this file
mylcd.lcd_clear()
mylcd.lcd_display_string("LHS Feedtime",1,2)
mylcd.lcd_display_string(str(round(LHS_feedtime, 2)) + " sec" , 2,5)
GPIO.output(27, GPIO.input(12) )
#Check if 10 seconds have passed
if((int(elapsedtime) - int(timebuttonpressed)) == 10):
timebuttonpressed = time.strftime("%H%M%S")
mylcd.lcd_clear()
mylcd.lcd_display_string("Flatson Feeding", 1)
mylcd.lcd_display_string("Systems", 2,4)
GPIO.output(27, GPIO.input(12) )
menuitem = 0
print("10 seconds havent passed...")

Pulse width reader printing same value every time

I'm connecting my raspberry pi to a 2.4ghz rc reciever, and I am trying to use python to interpret the pulse width signal. I am using an input pin to read the time while there is no input, then the time when there is an input, then subtracting the two.
import RPi.GPIO as GPIO
import time
GPIO.setmode(GPIO.BOARD)
GPIO.setup(13,GPIO.IN)
GPIO.setup(15,GPIO.OUT)
GPIO.output(15,GPIO.HIGH)
start = time.time()
stop = time.time()
x = 0
y = 0
while(x == 0):
if(GPIO.input(13) == 0):
start = time.time()
x = 1
while(y == 0):
if(GPIO.input(13) == 1):
stop = time.time()
y = 1
Width = stop-start
print(Width)
GPIO.cleanup()
The issue I am having is that no matter how long I make the pulse width (by manually connecting and disconnecting pin 13 and 15), it prints ~.006. It also will not print until I disconnect the pins from each other, although I haven't been able to figure out why.
Pin 13 might be floating. I'd suggest you replace ...
GPIO.setup(13,GPIO.IN)
... with ...
GPIO.setup(13,GPIO.IN, pull_up_down=GPIO.PUD_DOWN)
Here's an example of how to do this with interrupts:
#!/usr/bin/env python3
# example of reading PWM with GPIO interrupts
# Warning: Linux isn't built for real-time applications.
# A Raspberry Pi with Jessie will not produce reliable results
# That said...
import RPi.GPIO as GPIO
import time
GPIOpin_IN = 13
GPIOpin3v3 = 1 # fixed at 3v3 volts
myStart = None
myStop = None
GPIO.setmode(GPIO.BOARD)
GPIO.setup(GPIOpin_IN, GPIO.IN, pull_up_down=GPIO.PUD_DOWN)
def pinGoesUp(gpioIdentity):
myStart = time.time()
def pinGoesDown(gpioIdentity):
myStop = time.time()
GPIO.add_event_detect(GPIOpin_IN, GPIO.RISING, callback=pinGoesUp)
GPIO.add_event_detect(GPIOpin_IN, GPIO.FALLING, callback=pinGoesDown)
while True:
if myStop < myStart:
Width = stop-start
print(Width)`
documentation on gpio input.
On a side note, you're going to have difficulty getting reliable readings. Jessie is not intended to provide real-time interaction, and frequently takes small vacations to do other tasks.

Categories