How run 2 script python in same time? - python

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

Related

Running a python script at at system boot as a daemon

I am attempting to create a daemon that will execute my script at boot.
using this code as my template Running a python script
my python script works interactively when a user is logged in.
def wait_for_network():
while os.system("ping -c 1 8.8.8.8") != 0:
time.sleep(1)
return
from getmac import get_mac_address
from datetime import datetime
import RPi.GPIO as GPIO
import os
import time
import random
import RPi.GPIO as GPIO
import requests
GPIO.setwarnings(False)
GPIO.setmode(GPIO.BCM)
GPIO.setup(5, GPIO.IN)
GPIO.setup(6, GPIO.IN)
GPIO.setup(23, GPIO.IN)
GPIO.setup(24, GPIO.IN)
GPIO.setup(14, GPIO.IN)
eth_mac = get_mac_address()
#print(eth_mac)
API_ENDPOINT = "https://xxxxxx.com/handlers/receiveStatus.ashx"
CUSTOMER_KEY = "1234567890"
# Define a callback function that will be called by the GPIO
# event system:
def onButton(channel):
if channel == 14:
dt_string = (datetime.now().strftime('%Y-%m-%dT%H:%M:%S.%f')[:-3])
data = {'ID':CUSTOMER_KEY,
'UUID':str(eth_mac),
'DT':dt_string,
'A':str(GPIO.input(6)),
'B':str(GPIO.input(24)),
'C':str(GPIO.input(23)),
'D':str(GPIO.input(5))
}
r = requests.post(url = API_ENDPOINT, data = data)
#print r.text
#print data
GPIO.add_event_detect(14, GPIO.RISING, callback=onButton, bouncetime=20)
#input()
My question is this - the #input() do i need it when running as a daemon?
With it, the script runs until the users presses ctrl-c to break out of.
When I comment it out, the script runs once then returns to the prompt.
The GPIO is making a thread and the main thread needs to wait for it. That was done with the input(). What you can do instead is to make a loop that sleeps instead in place of the input().
while True:
time.sleep(1)
That will hold the process from exiting until a ctrl c happens.

Python: Multiple infinite Loops on RaspberryPi

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

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

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