Python: Multiple infinite Loops on RaspberryPi - python

I wrote a function to let a LED blink with variable parameters.
The code looks like this:
#!/usr/bin/python
import RPi.GPIO as GPIO
import time
from threading import Thread
GPIO.setmode(GPIO.BOARD)
def blink(port, hz):
""" Funktion zum Blinken von LEDs auf unterschiedlichen GPIO Ports und unterschiedlicher Hz angabe"""
GPIO.setup(port, GPIO.OUT)
while True:
GPIO.output(port, GPIO.HIGH)
time.sleep(0.5/hz)
GPIO.output(port, GPIO.LOW)
time.sleep(0.5/hz)
blink(16, 5)
As far the code works well.
Now I want to call the blink() function a second time with different parameters:
...
blink(16, 5)
blink(15, 10)
But with the first function calls a infinite Loop , the second call of blink() does not work. Is there a way to start a second infinite loop?

I see you've imported Thread, so something like this might do the trick(with a grain of salt here, I don't have my rpi around so I can't test it):
#!/usr/bin/python
import RPi.GPIO as GPIO
import time
from threading import Thread
GPIO.setmode(GPIO.BOARD)
def blink(port, hz):
""" Function to let LEDs blink with different parameters"""
GPIO.setup(port, GPIO.OUT)
while True:
GPIO.output(port, GPIO.HIGH)
time.sleep(0.5/hz)
GPIO.output(port, GPIO.LOW)
time.sleep(0.5/hz)
Thread(target=blink, args=(16, 5)).start()
Thread(target=blink, args=(15, 10)).start()

Related

How run 2 script python in same time?

I explain my need : i wish to run ffmpeg with a python script (that's ok) but i need to know of the script is launched with a blink led connected on the GPIO of my RPI, But i dont know why i can launch my script and start le blink (or just a led on)
Can u help me ? show me the light, please ;)
import RPi.GPIO as GPIO
import time
import os
GPIO.setwarnings(False)
GPIO.setmode(GPIO.BCM)
GPIO.setup(4, GPIO.OUT)
GPIO.setup(22,GPIO.IN)
# fonction qui fait clignoter la led
def blink(led):
GPIO.output(led,True)
time.sleep(0.5)
GPIO.output(led,False)
time.sleep(1)
# input of the switch will change the state of the LED
while 1:
if ( GPIO.input(22) == True ):
print "start broadcast"
os.system("sudo /home/pi/videopi/webcam.sh")
blink(4) << not ok like this !
time.sleep(1)
Assuming your os script runs successfully (I would recommend subprocess instead), what you're describing is called concurrency -- https://realpython.com/python-concurrency/
I would structure your code like this:
import RPi.GPIO as GPIO
import time
import os
from threading import Thread
GPIO.setwarnings(False)
GPIO.setmode(GPIO.BCM)
GPIO.setup(4, GPIO.OUT)
GPIO.setup(22,GPIO.IN)
# fonction qui fait clignoter la led
def blink(led):
while True:
GPIO.output(led,True)
time.sleep(0.5)
GPIO.output(led,False)
time.sleep(1)
# input of the switch will change the state of the LED
while True:
if ( GPIO.input(22) == True ):
blinking = Thread(target=blink, args=(4,)) # create thread
blinking.start() # start blinking
print("start broadcast")
os.system("sudo /home/pi/videopi/webcam.sh")
blinking.join() # stops blinking once webcam.sh completed
print("broadcast complete")

how to run a part of a python program when it is a certain time

I would like to run my a function within my python program when the time is 7am. Almost like a when function when time == time:
I don't want to use cron because I want this to be internal function not executing the whole script
Here is my python script I have created:
#sprinkler.py file for sprinkler system
#this is the main file for the sprinklerOS
#functions to import for our test_run.py file
import RPi.GPIO as GPIO
import time
import argparse
import sys
import datetime
#how many zones the user/YOU have set up
zone_count = 10
#gpio pins on the raspberry pi for sprinkler system
pin = [12,7,16,11,18,13,22,15,32,29]
#set mode to board meaning the pin number on pi (1-40) instead of gpio number
GPIO.setmode(GPIO.BOARD)
GPIO.setwarnings(False)
#setting up all of the lights or relays as outputs(in a while loop)
for a in range(10):
GPIO.setup(pin[a],GPIO.OUT)
GPIO.output(pin[a], GPIO.LOW)
def run_sprinklers():
for b in range(zone_count):
run_time = 5
GPIO.output(pin[b], GPIO.HIGH)
time.sleep(run_time)
GPIO.output(pin[b], GPIO.LOW)
time.sleep(1)
I want to run_sprinklers() when the time is 7am
Thank you in advanced
As others have mentioned in the comments, cron is probably the best solution. However if this is a persistent process and you cannot rely on a tool like cron the schedule module, https://github.com/dbader/schedule, might be of interest to you.
import RPi.GPIO as GPIO
import time
import argparse
import sys
import datetime
import schedule
#how many zones the user/YOU have set up
zone_count = 10
#gpio pins on the raspberry pi for sprinkler system
pin = [12,7,16,11,18,13,22,15,32,29]
#set mode to board meaning the pin number on pi (1-40) instead of gpio number
GPIO.setmode(GPIO.BOARD)
GPIO.setwarnings(False)
#setting up all of the lights or relays as outputs(in a while loop)
for a in range(10):
GPIO.setup(pin[a],GPIO.OUT)
GPIO.output(pin[a], GPIO.LOW)
def run_sprinklers():
for b in range(zone_count):
run_time = 5
GPIO.output(pin[b], GPIO.HIGH)
time.sleep(run_time)
GPIO.output(pin[b], GPIO.LOW)
time.sleep(1)
schedule.every().day.at("7:00").do(run_sprinklers)
while True:
schedule.run_pending()
time.sleep(1)

