2

I have written a small Wifi Radio program in Python that accesses the GPIO. Press button 1 it starts the radio, 2 pauses it, 3 next station etc. I have a i2c LCD display that displays the status of the radio (play, pause etc.)

I can execute the program with no issue through the GUI interface (Idle). I start Idle, open the program and press F5 to run. This opens the idle shell, outputs a 'restart' message and the radio works as it is supposed to.

However, when I run the program from a terminal (either ssh or from the terminal) the program executes but non of the buttons work. The radio starts but that is it.

I suspect is is something to do with one of the import statements.

My goal is to have this program run at boot. I don't have a preference if it runs in the GUI or Console but I will be running without a monitor (headless)

Following is a copy of the program.

I think I have commented enough to give you an idea of how it works.

Thanks in advance for looking...and hopefully helping me fix the problem.


#this is a wifi radio program
#the operation is simple
#manually add streaming stations to mpc
#from the console mpc add streaming station

#example mpc add http://live.scpr.org/kpcclive/
# will add the public KPCC radio station to the playlist
# you can either go to the radio station to see if they have
# a live stream available or go to www.shoutcast.com
# find the music or genre you want to listen to
# click the download button.  choose any player (.m3u) file format
# this will save a text 'playlist' to your computer.  rename
# the text list with a file type .txt so you can open it with
# a text editor.  copy all the text from http:// to the end of
# the line.

# from ssh or terminal type mpc add then paste the string
# it will look something like
# add mpc http://live.scpr.org/kpcclive/
# not all streams work.  I haven't figured out the magic
# to that yet.


# RPi.GPIO is the GPIO definition file (class?)
# os allows me to enter text in a command as if I was
# typing from the keyboard
# lcddriver is the driver for the 4x20 LCD i2c display
# subprocess allows me to get the stream name.

import RPi.GPIO as GPIO
from time import *
import os
import lcddriver
import subprocess


lcd = lcddriver.lcd()
lcd.__init__()


#Use board pin scheme
GPIO.setmode(GPIO.BOARD)

#allow the playlist to 'go around' 123,123 etc.

os.system ("mpc repeat on")

#All GPIO are set high, trigger on low to high

GPIO.setup (11, GPIO.IN, pull_up_down=GPIO.PUD_UP)
GPIO.setup (13, GPIO.IN, pull_up_down=GPIO.PUD_UP)
GPIO.setup (15, GPIO.IN, pull_up_down=GPIO.PUD_UP)
GPIO.setup (16, GPIO.IN, pull_up_down=GPIO.PUD_UP)
GPIO.setup (18, GPIO.IN, pull_up_down=GPIO.PUD_UP)
GPIO.setup (22, GPIO.IN, pull_up_down=GPIO.PUD_UP)

#interupts 11 = Play, 13 = pause, 15 = next, 16 = previous
#18 = volume up, 22 = volume down
GPIO.add_event_detect(11, GPIO.FALLING)
GPIO.add_event_detect(13, GPIO.FALLING)
GPIO.add_event_detect(15, GPIO.FALLING)
GPIO.add_event_detect(16, GPIO.FALLING)
GPIO.add_event_detect(18, GPIO.FALLING)
GPIO.add_event_detect(22, GPIO.FALLING)

#initilize radio - start playing

os.system ('mpc play')
lcd.lcd_display_string("       PLAYING",1)

os.system ('mpc play')
lcd.lcd_display_string("       PLAYING",1)
currentplay = subprocess.check_output(["mpc", "current"])
trunc = "      " +  currentplay[0:10]
print trunc
lcd.lcd_display_string(trunc,3)


# BUTTON 1 PLAY
def my_callback(n):
        lcd.lcd_clear()
        os.system ('mpc play')
        lcd.lcd_display_string("       PLAYING",1)
        currentplay = subprocess.check_output(["mpc", "current"])
        trunc = "      " + currentplay[0:10]
        print trunc
        lcd.lcd_display_string(trunc,3)


GPIO.add_event_callback(11, my_callback)


# BUTTON 2 PAUSE
def my_callback(n):

        lcd.lcd_clear()
        os.system ('mpc pause')
        lcd.lcd_display_string("       PAUSE",1)


GPIO.add_event_callback(13, my_callback)


# BUTTON 3 NEXT STATION
def my_callback(n):

        lcd.lcd_clear()
        os.system ('mpc next')
        currentplay = subprocess.check_output(["mpc", "current"])
        lcd.lcd_display_string("     NEXT STATION",2)

        sleep (.5)
        lcd.lcd_clear()
        trunc = "      " + currentplay[0:9]
        lcd.lcd_display_string("       PLAYING",1)
        lcd.lcd_display_string(trunc,3)


GPIO.add_event_callback(15, my_callback)

# BUTTON 4 PREVIOUS STATION
def my_callback(n):
        lcd.lcd_clear()
        os.system ('mpc prev')
        currentplay = subprocess.check_output(["mpc", "current"])
        lcd.lcd_display_string("  PREVIOUS STATION",2)
        sleep (.5)
        lcd.lcd_clear()
        trunc = "      " + currentplay[0:9]
        lcd.lcd_display_string("       PLAYING",1)
        lcd.lcd_display_string(trunc,3)


GPIO.add_event_callback(16, my_callback)


# BUTTON 5 VOLUME UP
def my_callback(n):

        os.system ('mpc volume +5')
        lcd.lcd_display_string("                    ",2)

        lcd.lcd_display_string("INCREASE VOLUME +5",2)


GPIO.add_event_callback(18, my_callback)

# BUTTON 6 VOLUME DOWN
def my_callback(n):
        os.system ('mpc volume -5')
        lcd.lcd_display_string("                    ",2)

        lcd.lcd_display_string("DECREASE VOLUME +5",2)

    GPIO.add_event_callback(22, my_callback)
  • Post the full script. If it's too long you won't be able to make the post. – joan Jun 10 '16 at 7:33
  • is it running from the same python version in both desktop and cli? I don't see a shebang at the top of the script so I am guessing it may be an issue but can't say for certain. – Brett Reinhard Feb 23 '17 at 23:04
1

I see some things that could potentially wipeout your program, but without testing i could not say if they are what you looking for.

But i could bet your problem is so simple as a loop. In IDLE your programs are running while you press f5. It executes and store everything you created. When you try this on a standard terminal, it will load your variables and functions, but the script will end there and everything will go to the trash. Callbacks will not be stored and your buttons will not work.

So you need a main loop which holds the program. Something of this kind:

if __name__ == '__main__':
    while True:
        GPIO.add_event_callback(type your callback here)

I'm not so sure about what should be in main loop, but i'm sure that is your problem!! Oh, and if this way work for you, you should add another button which returns false to end the program.

  • 1
    And just for manners, you should name your callbacks with custom names. Call everything myCallback is recipe for disaster. – David P. Jun 12 '16 at 15:25

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.