kempfa
Posts: 8
Joined: Wed Nov 22, 2017 8:57 pm

Reed contact starts omxplayer several times

Wed Nov 22, 2017 9:07 pm

Good evening,

i am new to this forum, maybe the entry here is in the wrong place.

I'm programming my Raspberry PI with a reed contact. When the door is opened, an audio file should be played back. So far I managed to do that, see Script, but the OMXPLAYER starts the playback of the song several times. But I want it to be given only once.

I am still a beginner in programming with Python, maybe you can help me! Many thanks in advance!

Cheers

André

Code: Select all

import time # so we can use "sleep" to wait between actions
import RPi.GPIO as io
import subprocess 
 
## set GPIO mode to BCM
## this takes GPIO number instead of pin number
io.setmode(io.BCM)
 
## enter the number of whatever GPIO pin you're using
door_pin = 23
 
## use the built-in pull-up resistor
io.setup(door_pin, io.IN, pull_up_down=io.PUD_UP)  # activate input with PullUp

## initialize door 
door=0
 
## this loop will execute the if statement that is true
while True:
    ## if the switch is open
    if io.input(door_pin):
        print("Door is open")
	myprocess = subprocess.Popen(['mpg321','/home/pi/Musik/song.mp3'])

        #time.sleep(5) # wait 0.5 seconds before the next action

    ## if the switch is closed and door does not equal 1
    if (io.input(door_pin)==False and door!=1):
        print("Door is closed")
        


Davies
Posts: 150
Joined: Sat Apr 04, 2015 4:24 pm

Re: Reed contact starts omxplayer several times

Thu Nov 23, 2017 1:17 am

you have a few lines missing to protect the code from running time and time again
while True: means while the unit is switched on
so at the moment your saying while the raspberry is switched on,
if door input is live print door open and run this mp3, that happens and the while script goes back to beginning and does the same thing again and again more or less instantaneously,
in the second code you have if not door open and door not = 1, print door closed but the variable isnt set to 1 so the while script runs again and again this condition is met so youll have multiple prints of door closed.
you need to handle the variable youve called "door" so the condition can only be met once when the door is opened and once when the door is closed.
you also need a sleep for time command on the while script otherwise you end up with multiple consecutive instances of the while script and it will fail eventually without the sleep command or some form of delay.

Code: Select all

while True:
    ## if the switch is open
    if io.input(door_pin) and door == 0:
        print("Door is open")
	myprocess = subprocess.Popen(['mpg321','/home/pi/Musik/song.mp3'])
	door = 1
	

    ## if the switch is closed and door does not equal 1
    if io.input(door_pin)==False and door == 1:
        print("Door is closed")
        door = 0
    
    time.sleep(0.5) # wait 0.5 seconds before the next action
door != means door not equal, door == means door is equal to.. so door != 1 and door == 0 means the same thing, as long as door can only ever equal 1 or 0

kempfa
Posts: 8
Joined: Wed Nov 22, 2017 8:57 pm

Re: Reed contact starts omxplayer several times

Sat Nov 25, 2017 4:13 pm

Thank you Davies it works very well!

kempfa
Posts: 8
Joined: Wed Nov 22, 2017 8:57 pm

Re: Reed contact starts omxplayer several times

Sat Nov 25, 2017 5:21 pm

I have one more question. If the door is getting closed until the song is playing, the song should stop. Hhow can I interrupt / kill this process?

Code: Select all

## Reedcontact starts Audiofile, when Switch is open

import time 
import RPi.GPIO as io
import subprocess 
import os
 
## set GPIO mode to BCM
io.setmode(io.BCM)
 
## enter the number of whatever GPIO pin you're using
door_pin = 23
 
## use the built-in pull-up resistor
io.setup(door_pin, io.IN, pull_up_down=io.PUD_UP)  # activate input with PullUp

## initialize door 
door=0
 
## this loop will execute the if statement that is true
while True:
    ## if the switch is open
    if io.input(door_pin) and door == 0:
        print("Door is open")
	myprocess = subprocess.Popen(['omxplayer','/home/pi/Musik/Metallica-Whiskey-In-The-Jar.mp3'])
	door = 1
	
	## if the door is getting closed song should stop
	if io.input(door_pin) and door == 1:
	os.system('killall omxplayer.bin')
	door = 0
	
    ## if the switch is closed and door does not equal 1
    if io.input(door_pin)==False and door == 1:
        print("Door is closed")
        door = 0
    
    time.sleep(0.5) # wait 0.5 seconds before the next action
