Understanding Digital Inputs and Outputs with Arduino
🎯 Learning Focus: Digital pins, LEDs, buttons, and basic control
Now that you have your Arduino hardware, it's time to install the Arduino IDE (Integrated Development Environment) - the software we'll use to write and upload programs to your Arduino board.
arduino.cc/software and download the Arduino IDEDigital signals have only two states: HIGH (5V) and LOW (0V). This binary nature makes them perfect for controlling devices like LEDs, motors, and relays.
pinMode(pin, OUTPUT) - Configure pin as outputdigitalWrite(pin, HIGH) - Set pin to 5VdigitalWrite(pin, LOW) - Set pin to 0VLet's start with the classic "Hello World" of electronics - blinking an LED.
// Basic LED Blink Program
const int ledPin = 13;
void setup() {
pinMode(ledPin, OUTPUT);
Serial.begin(9600);
Serial.println("LED Blink Program Started");
}
void loop() {
digitalWrite(ledPin, HIGH); // Turn LED on
Serial.println("LED ON");
delay(1000); // Wait 1 second
digitalWrite(ledPin, LOW); // Turn LED off
Serial.println("LED OFF");
delay(1000); // Wait 1 second
} Digital inputs allow us to read the state of switches, buttons, and sensors. The Arduino can detect whether a pin is HIGH or LOW.
pinMode(pin, INPUT) - Configure pin as inputpinMode(pin, INPUT_PULLUP) - Input with internal pull-updigitalRead(pin) - Read pin state (HIGH/LOW)Pull-up resistors ensure that input pins have a defined state when not connected to anything. Arduino has built-in pull-up resistors we can enable.
// Button Input with Pull-up Resistor
const int buttonPin = 2;
const int ledPin = 13;
void setup() {
pinMode(buttonPin, INPUT_PULLUP); // Enable internal pull-up
pinMode(ledPin, OUTPUT);
Serial.begin(9600);
Serial.println("Button Input Program Started");
}
void loop() {
int buttonState = digitalRead(buttonPin);
if (buttonState == LOW) { // Button pressed (pull-up inverts logic)
digitalWrite(ledPin, HIGH);
Serial.println("Button Pressed - LED ON");
} else {
digitalWrite(ledPin, LOW);
Serial.println("Button Released - LED OFF");
}
delay(50); // Debounce delay
} A breadboard is a reusable platform for building electronic circuits without soldering. It makes connecting components to your Arduino much easier!
Clean breadboard ready for components
💡 Why INPUT_PULLUP works: This mode connects an internal 20kΩ resistor between the pin and 5V. When the button is pressed, it connects the pin to ground (LOW). When released, the pull-up resistor keeps the pin at 5V (HIGH).
Note: The built-in button on the expansion board is connected to reset, not pin 2, so we need an external button for this exercise.
Push button connected to pin 2 with breadboard wiring
Now let's create more interactive programs that respond to user input and control multiple outputs.
// Toggle LED with Button Press
const int buttonPin = 2;
const int ledPin = 13;
bool ledState = false;
bool lastButtonState = HIGH;
bool currentButtonState = HIGH;
void setup() {
pinMode(buttonPin, INPUT_PULLUP);
pinMode(ledPin, OUTPUT);
Serial.begin(9600);
Serial.println("LED Toggle Program Started");
}
void loop() {
currentButtonState = digitalRead(buttonPin);
// Check for button press (HIGH to LOW transition)
if (lastButtonState == HIGH && currentButtonState == LOW) {
ledState = !ledState; // Toggle LED state
digitalWrite(ledPin, ledState);
if (ledState) {
Serial.println("LED Toggled ON");
} else {
Serial.println("LED Toggled OFF");
}
delay(50); // Simple debounce
}
lastButtonState = currentButtonState;
} Let's create more complex patterns using multiple LEDs and timing.
💡 LED Polarity: LEDs have polarity - the long leg (anode) connects to the positive side through a resistor, and the short leg (cathode) connects to ground.
⚡ Why 220Ω resistors: These limit current to protect the LEDs from burning out. Each LED needs its own resistor.
Traffic light LEDs with control buttons - complete interactive setup
// Traffic Light Simulator
const int redPin = 11;
const int yellowPin = 12;
const int greenPin = 13;
const int buttonPin = 2;
void setup() {
pinMode(redPin, OUTPUT);
pinMode(yellowPin, OUTPUT);
pinMode(greenPin, OUTPUT);
pinMode(buttonPin, INPUT_PULLUP);
Serial.begin(9600);
Serial.println("Traffic Light Simulator Started");
}
void loop() {
// Green light
digitalWrite(greenPin, HIGH);
digitalWrite(yellowPin, LOW);
digitalWrite(redPin, LOW);
Serial.println("GREEN - Go!");
delay(3000);
// Yellow light
digitalWrite(greenPin, LOW);
digitalWrite(yellowPin, HIGH);
digitalWrite(redPin, LOW);
Serial.println("YELLOW - Caution!");
delay(1000);
// Red light
digitalWrite(greenPin, LOW);
digitalWrite(yellowPin, LOW);
digitalWrite(redPin, HIGH);
Serial.println("RED - Stop!");
delay(3000);
} Create an interactive control panel with multiple buttons and LEDs that demonstrates digital I/O concepts.
// Control Panel Challenge Solution
const int redPin = 11;
const int yellowPin = 12;
const int greenPin = 13;
const int button1Pin = 2;
const int button2Pin = 3;
int currentLED = 0; // 0=red, 1=yellow, 2=green
bool blinkMode = false;
bool lastButton1State = HIGH;
bool lastButton2State = HIGH;
void setup() {
pinMode(redPin, OUTPUT);
pinMode(yellowPin, OUTPUT);
pinMode(greenPin, OUTPUT);
pinMode(button1Pin, INPUT_PULLUP);
pinMode(button2Pin, INPUT_PULLUP);
Serial.begin(9600);
Serial.println("Control Panel Ready!");
}
void loop() {
// Check button 1 for LED cycling
bool button1State = digitalRead(button1Pin);
if (lastButton1State == HIGH && button1State == LOW) {
currentLED = (currentLED + 1) % 3;
Serial.print("Switched to LED: ");
Serial.println(currentLED);
delay(50); // Debounce
}
lastButton1State = button1State;
// Check button 2 for blink mode
bool button2State = digitalRead(button2Pin);
if (lastButton2State == HIGH && button2State == LOW) {
blinkMode = !blinkMode;
Serial.print("Blink mode: ");
Serial.println(blinkMode ? "ON" : "OFF");
delay(50); // Debounce
}
lastButton2State = button2State;
// Control LEDs
updateLEDs();
}
void updateLEDs() {
// Turn off all LEDs first
digitalWrite(redPin, LOW);
digitalWrite(yellowPin, LOW);
digitalWrite(greenPin, LOW);
// Turn on current LED
if (blinkMode && (millis() % 500 < 250)) {
// Blink current LED
switch(currentLED) {
case 0: digitalWrite(redPin, HIGH); break;
case 1: digitalWrite(yellowPin, HIGH); break;
case 2: digitalWrite(greenPin, HIGH); break;
}
} else if (!blinkMode) {
// Solid current LED
switch(currentLED) {
case 0: digitalWrite(redPin, HIGH); break;
case 1: digitalWrite(yellowPin, HIGH); break;
case 2: digitalWrite(greenPin, HIGH); break;
}
}
}