Python Threading: Using 2 Light Dependant Resistors (LDR) - python

I am using a simple code from PiMyLife tutorial to read from a Light Dependant Resistor using a capacitor. This works great..
I then added a 2nd LDR and capacitor, added it to pin 31 and then duplicated the code (the rc_time function and the fuction call) to add an additional Light Dependant Resistor but for some reason the second function call never happens.
#!/usr/local/bin/python
import RPi.GPIO as GPIO
import time
GPIO.setmode(GPIO.BOARD)
#define the pin that goes to the circuit
pin_ldr_one = 29
pin_ldr_two = 31
def rc_time_one (pin_ldr_one):
count_one = 0
#Output on the pin for
GPIO.setup(pin_ldr_one, GPIO.OUT)
GPIO.output(pin_ldr_one, GPIO.LOW)
time.sleep(0.1)
#Change the pin back to input
GPIO.setup(pin_ldr_one, GPIO.IN)
#Count until the pin goes high
while (GPIO.input(pin_ldr_one) == GPIO.LOW):
count_one += 1
return count_one
def rc_time_two (pin_ldr_two):
count_two = 0
#Output on the pin for
GPIO.setup(pin_ldr_two, GPIO.OUT)
GPIO.output(pin_ldr_two, GPIO.LOW)
time.sleep(0.1)
#Change the pin back to input
GPIO.setup(pin_ldr_two, GPIO.IN)
#Count until the pin goes high
while (GPIO.input(pin_ldr_two) == GPIO.LOW):
count_two += 1
return count_two
#Catch when script is interrupted, cleanup correctly
try:
# Main loop
while True:
print("LDR 1: ",rc_time_one(pin_ldr_one))
print("LDR 2: ",rc_time_two(pin_ldr_two))
except KeyboardInterrupt:
pass
finally:
GPIO.cleanup()
So I thought I would try threading instead thinking that the 2 function calls were having issues.
So this is the threading code I came up with however this too fails to run the second (in this cask 2nd thread). Any ideas where I am going wrong. Thanks for all your help
#!/usr/local/bin/python
import RPi.GPIO as GPIO
import time
from time import sleep, perf_counter
from threading import Thread
GPIO.setmode(GPIO.BOARD)
#define the pin that goes to the circuit
pin_ldr_one = 29
pin_ldr_two = 31
def rc_time_one (pin_ldr_one = 29):
count_one = 0
#Output on the pin for
GPIO.setup(pin_ldr_one, GPIO.OUT)
GPIO.output(pin_ldr_one, GPIO.LOW)
time.sleep(0.1)
#Change the pin back to input
GPIO.setup(pin_ldr_one, GPIO.IN)
#Count until the pin goes high
while (GPIO.input(pin_ldr_one) == GPIO.LOW):
count_one += 1
print("LDR 1: ",count_one)
return count_one
def rc_time_two (pin_ldr_two = 31):
count_two = 0
#Output on the pin for
GPIO.setup(pin_ldr_two, GPIO.OUT)
GPIO.output(pin_ldr_two, GPIO.LOW)
time.sleep(0.1)
#Change the pin back to input
GPIO.setup(pin_ldr_two, GPIO.IN)
#Count until the pin goes high
while (GPIO.input(pin_ldr_two) == GPIO.LOW):
count_two += 1
print("LDR 2: ",count_two)
return count_two
#Catch when script is interrupted, cleanup correctly
try:
# Main loop
while True:
# create two new threads
t1 = Thread(target=rc_time_one)
t2 = Thread(target=rc_time_two)
# start the threads
t1.start()
t2.start()
t1.join()
t2.join()
#print("LDR 1: ",rc_time_one(pin_ldr_one))
#print("LDR 2: ",rc_time_two(pin_ldr_two))
except KeyboardInterrupt:
pass
finally:
GPIO.cleanup()
Peter

Related

Combining two python codes for raspberry pi with a servo and ldr sensor

