What I am trying to do is use a vibration sensor to trigger a motor to run. I want the pi to wait until a vibrate is sensed and then run the motor for a period of time, then stop and wait again. I can easily get the vibration trigger to work using "add_event_detect" interrupts but the motor running also triggers the event. So I can do a debounce but for whatever reason, it always creates a trigger loop. I've done a debounce of like 999999999 and have the motor stop after 10 seconds but once it reaches 10 seconds, it just starts the run again.
So I thought, maybe if I remove the event when it is triggered, run the motor and then when it is done running, add the event back, it would work but no luck. It gets triggered, runs the motor, stops the motor after my defined time and then the event detect won't trigger the motor to run again. Something else that may be noteworthy is that I was "waiting for a vibration" by doing the 'While True: pass' instead of sleeping but it gave me the same result.
Does anyone have any insight into this? My code is below.
import RPi.GPIO as GPIO
from time import sleep
import random
import decimal
# motor stuff
global Motor1
global Motor2
global Motor3
global p
global q
global dutyCycle
global channel
Motor1 = 16 # Input Pin
Motor2 = 18 # Input Pin
Motor3 = 22 # Enable Pin
GPIO.setmode(GPIO.BOARD)
GPIO.setup(Motor1,GPIO.OUT)
GPIO.setup(Motor2,GPIO.OUT)
GPIO.setup(Motor3,GPIO.OUT)
p = GPIO.PWM(Motor1,30)
q = GPIO.PWM(Motor2,30)
p.start(0)
q.start(0)
dutyCycle = 30
# vibration sensor stuff
channel = 40
GPIO.setup(channel, GPIO.IN)
def get_wait_time():
waitTime = float(decimal.Decimal(random.randrange(1, 201))/100)
return waitTime
def do_the_spin(channel):
remove_event_detect()
i=0
global Motor1
global Motor2
global Motor3
global p
global q
global dutyCycle
timeToSpin = 10
print "\n\nvibration detected! Run the motor!\n\n"
while i<timeToSpin:
try:
print "FORWARD MOTION"
q.ChangeDutyCycle(0)
p.ChangeDutyCycle(dutyCycle)
GPIO.output(Motor3,GPIO.HIGH)
waitTime = get_wait_time()
i+=waitTime
sleep(waitTime)
print "BACKWARD MOTION"
p.ChangeDutyCycle(0)
q.ChangeDutyCycle(dutyCycle)
GPIO.output(Motor3,GPIO.HIGH)
waitTime = get_wait_time()
i+=waitTime
sleep(waitTime)
print "STOP"
print 'i= '+str(i)
GPIO.output(Motor3,GPIO.LOW)
except KeyboardInterrupt:
print "\nCleaning up and closing"
p.stop()
q.stop()
GPIO.cleanup()
quit()
set_event_detect()
def remove_event_detect():
print "remove_event_detect"
GPIO.remove_event_detect(channel)
def set_event_detect():
print "set_event_detect"
GPIO.add_event_detect(channel, GPIO.BOTH, callback=do_the_spin, bouncetime=99)
GPIO.add_event_callback(channel, do_the_spin) # assign function to GPIO PIN, Run function on change
go_to_sleep()
def go_to_sleep():
#GPIO.add_event_detect(channel, GPIO.BOTH, callback=do_the_spin, bouncetime=15000) # let us know when the pin goes HIGH or LOW
print "\nWaiting for vibration..."
sleep(150000)
try:
#GPIO.add_event_detect(channel, GPIO.BOTH, callback=do_the_spin, bouncetime=15000) # let us know when the pin goes HIGH or LOW
#GPIO.add_event_callback(channel, do_the_spin) # assign function to GPIO PIN, Run function on change
#do_the_spin(channel)
set_event_detect()
except:
print "\nCleaning up and closing"
p.stop()
q.stop()
GPIO.cleanup()
quit()