This lesson will show you how to connect a tactile switch (button) to your Oak and use it to control a sketch. In the examples we will turn a LED on and off by pushing the button.
Part | Quantity | Identification |
---|---|---|
Oak with soldered *female* headers | 1 | |
Breadboard | 1 | |
5mm RGB Common Cathode LED | 1 | |
150R Resistor | 1 | Brown-Green-Brown |
10K Resistor | 1 | Brown-Black-Orange |
12mm Tactile Button | 1 |
[NOTE: You can find an index of the parts in the starter and ultimate kits here: Starter and Ultimate Kit Parts List]
Pull-Down Resistor: In this lesson we will use a Pull-Down resistor to make sure we can reliably detect button presses. If an I/O pin is 'left floating' reading it's value can result in either HIGH or LOW. By attaching a resistor between the I/O pin of the Oak and GND we can ensure that if the button is not pressed, the state is always LOW.
A pulldown configuration is shown on the left, with a floating circuit on the right (digital pin connection shown in blue, with Vcc
and ground in red/black, respectively):
Interrupt: A method to attach code (small functions!) to the state change of a pin. The supported triggers are:
In interrupt will interrupt anything the microcontroller is doing (even if it is in the middle of a function!) but will return after executing the interrupt handler. See some example of a good and a bad handleButtonPress() interrupt handler:
bool event_has_happened = false; void good_handleButtonPress() { //set a bool to true so we can handle it in loop() event_has_happened = true; } void bad_handleButtonPress() { // wait user to release button delay(500); //Handle the button press now so we won't forget it happened! call_another_slow_function(); }
1. Resistors To build up the circuit for this lesson, start with the resistors. As you can see, the resistors share a common pin. The 10K resistor (Brown-Black-Orange) is the pull-down resistor and the 150R resistor (Brown-Green-Brown) is used to limit the current sent to the LED. Connect the black wire as shown in the image to provide ground to the resistors.
2. LED After adding the resistors, you can add the LED. When connecting the LED, double-check the polarity. The shorter leg is the cathode (-) and the longer leg is the anode (+). Connect the cathode to the top (150 Ohm) resistor, and connect the anode to P2 of the Oak using a wire (the blue wire in the example).
3. Button As with the resistors, the button has no specific orientation, but it will connect its top two legs with the bottom two legs. In this example we connect VCC (3.3v) to the bottom-left leg of the button using a red wire. The top-left leg is connected to the pull-down resistor.
4. The final wire To read out the button state, a connection between P6 and the top-left pin of the button is required (shown in green in the example image).
That's it! You should now be able to test the circuit by uploading code to your Oak!
The simple mode allows you to check for the current button state and react accordingly. This example assumes Pin 6 for the button and Pin 2 for the LED. You can define these at the top section of your sketch like this:
#define BUTTON_PIN 6 #define LED_PIN 2
Because the Oak has to know how the pins will be used, you will have to set the pinMode as follows: This requires the following code in setup():
void setup() { pinMode(BUTTON_PIN, INPUT); pinMode(LED_PIN, OUTPUT); }
And to finish the sketch, use the following loop code:
void loop() { if(digitalRead(BUTTON_PIN) == HIGH) { digitalWrite(LED_PIN, HIGH); } else { digitalWrite(LED_PIN, LOW); } }
The code above will check the state of the BUTTON_PIN. If the state is LOW (which means: button pressed) the LED will turn on for as long as the button is pressed. Releasing the tactile switch turns the LED off again.
So getting the button to work isn't that hard, but what if you want to do other stuff in your loop as well? We can use interrupts for that! Start by adding the handle_button method to your sketch:
void handle_button() { bool btn_state = digitalRead(BUTTON_PIN); digitalWrite(LED_PIN, btn_state); }
For readability we first assign the current state to the bool state. If the button is pressed, the pin is perceived as HIGH (or: true). If the button is released, it is perceived as LOW (or: false). Then we set the LED to the current state of the button.
Then, replace line where you set the pin mode for BUTTON_PIN so that it looks like this:
void setup() { pinMode(LED_PIN, OUTPUT); attachInterrupt(digitalPinToInterrupt(BUTTON_PIN), handle_button, CHANGE); }
This assigns the handle_button function to the interrupt signal. Now because we're using the interrupt instead of polling, you can just keep the loop() empty, or do something else with it.
In this lesson you learned how to read a button state using digitalRead and attachInterrupt. Of course it doesn't have to stop at a single button, all digital I/O pins on the Oak can be used to handle interrupts!