I have Python code running on my raspberry pi 2b and a light sensor, which measures the amount of time it takes for the capacitor of the light sensor to charge and send the pin high:
import RPi.GPIO as GPIO
import time
GPIO.setmode(GPIO.BOARD)
pin_to_circuit = 7
def rc_time (pin_to_circuit):
count = 0
#Output on the pin for
GPIO.setup(pin_to_circuit, GPIO.OUT)
GPIO.output(pin_to_circuit, GPIO.LOW)
time.sleep(0.1)
#Change the pin back to input
GPIO.setup(pin_to_circuit, GPIO.IN)
#Count until the pin goes high
while (GPIO.input(pin_to_circuit) == GPIO.LOW):
count += 1
if count > 1000000:
return True
else:
return count
#Catch when script is interrupted, cleanup correctly
try:
# Main loop
while True:
print rc_time(pin_to_circuit)
except KeyboardInterrupt:
pass
finally:
GPIO.cleanup()
I want when the count goes higher than 1000000, a MG90S, that I have also connected to the pi and a 4AA battery pack, moves about 90 degrees.
The code I was trying to integrate to move the servo:
import RPi.GPIO as GPIO
import time
GPIO.setmode(GPIO.BOARD)
GPIO.setup(12, GPIO.OUT)
p.ChangeDutyCycle(7.5) # turn towards 90 degree
time.sleep(1) # sleep 1 second
p.stop()
GPIO.cleanup()
I want to combine these two Python codes. I tried for a bit, but I have almost no Python experience.
The code is now:
import RPi.GPIO as GPIO
import time
GPIO.setmode(GPIO.BOARD)
pin_to_circuit = 7
def move_90_degrees():
GPIO.setmode(GPIO.BOARD)
GPIO.setup(12, GPIO.OUT)
p = GPIO.PWM(12, 50)
p.start(7.5)
p.ChangeDutyCycle(7.5) # turn towards 90 degree
time.sleep(1) # sleep 1 second
p.stop()
def rc_time (pin_to_circuit):
count = 0
#Output on the pin for
GPIO.setup(pin_to_circuit, GPIO.OUT)
GPIO.output(pin_to_circuit, GPIO.LOW)
time.sleep(0.1)
#Change the pin back to input
GPIO.setup(pin_to_circuit, GPIO.IN)
#Count until the pin goes high
while (GPIO.input(pin_to_circuit) == GPIO.LOW):
count += 1
if count > 1000000:
return True
move_90_degrees()
else:
return count
#Catch when script is interrupted, cleanup correctly
try:
# Main loop
while True:
print rc_time(pin_to_circuit)
except KeyboardInterrupt:
pass
finally:
GPIO.cleanup()
The code does print True when the count exceeds 1000000, but the servo still doesn't move. The servo code on its own does however work correctly. (I forgot a bit of the servo code, that's why p wasn't defined, sorry.)
You could just integrate the code block you are using to move the MG90S into a function, insert it before or below your def rc_time (pin_to_circuit): (but first you have to define p inside, its not really clear what p refers to):
New Function from second code block:
def move_90_degrees():
p = '???'
GPIO.setup(12, GPIO.OUT)
p.ChangeDutyCycle(7.5) # turn towards 90 degree
time.sleep(1) # sleep 1 second
p.stop()
After defining this function, call it inside your first block like:
if count > 1000000:
move_90_degrees()
return True
else:
return count
That should work.
I've made a mistake in the code. I changed the order of the function call inside of the
if count > 1000000:
return True
move_90_degrees()
else:
return count
block to :
if count > 1000000:
move_90_degrees()
return True
else:
return count
otherwise, the code returns before the function call is executed. Is it working now?

Python Multiprocessing Stops after a while

So basically we're using raspberry pi for a project and a part of it includes the usage of ultrasonic sensors. We have three, and we've been able to get readings from all of them (I actually came from multi-threading but decided to move to multiprocessing). Here is my code:
#Libraries
from multiprocessing import Process, Lock
import RPi.GPIO as GPIO
import time
#GPIO Mode (BOARD / BCM)
GPIO.setmode(GPIO.BCM)
GPIO.setwarnings(False)
#set GPIO Pins
GPIO_TRIGGER1 = 23
GPIO_ECHO1 = 24
GPIO_TRIGGER2 = 27
GPIO_ECHO2 = 22
GPIO_TRIGGER3 = 25
GPIO_ECHO3 = 17
#set GPIO direction (IN / OUT)
GPIO.setup(GPIO_TRIGGER1, GPIO.OUT)
GPIO.setup(GPIO_ECHO1, GPIO.IN)
GPIO.setup(GPIO_TRIGGER2, GPIO.OUT)
GPIO.setup(GPIO_ECHO2, GPIO.IN)
GPIO.setup(GPIO_TRIGGER3, GPIO.OUT)
GPIO.setup(GPIO_ECHO3, GPIO.IN)
def sense_distance(lock, processName):
#lock.acquire()
gpio_echo_var = ''
gpio_trigger_var = ''
if processName == "Sensor-1":
gpio_echo_var = GPIO_ECHO1
gpio_trigger_var = GPIO_TRIGGER1
elif processName == "Sensor-2":
gpio_echo_var = GPIO_ECHO2
gpio_trigger_var = GPIO_TRIGGER2
elif processName == "Sensor-3":
gpio_echo_var = GPIO_ECHO3
gpio_trigger_var = GPIO_TRIGGER3
print "%s process created." % (processName)
try:
while True:
# set Trigger to HIGH
GPIO.output(gpio_trigger_var, True)
# set Trigger after 0.01ms to LOW
time.sleep(0.00001)
GPIO.output(gpio_trigger_var, False)
StartTime = time.time()
StopTime = time.time()
# save StartTime
while GPIO.input(gpio_echo_var) == 0:
StartTime = time.time()
# save time of arrival
while GPIO.input(gpio_echo_var) == 1:
StopTime = time.time()
# time difference between start and arrival
TimeElapsed = StopTime - StartTime
# multiply with the sonic speed (34300 cm/s)
# and divide by 2, because there and back
distance = (TimeElapsed * 34300) / 2
if distance <= 10:
print "%s has read less than 10 cm." % (processName)
else:
pass
# Reset by pressing CTRL + C
except KeyboardInterrupt:
print("Measurement stopped by User")
GPIO.cleanup()
#lock.release()
if __name__ == '__main__':
lock = Lock()
Process(target=sense_distance, args=(lock, "Sensor-1")).start()
Process(target=sense_distance, args=(lock, "Sensor-2")).start()
Process(target=sense_distance, args=(lock, "Sensor-3")).start()
It successfully reads the input and prints out the text when input goes smaller than 10 cm. However, after some time, they stop. I have run out of ideas and have searched all over only to come up short. Any sort of help will be appreciated.

