GPIO control in while true: - python

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!

Related

setting rpi-gpio pin on high after running a python script

I'm building a photogrametry setup with raspberry pi and stepper motor.
The python script runs fine, but i got a problem with setting a pin to high after the script ran through.
The stepper driver has an enable input, which diasables the motor with high input, so i set the pin (gpio26) on high on boot with pigpio, this works fine. While running the python script, the pin is set on low, so the stepper can proceed, after proceeding i want to set the pin on high again.
i tried following commands:
os.system('pigs w 26 1') and
subprocess.call("pigs w 26 1", shell=True)
for a moment they work, but after exiting the script the pin is set on low again.
It's like the commands are resetted after the script stops.
Where is my fault?
Thank you
Edit:
Here is the gpio related code:
import os, sys
import subprocess
from time import sleep
from gpiozero import DigitalOutputDevice as stepper
def InitGPIO():
try:
global step_pul #pulse
global step_en #enable
step_pul=stepper(21)
step_en=stepper(26)
print ("GPIO initialisiert.")
except:
print ("Fehler bei der GPIO-Initialisierung.")
def motor_step():
SPR=40000 #steps per rotation
step_count = SPR
delay = .000025
for x in range(step_count):
step_pul.on()
sleep(delay)
step_pul.off()
sleep(delay)
InitGPIO()
step_en.off()
for i in range(1):
#camTrigger(1)
motor_step()
#os.system('sudo -u root -S pigs w 26 1')
subprocess.call("pigs w 26 1", shell=True)
When i type pigs w 26 1 in the shell, it works...
To make my comment an answer:
Gpiozero only resets the pins it touches, so if you don't initialize or touch pin 26 with gpiozero (i.e. replace step_en.off() with pigs w 26 0 and don't even initialize step_en), it shouldn't also reset the pin:
import os
import time
import gpiozero
step_pul = gpiozero.DigitalOutputDevice(21)
def motor_step():
SPR = 40000 # steps per rotation
step_count = SPR
delay = .000025
for x in range(step_count):
step_pul.on()
time.sleep(delay)
step_pul.off()
time.sleep(delay)
# Enable motor
os.system("pigs w 26 0")
for i in range(1):
# camTrigger(1)
motor_step()
# Disable motor
os.system("pigs w 26 1")

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

GPIO output initially on and GPIO.output

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()

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.

Unexpected results in Raspberry Pi email notifier

Just bought a raspberry pi b+ and decided to tackle some "simple" projects. Currently I'm working trying to sync my gmail account to a LED notifier.
If I have an email, the green LED lights up. If I don't have an email, the red one lights up. The issue is this... as it currently functions, when I have no emails, the green LED lights up, however, when I do have at least 1 email, neither LED lights up. I know everything on the hardware side is working because I've tested different combinations.
I've pasted the code from the tutorial below and from what I can tell it's a very simple conditional with some extra stuff so it can talk to my raspberry pi.
Just seems odd that the if-statement always returns true.
import RPi.GPIO as GPIO, feedparser, time
DEBUG = 1
USERNAME = "my-username"
PASSWORD = "my-password"
NEWMAIL_OFFSET = 0 # empty inbox
MAIL_CHECK_FREQ = 60 # check mail every 60 seconds
GPIO.setmode(GPIO.BCM)
GREEN_LED = 18
RED_LED = 23
GPIO.setup(GREEN_LED, GPIO.OUT)
GPIO.setup(RED_LED, GPIO.OUT)
while True:
newmails = int(feedparser.parse("https://" + USERNAME + ":" + PASSWORD +"#mail.google.com/gmail/feed/atom")["feed"]["fullcount"])
if DEBUG:
print "You have", newmails, "new emails!"
if newmails > NEWMAIL_OFFSET:
GPIO.output(GREEN_LED, True)
GPIO.output(RED_LED, False)
else:
GPIO.output(GREEN_LED, False)
GPIO.output(RED_LED, True)
time.sleep(MAIL_CHECK_FREQ)
!
Here's my setup...
By the look of your hardware picture, it may be that your resistors might be touching there. Also, the lead going to the green LED is not down on an empty row. Currently it would be interacting with pin 16 and your voltage when high is draining to that... This article may help
https://learn.adafruit.com/raspberry-pi-e-mail-notifier-using-leds/wire-leds
First of all just to make things clear: The code does not notify you about new messages as long as there is at least one unread message in your inbox.
The issue with the light is indeed hardware related because I just did the same setup at home and it worked fine. I made some minor changes to the code though:
import RPi.GPIO as GPIO, feedparser, time, sys
USERNAME = "my-username"
PASSWORD = "my-password"
NEWMAIL_OFFSET = 0 # empty inbox
MAIL_CHECK_FREQ = 60 # check mail every 60 seconds
GPIO.setmode(GPIO.BCM)
GREEN_LED = 18
RED_LED = 23
GPIO.setup(GREEN_LED, GPIO.OUT)
GPIO.setup(RED_LED, GPIO.OUT)
while True:
try:
newmails = int(feedparser.parse("https://" + USERNAME + ":" + PASSWORD +"#mail.google.com/gmail/feed/atom")["feed"]["fullcount"])
print "You have ", newmails, " unread emails!"
if newmails > NEWMAIL_OFFSET:
GPIO.output(GREEN_LED, True)
GPIO.output(RED_LED, False)
else:
GPIO.output(GREEN_LED, False)
GPIO.output(RED_LED, True)
time.sleep(MAIL_CHECK_FREQ)
except KeyboardInterrupt:
#Ctrl + C
#Ensure you are cleaning up the GPIO setup or it might not work correctly after the first run
GPIO.cleanup()
break
except:
#Here you can capture possible unknown issues with the code
print("There following error happened: " + str(sys.exc_info()[1]))
finally:
pass

Categories