On Wednesday, 22 February 2017 17:49:08 GMT Ralph Corderoy wrote:
> > They seem to get variously called Procedures and Functions in my
> > 'Learning Python' Book (which doesn't cover multiprocessing).  I mean
> > a piece of code defined within a 'def' block.
> 
> The book's wrong.  :-)  In Python, they're functions, lower F.  Even a
> function without an explicit return statement still returns None whether
> the caller wants it or not.

Well to be fair, the book does mention in a couple of places that they are 
called functions and are similar to procedures in other languages, but then 
mentions procedures quite a few times in a fairly ambiguous way.  (I had to 
search through the eBook version to discover that statement BTW.)

> > Well the documentation for RPi.GPIO seems to consist only of the
> > Tutorials  on Alex Eames' website
> 
> I was looking at
> https://sourceforge.net/p/raspberry-gpio-python/wiki/Inputs/
> Don't know if that's the same thing.  And then
> https://sourceforge.net/p/raspberry-gpio-python/code/ci/default/tree/source/
> event_gpio.c#l36

Those are one of several places that I looked.  What I haven't found is a 
definitive list of methods that RPi.GPIO supports.

> > def change_rings():       # Play a file of change rings
> > 
> >     global chr_subdir
> >     global chr_control
> >     
> >     c_file = 'Wimborne_Minster_StedmanCinques_16-10-2016.mp3' # Change
> >     rings.
> >     c_path = os.path.join(chr_subdir, c_file)
> >     blackhole = open(os.devnull, 'w')
> 
> I'd open this once as a global variable.  Python will garbage collect
> and close the file descriptors over time as all the references die out,
> but that's assuming they do die out.  If they don't, the process will
> use up ever more file descriptors and there's a couple of limits it
> could reach that would make open() fail.

This part has me somewhat confused.  When you say 'I'd open this once as a 
global variable', you surely don't mean the function?  How would you do that?

> >     print 'Playing Changes - ', c_file, 'to the Tower'
> >     c_player = subprocess.Popen(['mpg321', '-q', '-m', '-a', 'hw:0,0',
> >     c_path],
> >     
> >         stdin=subprocess.PIPE, stdout=blackhole, stderr=blackhole)
> >     
> >     while chr_control:
> >         c_player.poll()   # check to see if terminated
> >         
> >         if c_player.returncode != None:
> >             break
> >         
> >         time.sleep(0.1)
> 
> Does this busy loop really need to exist?  Instead, change_rings() could
> just kick off the subprocess, stash the `c_player' somewhere, and then
> return.  Callbacks often do a small slice of work and then return,
> otherwise the `main loop' can't continue, as you've found.
> 
> The callback for the switch to nobble the bells can then terminate(),
> since it's OK to do that whether mpg321 has finished or not as long as
> the zombie child hasn't been reaped with poll().

I think I understand what you are suggesting here.  What I believe that you 
are saying is that c_player should be made into a global variable and the 
callback in the GPIO event should perform the terminate().  Is that what you 
were leading up to above?

Assuming this is possible, would it be something like:

GPIO.add_event_detect(20, GPIO.RISING, callback=c_player.terminate(), 
bouncetime=500)

Can that be done (or something like it)?

Assuming that it can, it still leaves me with some work left to do.  I picked 
the change_rings() function because it was one of the simplest, but maybe I 
should have been more explicit.  The are four functions that are controlled by 
the toggle switches on the front of the Control Box:

1.  Extended Hours Control - Change the 'Opening Hours' that determine when 
the hours, Quarter Jack chimes and other playing functions are allowed to 
sound.  This needs to set / unset a variable and play a short message to 
inform the user of the current state, eg 'Extended Hours Enabled'.  The 
variable is then used to inhibit playback outside opening hours.

2.  Change Rings Control - The simplest function.  It either plays the bells 
or it stops them.  No extra feedback needed for the user.  I could seen that 
your suggestion could work here.

3.  MP3  Control - The most complicated.  Depressing the switch increments a 
variable, plays a user message to indicate which Playlist is selected and then 
fires off the player whaich will then loop through the Playlist until stopped 
by an upwards click.

4.  Wedding Sequence - A kind of extended Change Rings, except that there are 
three tracks to play.

So you see, for most cases it isn't enough to simply kill the MP3 player.  
There are generally at least one other thing that needs doing; hence my query 
about threaded or multi-processed function calls.

-- 



                Terry Coles

-- 
Next meeting:  Bournemouth, Tuesday, 2017-03-07 20:00
Meets, Mailing list, IRC, LinkedIn, ...  http://dorset.lug.org.uk/
New thread:  mailto:[email protected] / CHECK IF YOU'RE REPLYING
Reporting bugs well:  http://goo.gl/4Xue     / TO THE LIST OR THE AUTHOR

Reply via email to