New Project... New Python problem

Hi Guys,
My latest project is to rebuild my Door Bell after it stopped working… with a Pi ZeroW.

Im using a Pi Zero W, Pi camera, mono amplifier, 8ohm speaker and Pushbullet. My plan is to have someone press the bell, take a photo, play a doorbell sound and then send the picture to my phone via pushbullet.

I followed the Adafruit guide to getting 2 channel sound of the Pi, then linked the Left & Right Channels together with a 1k resistor on each channel to form a mono output (not sure if this is correct, but it works). The mono output then feeds into the Adafruit mono amplifier.

My code kind’a works fine except it plays the doorbell mp3 twice and I have no idea why. Its not the mp3 itself, I have removed the line to play the mp3 and replaced it with print (“Hello”) and I get hello appearing twice on the screen (and the button LED flashes twice).

Id appreciate any thoughts as to why this maybe happening. My only thought so far is button bouncing.

Here is my code so far:

#!/usr/bin/env python3

# Initialise Camera, PIR, Pushbullet
# If PIR goes high, Take picture & send via pushbullet and Play Doorbell.mp3
#
# mpg123 is a simple mp3 player.  Download and insall with:
#   - sudo apt-get install alsa-utils mpg123
#
# On Button Press, play mp3, power on Camera_LED, Take Photo, Turn Off Camera_LED


import RPi.GPIO as GPIO
#from pushbullet.pushbullet import Pushbullet
from time import sleep
import os
import picamera
import datetime


#PIR_sensor = 6             # This is the sensor-pin that goes high when movement is detected
Door_bell_lED = 23          # Switch LED on when PIR Sensor is triggered
Door_bell_button = 6        # Door Bell Switch

picture = ""
pic_path = "/home/pi/Python/Doorbell/Pictures/"
pic_filename = ""
mp3_path = "/home/pi/Python/Doorbell/Code/"
mp3 = "doorbell.mp3"
mp3_filename = mp3_path + mp3


GPIO.setmode(GPIO.BCM)
GPIO.setup(Door_bell_lED, GPIO.OUT)
GPIO.setup(Door_bell_button, GPIO.IN, pull_up_down=GPIO.PUD_UP)
#GPIO.setup(PIR_sensor, GPIO.IN)

camera = picamera.PiCamera()



def Initialise_Camera():
#    camera.resolution = (1024, 768)
#    camera.start_preview()
    sleep(0.25)
#    for i in range(100):
#        camera.brightness = i
#        print("Camera Brightness = " + str(i))
#        sleep(0.2)
#    camera.stop_preview()
#    camera.hflip = True
#    camera.vflip = True



#def Send_Pushbullet():
#    # This is the script to send the picture to Pushbullet
#    pb = Pushbullet("o.ogCp0HROoicYW0abk1Wy80TLPtSzqi9t")
#    #pic_filename = pic_path + picture + ".jpg"
#    with open(pic_filename, "rb") as pic:
#        file_data = pb.upload_file(pic, pic_filename)
#    push = pb.push_file(**file_data)



def PIR_Motion_Sensor(PIR):
        GPIO.output(Door_bell_lED, True)
        print("LED ON - Button Pressed, taking Photo.")
        Get_TimeandDate()
        GPIO.output(Door_bell_lED, False)
        print("LED OFF")
#        Send_Pushbullet()
        sleep(0.25)
        


def Get_TimeandDate():
        now = datetime.datetime.now()
        picture = now.strftime("%Y-%m-%d_%H-%M-%S")
        pic_filename = pic_path + picture + ".jpg"
        print (pic_filename)
        camera.capture(pic_filename)                        # Take Picture
        os.system('mpg123 -q ' + mp3_filename + ' &')       # Play DoorBell sound


  

# COMMENCE MAIN CODE / LOOP
#

Initialise_Camera()
print ("Camera Initialised (CTRL+C to exit)")
print ("Waiting for Button Press...")

GPIO.add_event_detect(Door_bell_button, GPIO.FALLING, callback=PIR_Motion_Sensor)   # Setup interrupt event

try:
    while 1:
        sleep(0.1)
 
except KeyboardInterrupt:  
        # here you put any code you want to run before the program   
        # exits when you press CTRL+C
        print("Hello Keyboard Interrupt")
  
#except:  
        # this catches ALL other exceptions including errors.  
        # You won't get any error messages for debugging  
        # so only use it once your code is working  
        # print ("Other error or exception occurred!")
  
finally:
        print("Cleaned Up GPIO... \nBye!")
        GPIO.cleanup() # this ensures a clean exit

Any thoughts?

Thanks
Jon

Hi John,

The easiest way to check if it’s an issue with your button debouncing (I’m fairly sure that’s the issue) is to print something to the terminal whenever the button is pressed. If that’s triggering twice, then your button is bouncing. Adding a short delay is a simple way to implement debouncing, otherwise, take a look at the example in the ‘If Statement’ chapter of the Arduino Online Course which provides some nice logic for button debouncing. You’d need to write it in Python obviously, but it helps simplify the logic required.

Hi Sam,
Problem solved…

I remembered some reading Id done a while ago about the GPIO library now including a debounce algorithm for interrupts. My original code was:

GPIO.add_event_detect(Door_bell_button, GPIO.FALLING, callback=PIR_Motion_Sensor)

The modified / corrected code is:

GPIO.add_event_detect(Door_bell_button, GPIO.FALLING, callback=PIR_Motion_Sensor, bouncetime=1000)

Hope this is of use to others as well.

Jon

Hi Jon,

Glad to hear it, best of luck with the project!