I was facing a problem to break counter variable after every 1 second.
This counter variable will keep tract of vehicle wheel revolution per seond which will help to calculate speed.
Also how we can pass a parameter in a function callback inside GPIO.add_event_detect() method.
My code for calculating vehicle speed is as follows :
import time
import datetime
import RPi.GPIO as GPIO
def sensorCallback(channel,cir=1.884):
#Called if sensor output changes
ts = datetime.datetime.now()
s=ts.second
count=0
if s%59==0:
count=0
else:
#Magnet
count=count+1
speed = count*cir*3600/1000
print(speed)
def main():
count=0
r=30
cir = (2*3.14*r)/100
s=0
last=0
speed=0
try:
while True :
time.sleep(0.1)
except KeyboardInterrupt:
GPIO.cleanup()
GPIO.setmode(GPIO.BCM)
GPIO.setup(17 , GPIO.IN, pull_up_down=GPIO.PUD_UP)
GPIO.add_event_detect(17, GPIO.BOTH, callback=sensorCallback(count), bouncetime=200)
Related
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
Hi ladies and gentleman,
please forgive me if I've inputted the below code wrong as this is my first time posting here. I have a python script here that polls a capacitor every tenth of a second that is currently being used with a light dependent resistor to determine the brightness outside.
The only problem is that the numerical value often varies by around +/- 5. I would like to implement a line of code that averages the last ten polls every second and prints them. I have no idea where to start, any help would be appreciated!!
#!/usr/local/bin/python
import RPi.GPIO as GPIO
import time
import I2C_LCD_driver
GPIO.setmode(GPIO.BOARD)
mylcd = I2C_LCD_driver.lcd()
#define the pin that goes to the circuit
pin_to_circuit = 40
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
return count
#Catch when script is interrupted, cleanup correctly
try:
# Main loop
while True:
print "Current date & time " + time.strftime("%c")
print rc_time(pin_to_circuit)
a = rc_time(pin_to_circuit)
mylcd.lcd_display_string("->%s" %a)
mylcd.lcd_display_string("%s" %time.strftime("%m/%d/%Y %H:%M"), 2)
except KeyboardInterrupt:
pass
finally:
GPIO.cleanup()
You could define a list in your main loop:
polls = []
#Catch when script is interrupted, cleanup correctly
try:
# Main loop
while True:
print "Current date & time " + time.strftime("%c")
print rc_time(pin_to_circuit)
a = rc_time(pin_to_circuit)
#add current poll to list of polls
polls.append(a)
#remove excess history
if len(polls) > 10:
polls.pop(0)
#calculate average
avg = sum(polls)/len(polls)
mylcd.lcd_display_string("->%s" %avg)
mylcd.lcd_display_string("%s" %time.strftime("%m/%d/%Y %H:%M"), 2)
except KeyboardInterrupt:
pass
finally:
GPIO.cleanup()
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?
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)
I have this function in a python script that detects 2 vibrations sensors, the problem is the sensors are very sensitive so usually when one is hit they are both detected which gives me a false reading. How would I stop them both from being detected at the same time? I want to detect whichever was first. This is what I have tried -
#!/usr/bin/env python
import RPi.GPIO as GPIO
from time import sleep
def setup():
GPIO.setmode(GPIO.BOARD)
GPIO.setup(KnockPin, GPIO.IN, pull_up_down=GPIO.PUD_UP)
GPIO.setup(ShockPin, GPIO.IN, pull_up_down=GPIO.PUD_UP)
def shock():
print('shock')
def knock():
print('knock')
def register_callbacks():
if GPIO.add_event_detect(ShockPin, GPIO.FALLING, callback=shock, bouncetime=5000):
sleep(5)
elif GPIO.add_event_detect(KnockPin, GPIO.FALLING, callback=knock, bouncetime=5000):
sleep(5)
if __name__ == '__main__':
try:
setup()
register_callbacks()
Just a suggestion, I don't have the setup to test it. Save the time of the last event (using datetime), and then check if the last event is more than 5 seconds ago.
import datetime
sensor_delay = 5 #delay in seconds
last_event = datetime.datetime.now()
def shock():
global last_event
if datetime.datetime.now() > last_event + datetime.timedelta(seconds=sensor_delay):
print ('shock')
last_event = datetime.datetime.now()
def knock():
global last_event
if datetime.datetime.now() > last_event + datetime.timedelta(seconds=sensor_delay):
print('knock')
last_event = datetime.datetime.now()