QTR-8RC Reflectance Sensor Array not returning data

I purchased a QTR-8RC Reflectance Sensor Array and now trying to configure it with Python. I am trying to determine the rate of decay of the voltage that is being read by my receivers (phototransistors) so that I know when a line is being detected. I don't know why my Python code isn't returning anything. Not even a warning statement. Additional information includes that by default the GPIO is an output and the LEDs are ON. Any help is appreciated!
import RPi.GPIO as GPIO
from time import sleep
def Read():
GPIO.setmode(GPIO.BOARD)
GPIO.setup(5, GPIO.OUT)
sleep(0.01)
count = 0
GPIO.setup(5, GPIO.IN)
while GPIO.input(5) == True:
count = count + 1
return count
while True:
Read()
print(Read())
sleep(1)
I don't have any knowledge about QTR-8RC Reflectance Sensor Array.
But looking at your python code, the problem might be with
while GPIO.input(5) == True
If the value is always true then the line with the return statement is never reached.
You could use print statement after while block to check that. Something like
while GPIO.input(5) == True:
count = count + 1
print "while loop has ended"
return count
Instead of running the program continuously run it for some time and check the outputs.
And may be you need to increase the sleep time to see the output practically.
import RPi.GPIO as GPIO
from time import sleep
def Read():
GPIO.setmode(GPIO.BOARD)
GPIO.setup(5, GPIO.OUT)
sleep(0.01)
count = 0
GPIO.setup(5, GPIO.IN)
while GPIO.input(5) == True:
count = count + 1
print "count :", count
return count
for _ in range(100):
print(Read())
sleep(2)

UnboundLocalError: local variable 'signaloff' referenced before assignment

I'm trying to read ultrasonic range when a button is pressed on a raspberry pi.
I'm getting a random error that happens about 1 in three times. Have also tried running 'print reading(0)' three times with a wait of 2 seconds in between each attempt and sometimes it works and sometimes it fails on the first try.
The error is:
Traceback (most recent call last):
File "test.py", line 37, in <module>
print reading(0)
File "test.py", line 30, in reading
timepassed = signalon - signaloff
UnboundLocalError: local variable 'signaloff' referenced before assignment
The code is:
import RPi.GPIO as GPIO
import time
GPIO.setwarnings(False)
GPIO.setmode(GPIO.BCM)
# btn on pin 18
GPIO.setup(18, GPIO.IN, pull_up_down=GPIO.PUD_UP)
# LED on pin 24
GPIO.setup(24, GPIO.OUT)
# GPIO output = the pin that's connected to "Trig" on the sensor
# GPIO input = the pin that's connected to "Echo" on the sensor
GPIO.setup(17,GPIO.OUT)
GPIO.setup(27,GPIO.IN)
def reading(sensor):
if sensor == 0:
GPIO.output(17, GPIO.LOW)
time.sleep(0.3)
GPIO.output(17, True)
time.sleep(0.00001)
GPIO.output(17, False)
while GPIO.input(27) == 0:
signaloff = time.time()
while GPIO.input(27) == 1:
signalon = time.time()
timepassed = signalon - signaloff
distance = timepassed * 17000
return distance
else:
print "Incorrect usonic() function varible."
while True:
input_state = GPIO.input(18)
if input_state == False:
print('Button Pressed')
GPIO.output(24, True)
print reading(0)
time.sleep(2)
GPIO.output(24, False)
If GPIO.input(27) returns 0 the first time you call it, the while loop will never be entered, and signaloff will never be set. The same is actually true for the loop that set signalon, although that issue might be rarer.