Move DC motors with differents speed

I'm doing a project which I got to move two motors and they have differents movements. There are the codes:
import RPi.GPIO as GPIO ## Import GPIO library
import time ## Import 'time' library. Allows us to use 'sleep'
import sys
GPIO.setmode(GPIO.BOARD) ## Use board pin numbering
GPIO.setup(19, GPIO.OUT) ## Setup GPIO Pin 11(motor b enable) to OUT
GPIO.setup(16, GPIO.OUT) ## Setup GPIO Pin 11(motor a enable) to OUT
GPIO.setup(22, GPIO.OUT) ## Setup GPIO Pin 11(motor a control) to OUT
GPIO.setup(18, GPIO.OUT) ## Setup GPIO Pin 11(motor a control) to OUT
GPIO.setup(23, GPIO.OUT) ## Setup GPIO Pin 11(motor b control) to OUT
GPIO.setup(21, GPIO.OUT) ## Setup GPIO Pin 11(motor b control) to OUT
GPIO.output(16, False) ## disable motor a
GPIO.output(19, True) ## enable motor b
p=GPIO.PWM(19,50) ## frequency 50
p.start(1)
try:
while True:
GPIO.output(22, False) ## dont run motor a
GPIO.output(18, False) ## dont run motor a
GPIO.output(23, True) ## run motor b
GPIO.output(21, False) ## run motor b
p.ChangeDutyCycle(35) ## duty cycle 10%
except KeyboardInterrupt:
pass
p.stop()
GPIO.cleanup()
sys.exit()
Code #2
import RPi.GPIO as GPIO
from time import sleep
import sys
GPIO.setmode(GPIO.BOARD)
Motor1A = 22
Motor1B = 18
Motor1E = 16
Motor2A = 23
Motor2B = 21
Motor2E = 19
GPIO.setup(Motor1A,GPIO.OUT)
GPIO.setup(Motor1B,GPIO.OUT)
GPIO.setup(Motor1E,GPIO.OUT)
GPIO.setup(Motor2A,GPIO.OUT)
GPIO.setup(Motor2B,GPIO.OUT)
GPIO.setup(Motor2E,GPIO.OUT)
print "Going forwards"
GPIO.output(Motor1A,GPIO.HIGH)
GPIO.output(Motor1B,GPIO.LOW)
GPIO.output(Motor1E,GPIO.HIGH)
GPIO.output(Motor2A,GPIO.HIGH)
GPIO.output(Motor2B,GPIO.LOW)
GPIO.output(Motor2E,GPIO.HIGH)
sleep(2)
print "Now stop"
GPIO.output(Motor1E,GPIO.LOW)
GPIO.output(Motor2E,GPIO.LOW)
GPIO.cleanup()
sys.exit()
I want to mix both codes in one. I mean, convert these two codes in one which has two differents speed.
Or If someone knows another code I'll be very thankful
How do I do that?
Seriously, use gpiozero, it's a lot more fun and turns your code into:
from gpiozero import Motor
from time import sleep
motorA = Motor(22, 18) # your gpio pins go here
motorB = Motor(23, 21)
motorA.forward(0.5) # half speed
motorB.forward(0.5)
sleep(2) # wait 2 seconds before stopping the motors
motorA.stop()
motorB.stop()
Then, you can go a step further and use the Robot class instead (Documentation here), and make everything even easier:
from gpiozero import Robot
from time import sleep
robot = Robot(left=(22, 18), right=(23, 21))
robot.forward(1) # full speed
sleep(2)
robot.stop()
The robot class also has some more functions, for example:
robot.left()
robot.right()
Most likely, you'll have to install the library first if you haven't used it yet. Type the following on the terminal in order to do so.
pip install gpiozero

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.

Raspberry Pi simple LED and GPIO with Python not working

I just bought a Raspberry Pi and I was playing around with an LED, trying to learn Python. So my setup is as follows: my led is is connected to the 7th PIN of my GPIO and to ground. I made the following code:
import RPi.GPIO as GPIO
import time
GPIO.setmode(GPIO.BOARD)
GPIO.setup(7, GPIO.OUT)
GPIO.output(7, True)
time.sleep(10)
GPIO.output(7, False)
time.sleep(5)
GPIO.output(7, True)
When I ran this code, the LED blinks once for 10 seconds, turns off and nevers turns back on. What can be wrong?
Try this:
import RPi.GPIO as GPIO
import time
GPIO.setmode(GPIO.BOARD)
GPIO.setup(7, GPIO.OUT)
while True:
GPIO.output(7, True)
time.sleep(10)
GPIO.output(7, False)
time.sleep(5)
It should loop the on/off sequence, causing the light to turn on for 10s, then turn off for 5s, and repeat.

Categories

Resources