Classroom Public page

Week 8: Digital I/O

540 words

Reading buttons. Driving LEDs based on what the button says. By the end of the week you understand pinMode (INPUT vs OUTPUT vs INPUT_PULLUP), digitalRead, digitalWrite, and you have debounced a button in software.


Reading (~45 min)

  • The Arduino reference for pinMode, digitalRead, digitalWrite. Read all three pages
  • Optional: any "button debouncing" tutorial online; SparkFun's is clear

Lecture (~2 hr)

  • pinMode. Each pin is either input or output. INPUT_PULLUP is a special input mode that enables an internal pull-up resistor (saves you a part). digitalWrite on an INPUT pin does nothing useful; digitalRead on an OUTPUT pin gives garbage. Set the mode in setup(), once
  • Pull-up resistors. A pull-up resistor connects a pin to +5 V through a high-value resistor (~10 kΩ). When nothing is driving the pin, the pull-up keeps it at HIGH. When a switch shorts the pin to ground, the pin reads LOW. Without the pull-up, an unconnected pin "floats" and reads random values
  • Active-low logic. With a pull-up + a button to ground, the button reads LOW when pressed and HIGH when released. This is "active-low" sensing. Common; learn to read your code with this convention in mind
  • Debouncing. A real button does not switch cleanly. Over a few milliseconds it makes and breaks contact multiple times. Without debouncing, one press registers as several. The software fix: read the button; if it changed state, wait ~10 ms and read again. Only accept the change if the state is still different

Lab exercises (~2 hr)

Lab 8.1: Button Input. Wire a pushbutton to pin 2 with INPUT_PULLUP. Read it; print the state to the Serial Monitor (preview of next week). Add LED output: button pressed turns LED on, released turns it off. Then add debouncing. ~90 minutes.

Independent practice (~3 hr)

  • Wire two buttons. One toggles the LED on/off (state changes only on press, not on hold). The other turns it off regardless of state. This requires you to remember the previous button state across loop iterations
  • Build a "Simon Says" prototype: three LEDs, three buttons. The Arduino lights one LED at random; the player presses the matching button; if correct, the next round adds another light to the sequence. (Stretch project; takes most of an evening; saves you week 12 capstone-scoping time if you want to extend this into the capstone)
  • Read the Arduino source for digitalRead. Notice how thin the wrapper is; digital I/O ends up reading a hardware register. The "abstraction" is shallow on purpose; embedded code stays close to the hardware

Reflection prompts

  1. Without a pull-up resistor, an unconnected input pin reads random values. Why "random," specifically? What is the pin picking up?
  2. Debouncing in software takes a few lines of code. Debouncing in hardware would take a capacitor and a resistor. When would you choose hardware over software, or vice versa?
  3. INPUT_PULLUP saves you an external resistor. Why is the internal pull-up "approximately good enough" for buttons but not for analog sensing?

What's next

Week 9 makes input analog. Instead of "is the button pressed yes or no," the Arduino reads a continuous voltage from a sensor and gives you a number from 0 to 1023. The world goes from black-and-white to grayscale.