2

I have a while statement running and checking if my button (on a gpio) is pressed and once it is I print something. I would like to add some shell commands like exit, etc... How can i have the while statement running while also accepting raw input and run different things depending on what's typed? (ex. check for button press in background but have raw input accept the word exit and close the program)

--Thanks

#--------------------------
#SORRY FOR HOW SLOPPY IT IS
#--------------------------


import RPi.GPIO as GPIO
import time
import os
import sys
sys.path.append('/usr/local/lib/python2.7/dist-packages')

#Library that allows me to print to my printer
from escpos import *

#To get the weather
import pywapi


import string

GPIO.setmode(GPIO.BCM)
GPIO.setwarnings(False)

button = 26
green = 4
yellow = 18
GPIO.setup(green, GPIO.OUT)
GPIO.setup(yellow, GPIO.OUT)
GPIO.setup(button, GPIO.IN, GPIO.PUD_UP)

GPIO.output(green, 1)
GPIO.output(yellow, 0)

print("Waiting for button press...")




#When the button is pressed begin the weather fetching and printing
def buttonPress(button):
    GPIO.output(green, 0)
    GPIO.output(yellow, 1)
    print("Printing...")
    weather_com_result = pywapi.get_weather_from_weather_com('CAXX2088')
    temp = (weather_com_result['current_conditions']['temperature'])
    text = string.lower(weather_com_result['current_conditions']['text'])
    precip0 = (weather_com_result['forecasts'][0]['day']['chance_precip'])
    precip1 = (weather_com_result['forecasts'][1]['day']['chance_precip'])
    precip_date1 = (weather_com_result['forecasts'][1]['date'])
    high = (weather_com_result['forecasts'][1]['high'])
    low = (weather_com_result['forecasts'][1]['low'])
    Epson = printer.Usb(0x04b8,0x0202)

    Epson.set(align="CENTER")
    Epson.set(bold=True)
    Epson.set(size="2x")
    Epson.text("Current Weather\n\n")

    Epson.set(size='normal')
    Epson.set(bold=False)

    Epson.text(string.capwords(text))

    Epson.text(" and "+temp)

    Epson.text("C\n")

    Epson.text("POP: " + precip0 + "%\n\n")

    Epson.set(bold=True)

    Epson.set(size="2x")

    Epson.text("Forecast For " + precip_date1 + "\n\n")

    Epson.set(size='normal')

    Epson.set(bold=False)

    Epson.text("POP: " + precip1 + "\n")
    Epson.text("High: " + high + "C  Low: "+ low +"C\n")
    Epson.cut()
    time.sleep(3)
    print("Printed.")

    #A loop that flashes a green light until the printer is ready for another print

    waittime=0

    while waittime<11:
        GPIO.output(green, 1)
        GPIO.output(yellow, 0)

        time.sleep(1)

        GPIO.output(green, 0)
        GPIO.output(yellow, 0)
        time.sleep(1)

        waittime += 2

    GPIO.output(green, 1)
    print("Waiting for button press...")



#Where I want to be able to input the command
#Also i know that this isnt a loop and will only happen once (i think) but i think i can manage to turn it into a loop later on
command = raw_input(": ")

GPIO.add_event_detect(button, GPIO.RISING,callback=buttonPress)

if command == "exit":
    GPIO.cleanup()
    sys.exit()
  • It depends on what sort of input you are looking for but there is python code in the standard stuff to handle "exceptions" and "signal-handling" such as the SIGTERM that typing <CTRL>-C sends when running python code interactively (in the foreground, in Raspian and other *nix OSes). Look up the python try, except (used with KeyboardInterrupt:) and finally keywords... – SlySven Jan 29 '16 at 20:26
  • Thanks ill take a look i wasnt sure where to start looking – Tyler Jan 30 '16 at 4:35
  • This question looks like it would have equal, if not more, merit on Stackoverflow.com – Quiquȅ Jan 31 '16 at 0:38
3

Depending on how your circuit is wired you should use

import RPi.GPIO as GPIO
GPIO.setmode(GPIO.BCM)

inputPin = "YOUR_PIN_GOES_HERE"
GPIO.setup(inputPin,GPIO.IN,pull_up_down=GPIO.PUD_UP)

def buttonPress(channel):
     #stuff

def buttonRelease(channel):
     #stuff


GPIO.add_event_detect(channel,GPIO.RISING,callback=buttonPress)
#OR
GPIO.add_event_detect(channel,GPIO.FALLING,callback=buttonRelease)

while(1):
      keypressed = raw_input('Press q to quit: ')
      if keypressed == 'q':
           break
      elif keypressed == 'SOME OTHER KEY':
           #code for some other thing
      else
           print("Unknown input")

These are events that will be trigged where there is a change on your input pin. Your raw_input can still handle whatver code you want because the event loop is running in the background.

Pulled from here

Edits: put the event defs above event declaration because I am teh dumb

While(1)'s are ugly. For the sake of staying a loop this should suffice though. Essentially this will run the keyboard input loop until you hit q. Use the elifs to handle other inputs. The else will capture unknown input and provide feedback. The break statment will boot the program out of the while loop and will reach the end of code and terminate.

Should you feel fancy and want to handle a lot of input I would look to use what other languages have a switch statement to clean up a bunch of elifs

Oh and standard warranty applies, I may have missed a tab or : here and there.

  • Thanks i think i understand how that works ill give it a try – Tyler Jan 30 '16 at 4:36
  • So I've been playing around with it and have gotten stuck I was hoping you could help. So I tried implementing the add_event_detect before the def buttonPress and got an error that "buttonPress is not defined" so i figured i'd try to but the add_event_detect after the def and now the function keeps loops any help would be appreciated. Thanks! – Tyler Jan 30 '16 at 17:25
  • My apologies. The functions buttonRelease and buttonPress should be defined before the event declaration. I will edit that as well as a suggestion for the loop. Stay tuned! – Bmo Jan 30 '16 at 18:24
  • Ok that makes a lot of sense however i'm still having an issue and i just realized I hadn't explained it very well. I had tried putting the def before and for the most part it worked however the function loops and code inside the def runs over and over. Do you know what this could be? If not maybe you'd like to look at my code. I must warn you though its very messy im new very new to python this is pretty much my first real project. – Tyler Jan 30 '16 at 18:55
  • Edit your question and drop the code in. – Bmo Jan 30 '16 at 18:56
1

Your Python module will offer GPIO callbacks. Generally you specify

  • a GPIO
  • whether you are interested in rising edges (0->1), falling edges (1->0), or both edges
  • and a function to be called when the event happens

The specified function will be called asynchronously to the main thread, i.e. it will still be called even if the main thread is waiting in a raw_input.

Generally you would use global variables to pass state information between the callback and main thread.

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.