Tutorial: Using a Grove Button on Smart Plant Pi Kickstarter – Raspberry Pi
This is an article about how to use a Grove Button using Python on the Raspberry Pi. This button is a part of the Smart Plant Pi new Kickstarter.
SmartPlantPi Features
[list]
[list_item size=”small” icon=”icon-beaker” hex_color=””]Measure your Temperature![/list_item]
[list_item size=”small” icon=”icon-beaker” hex_color=””]Measured your Soil Moisture![/list_item]
[list_item size=”small” icon=”icon-beaker” hex_color=””]Measure your Sunlight![/list_item]
[list_item size=”small” icon=”icon-beaker” hex_color=””]Show your results on the Internet![/list_item]
[list_item size=”small” icon=”icon-beaker” hex_color=””]Even connect your plant to the Amazon Echo/Alexa![/list_item]
[/list]
[callout size=”col-12″ title=”Checkout the SmartPlantPi Kickstarter” button_title=”Go to Kickstarter” button_link=”https://www.kickstarter.com/projects/sunair/1801490632?token=c7277b31″ button_size=”normal” button_rounded=”true” button_color=”red”]
[section]
This is a perfect project kit for kids with some help from the adults and for adults trying to learn some new things. We have done this before with our successful OurWeather kickstarter so we know what we are talking about. People all over the world have built the OurWeather weather station with great success. This project has no soldering involved and uses Grove connectors to wire everything up! You can’t reverse them and blow things up. Here is our tutorial on the Grove system.
Easy to build. Easy to learn about the IOT (Internet Of Things) and the Raspberry Pi.
SwitchDoc Labs is building on the strength and reception of our last successful No Soldering Kickstarter Project – OurWeather.
Just want a single button? You can buy one in our SwitchDoc Labs store here or on Amazon.com.
The Grove Button (P) – P for Panel
This Grove button contains one independent button, which is configured with pull-down resistor. Ready for use with our microcontrollers as digital input. The button signals the SIG wire, with the second SIG wire being a no-connect.
What does “P” mean? “P” is for “panel mount” in this product. . The Grove connecter is moved to the back so that you can easily use it as a neat and wire-free interface button.
The Grove Button (P) is a momentary push button. It contains one “momentary on/off” button. “Momentary” means that the button rebounds on its own after it is released. The button outputs a HIGH signal when pressed, and LOW when released. The button signals the SIG Pin of the Grove Interface.
The Video
The Raspberry Pi Software
We are using this button in the new Kickstarter, SmartPlantPi. The button has three functions. Press it once (all within two seconds), it will tell the computer that you have filled the water basin (SmartPlantPi knows that the basin is empty by looking at the flow meter sensor). Press it twice (again all within two seconds), it will set the Moisture Threshold (the percent soil moisture to start watering the plant) to the current soil moisture of the plant. It’s a handy way of setting the Moisture Threshold when you have your plant with just the perfect amount of water for the plant. Three presses and SmartPlant Pi sets the Moisture Threshold to the default value (currently 65%).
The Interrupt Driver
When you press the button, the software is set up such that you interrupt the processor and the software counts the number of presses and sets a time out (using apscheduler – a fabulous easy to use Python based scheduler package)
Following is the GPIO initialization line of code and the two Interrupt service routines. The first is called by the button press and the second routine is called by the 2 second timeout by apscheduler.
############### # button sensor setup ############### GPIO.setup(config.buttonClick, GPIO.IN, pull_up_down=GPIO.PUD_DOWN) # set up interrupts to handle buttonClick GPIO.add_event_detect(config.buttonClick,GPIO.FALLING,callback=buttonClickEventHandler, bouncetime=100) # handle the button click event def buttonClickEventHandler (pin): global buttonPush, buttonInProgress, buttonState, buttonStartTime, scheduler print "handling button Click event. preBS=",buttonState if (buttonPush == False): if (buttonInProgress == False): buttonInProgress = True buttonPush = False buttonState = 1 buttonStartTime = time.time() endTime = datetime.now() + timedelta(seconds=2) scheduler.add_job(buttonSampleEnd, 'date', run_date=endTime) state.SPP_State = state.SPP_States.Button return else: buttonState = buttonState +1 # limit to 3 if (buttonState > 3): buttonState = 3 return def buttonSampleEnd(): global buttonPush, buttonInProgress, buttonState, buttonStartTime buttonInProgress = False buttonPush = True state.SPP_State = state.SPP_States.Monitor buttonPush = False buttonInProgress = False buttonState = 0 buttonStartTime = 0
Note how the interrupt routine counts up to three key presses in two seconds. That is how we determine what we are being told to do.
The Button Interpretation Code
Next is the code in the main line section of SmartPlantPi that specifically handles the Button Press and writes out the results to the Grove OLED screen on SmartPlantPi. Note the use of the threading lock OLEDLock to keep this OLED writing code from interfering with other status output.
############# # Standalone Button Interface ############# if (buttonPush == True): # deal with the button Push print "button State = ", buttonState buttonPush = False OLEDLock.acquire() list = startStatementDisplay(display) # one button push = water now full if (buttonState == 1): makeStatementDisplay(list, 1," Water Filled" ) state.Pump_Water_Full = 1 state.Last_Event = "Water set to Full "+time.strftime("%Y-%m-%d %H:%M:%S") # two button push = set moisture threshold to current reading of moisture_sensor if (buttonState == 2): makeStatementDisplay(list, 1," Soil Moisture") makeStatementDisplay(list, 2," Threshold") state.Moisture_Limit = state.Moisture_Humidity makeStatementDisplay(list, 3," Set to=%6.1f%%" % state.Moisture_Limit) state.Last_Event = ("Moisture Lim Set to %6.1f: " % state.Moisture_Limit)+time.strftime("%Y-%m-%d %H:%M:%S") # three button push, set moisture threshold to default (65%) if (buttonState == 3): makeStatementDisplay(list, 1," Soil Moisture") makeStatementDisplay(list, 2," Threshold") makeStatementDisplay(list, 3," Set to default=65%") state.Moisture_Limit = 65.0 state.Last_Event = ("Moisture Lim Set to %6.1f: " % state.Moisture_Limit)+time.strftime("%Y-%m-%d %H:%M:%S") finishStatementDisplay(display,list) OLEDLock.release() buttonPush = False
Works like a champ. Next up, the code for the combo Rotary Dial and Button input device.