In this section, we will connect a button to a Raspberry Pi and use a GPIO input pin to read its state (pressed and not pressed); first using BlueJ interactively, then programatically by writing code in the Controller class.
For this experiment, you will need:
Connect the wires to the button as depicted in Figure 1:
Now connect the wires to the pins 1 (3.3V) and 7 (GPIO7) (Using the marks in Figure 2, below). A button, unlike an LED, is a component that has no polarity, i.e., it doesn't matter which wire you connect to which pin.
Note: If you have a Raspberry Pi model B+, you will have more than 26 pins. However, the assignment for those pins present on both models (B and B+) will still be the same as described here and the project should work without change.
Figure 3 shows the assembly (note: we removed the LED connections so you can see what we've done. You will need the LED connected for the next part of this project):
Just like the LED class, we first need to instantiate the Button class.
In order to do so, we first right-click on the Button class and from the pop-up menu, choose:
BlueJ will ask for the "name of the instance": the suggested name is good for now. You will see a red rectangle on the bottom left of the BlueJ window named "button1":
Right-click on the "button1" instance and select the "boolean isPressed()" method:
You should get a message saying that "button1.isPressed()" returned "false" (see Figure 8). Indeed, the button wasn't pressed when we called this method.
Find out what happens if you have the button pressed while calling the "boolean isPressed()" method.
We just learnt how to ask the button what is its current state. However, to keep actively asking the button object if it was being pressed is not very efficient and consumes precious processing power on the Raspberry Pi’s without doing much. This technique, where a device (button) is continuously being asked its status is known as 'polling'.
However, instead of polling the button state, there is a mechanism (common in Java and called a Listener) to have a method called whenever the button is pressed or released.
This mechanism has already been partly implemented in our project, with a method in the Controller called "void buttonChanged(boolean isPressed)". Whenever you create an instance of the Controller class, and the button is pressed (or released) this method is automatically called. The parameter "isPressed" tell us if the button has just been pressed (true) or released (false).
So, whenever we want to make the Controller class do something when the button is pressed, we just need to put this behaviour inside the buttonChanged method.
Tip: You may want to add a boolean variable in the Controller class to remember the current state of the LED.
Exercise 2.4: Reaction timer: Implement the method "int reactionTime()" in the Controller class and change the method "void buttonChange(boolean isPressed)" in order to make the led turn on after a random short delay and then measure the time until you press the button. Your reactionTime() method can then calculate and return the time difference between when the LED was turned on and when the button was pressed.
If a method called interactively by the user returns a value, then BlueJ will show this value to the user. Alternatively, your can also use System.out.println if you want to keep a record of the times. Compare your times with your friends and see who is faster in pressing the button.
You can use these two classes as a starting point for controlling other devices using GPIO input and output pins. For all the details of how they work and the way you can access them from Java, visit the Pi4J website and the Pi4J library documentation.