RaspberryPi webiopi script error doesn't work

I want to experiment with the RaspberryPi, but the .py code doesn't work. It gives me a lot of errors.
a space error
indentation error: expected an indented block " global VELUX_STATE, AUTO_mode "
I only copied the code from the official forum, that works for other people.
Link:
http://egrasland.blogspot.fr/2014/01/control-your-velux-roller-shutter-with.html
I copy the code and paste in "sudo nano script.py"
What do I do wrong ?
Furthermore, the code from the official webiopi from RaspberryPi doesn't work either for me. Debug gives error, and the program doesn't start.
Link: https://code.google.com/p/webiopi/wiki/Tutorial_Basis
Thanks for the answers.
The code I used is:
Python server script :
import webiopi import datetime
GPIO = webiopi.GPIO
VELUX_UP = 17 # GPIO pin using BCM numbering VELUX_DOWN = 18 # GPIO pin using BCM numbering VELUX_STOP = 27 # GPIO pin using BCM numbering
VELUX_STATE = 0 # DOWN AUTO_MODE = 1
HOUR_UP = 9 # Turn Velux UP at HOUR_DOWN = 19 # Turn Velux Down at
# setup function is automatically called at WebIOPi startup
def setup(): global VELUX_STATE, AUTO_MODE
# set the GPIO used for VELUX command to output
GPIO.setFunction(VELUX_UP, GPIO.OUT)
GPIO.setFunction(VELUX_DOWN,GPIO.OUT)
# STOP function not used at this time
GPIO.setFunction(VELUX_STOP,GPIO.OUT)
GPIO.digitalWrite(VELUX_STOP, GPIO.LOW)
# retrieve current datetime now = datetime.datetime.now()
if (AUTO_MODE==1):
# test time
if ((now.hour >= HOUR_UP) and (now.hour < HOUR_DOWN)):
GPIO.digitalWrite(VELUX_UP, GPIO.HIGH)
webiopi.sleep(0.2)
GPIO.digitalWrite(VELUX_UP, GPIO.LOW)
VELUX_STATE = 1
else:
GPIO.digitalWrite(VELUX_DOWN, GPIO.HIGH)
webiopi.sleep(0.2)
GPIO.digitalWrite(VELUX_DOWN, GPIO.LOW)
VELUX_STATE = 0
# loop function is repeatedly called by WebIOPi
def loop(): global VELUX_STATE, AUTO_MODE
# retrieve current datetime now = datetime.datetime.now()
if (AUTO_MODE==1):
# toggle VELUX UP all days at the correct time
if ((now.hour == HOUR_UP) and (now.minute == 0) and (VELUX_STATE == 0)):
GPIO.digitalWrite(VELUX_UP, GPIO.HIGH)
webiopi.sleep(0.2)
GPIO.digitalWrite(VELUX_UP, GPIO.LOW)
VELUX_STATE = 1 #UP
# toggle VELUX DOWN all days at the correct time
if ((now.hour == HOUR_DOWN) and (now.minute == 0) and (VELUX_STATE == 1)):
GPIO.digitalWrite(VELUX_DOWN, GPIO.HIGH)
webiopi.sleep(0.2)
GPIO.digitalWrite(VELUX_DOWN, GPIO.LOW)
VELUX_STATE = 0 #DOWN
# gives CPU some time before looping again webiopi.sleep(1)
# destroy function is called at WebIOPi shutdown
def destroy():
GPIO.digitalWrite(VELUX_UP, GPIO.LOW)
GPIO.digitalWrite(VELUX_DOWN, GPIO.LOW)
GPIO.digitalWrite(VELUX_STOP, GPIO.LOW)
#webiopi.macro def getHours():
return "%d;%d" % (HOUR_UP, HOUR_DOWN)
#webiopi.macro def setHours(on, off):
global HOUR_UP, HOUR_DOWN
HOUR_UP = int(on)
HOUR_DOWN = int(off)
return getHours()
#webiopi.macro def getAutoMode():
return "%d" % (AUTO_MODE)
#webiopi.macro def setAutoMode():
global AUTO_MODE
if AUTO_MODE:
AUTO_MODE=0
else:
AUTO_MODE=1
return getAutoMode()
The debug can't I post here because its on my RaspberryPi and the browser is to slow :)
But the first error he give is the dubble spaces by the comment VELUX UP
"HOUR_UP = 9 # Turn Velux UP at"
I solved this but then is it the error
"def setup():
global VELUX_STATE, AUTO_MODE"
Why?
Thanks!

Categories