I tried os.system('killal omxplayer.bin')

Thank you in advance!

Davies
Posts: 150
Joined: Sat Apr 04, 2015 4:24 pm

Re: Reed contact starts omxplayer several times

Sun Nov 26, 2017 10:52 am

Code: Select all

import time
import RPi.GPIO as io
import subprocess
import os

## set GPIO mode to BCM
io.setmode(io.BCM)

## enter the number of whatever GPIO pin you're using
door_pin = 23

## use the built-in pull-up resistor
io.setup(door_pin, io.IN, pull_up_down=io.PUD_UP)  # activate input with PullUp

## initialize door 
door = 0

## this loop will execute the if statement that is true
while True:
    ## if the switch is open
    if io.input(door_pin) and door == 0:
        print("Door is open")
        myprocess = subprocess.Popen(['omxplayer', '/home/pi/Musik/Metallica-Whiskey-In-The-Jar.mp3'])
        door = 1


    ## if the switch is closed and door does not equal 1
    if not io.input(door_pin) and door == 1:
        print("Door is closed")
        door = 0
        os.system('killall omxplayer.bin')  # door closed will kill current music

    time.sleep(0.5)  # wait 0.5 seconds before the next action
you may get an error in the condition that,
if the door is left open longer than the song time, then omxplayer may close itself on the song finish. if omxplayer has closed itself and you try to close it again with killall by closing the door, then it may bring an error (im unsure of this without testing) an error would cause the code to fail and stop.
you can test for this by leaving the door open with the raspberry plugged into a screen, once the song is finished close the door and see if you get an error, if so you would need to handle the error(if no error open door again to ensure the code is still running and song plays again). you could handle an error with try: except:

Code: Select all

    ## if the switch is closed and door does not equal 1
    if not io.input(door_pin) and door == 1:
        print("Door is closed")
        door = 0
        try:
            os.system('killall omxplayer.bin')  # door closed will kill current music
        except:
            pass

kempfa
Posts: 8
Joined: Wed Nov 22, 2017 8:57 pm

Re: Reed contact starts omxplayer several times

Sun Nov 26, 2017 5:52 pm

Thank you so much, it works fine.

But now I've the next problem. I want to select a soundfile from a specific folder. I put in a function called rndmp3. A file in the directory is selected and played back, but when I close the door the playback does not stop. How can I stop the playback of the function?

Code: Select all

## Reedcontact starts Audiofile, when Switch is open

import time 
import RPi.GPIO as io
import subprocess 
import os, random
 
## set GPIO mode to BCM
io.setmode(io.BCM)
 
## enter the number of whatever GPIO pin you're using
door_pin = 23
 
## use the built-in pull-up resistor
io.setup(door_pin, io.IN, pull_up_down=io.PUD_UP)  # activate input with PullUp

## initialize door 
door=0

## Function Random Soundfile
def rndmp3():
    rmfile = random.choice(os.listdir("/home/pi/Musik/"))
    file = '\'/home/pi/Musik/'+ rmfile + '\''
    os.system ('omxplayer ' + file)
    print(file)
    return;

## this loop will execute the if statement that is true	
while True:
	
    ## if the switch is open
    if io.input(door_pin) and door == 0:
        print("Door is open")
        rndmp3()
        door = 1
		
    ## if the switch is closed and door does not equal 1
    if io.input(door_pin)==False and door == 1:
        print("Door is closed")
        door = 0
        try:
            os.system('killall omxplayer')		
        except:
            pass
			
    time.sleep(0.5) # wait 0.5 seconds before the next action
 
Thank you all!

Davies
Posts: 150
Joined: Sat Apr 04, 2015 4:24 pm

Re: Reed contact starts omxplayer several times

Sun Nov 26, 2017 6:20 pm

can you open the file in the current manner, using

Code: Select all

myprocess = subprocess.Popen(['omxplayer', file])
rather than using

Code: Select all

os.system ('omxplayer ' + file)
?

Return to “Python”