Skip to content

Arduino - I/O Functions

The General-Purpose Input/Output (GPIO) pins are the bridge between your Arduino and the physical world. You can configure them to either read information from the environment (input) or to control devices (output). This chapter covers the essential functions for managing both digital and analog I/O.

Before you can use a pin, you must tell the Arduino its purpose. The pinMode() function, typically called within setup(), configures a specific pin to behave as an input or an output.

pinMode(pinNumber, mode);
  • pinNumber: The number of the pin you want to configure (e.g., 13, or A0).
  • mode: The mode to set. The three most common modes are:
    • INPUT: Configures the pin to read a signal, like from a sensor or a switch. The pin is in a high-impedance state, meaning it draws very little current.
    • OUTPUT: Configures the pin to send a signal, like lighting an LED or turning on a motor. The pin is in a low-impedance state, capable of supplying a significant current.
    • INPUT_PULLUP: A special input mode that enables a built-in pull-up resistor. This is extremely useful for reading switches without needing external components.

Digital I/O deals with discrete signals: on or off, 1 or 0, HIGH or LOW. On a 5V Arduino like the Uno, HIGH is 5V and LOW is 0V.

When a pin is configured as an OUTPUT, digitalWrite() sets it to either HIGH or LOW.

When a pin is configured as an INPUT or INPUT_PULLUP, digitalRead() returns its current state, either HIGH or LOW.

This complete sketch demonstrates how to use INPUT_PULLUP to read a button and control an LED. This is a foundational pattern in physical computing.

// This sketch reads a pushbutton on pin 2 and turns on an LED on pin 13
// when the button is pressed.
const int buttonPin = 2; // The pin the pushbutton is attached to
const int ledPin = 13; // The pin the LED is attached to
void setup() {
// Initialize the LED pin as an output
pinMode(ledPin, OUTPUT);
// Initialize the button pin as an input with a pull-up resistor
// When the button is NOT pressed, the pin reads HIGH.
// When the button IS pressed (connecting it to ground), the pin reads LOW.
pinMode(buttonPin, INPUT_PULLUP);
// Initialize serial communication for debugging purposes
Serial.begin(9600);
}
void loop() {
// Read the state of the button
int buttonState = digitalRead(buttonPin);
// Print the state to the Serial Monitor to see what's happening
Serial.println(buttonState);
// Check if the button is pressed. If it is, the state will be LOW.
if (buttonState == LOW) {
digitalWrite(ledPin, HIGH); // Turn the LED on
} else {
digitalWrite(ledPin, LOW); // Turn the LED off
}
}

Analog I/O: Working with a Range of Values

Section titled “Analog I/O: Working with a Range of Values”

While digital signals are on/off, analog signals can have any value within a range. This is essential for reading sensors that measure continuous values like temperature or light level.

This function reads the voltage on one of the analog input pins (A0, A1, etc.). The Arduino has a 10-bit Analog-to-Digital Converter (ADC), which maps input voltages between 0V and 5V into integer values between 0 and 1023.

Arduino boards cannot produce a true analog voltage output. Instead, they simulate it using Pulse-Width Modulation (PWM). analogWrite() rapidly switches a digital pin between HIGH and LOW. The value (from 0 to 255) determines the percentage of time the pin is HIGH (the duty cycle). This can be used to dim LEDs or control the speed of DC motors. Note: analogWrite() only works on pins marked with a tilde (~) symbol.

Example: Fading an LED with a Potentiometer

Section titled “Example: Fading an LED with a Potentiometer”
// This sketch fades an LED up and down using a potentiometer.
const int potPin = A0; // Analog pin for the potentiometer
const int ledPin = 9; // PWM pin for the LED (must have ~)
void setup() {
// No pinMode() is needed for analog inputs
pinMode(ledPin, OUTPUT);
Serial.begin(9600);
}
void loop() {
// 1. Read the potentiometer value (0 to 1023)
int sensorValue = analogRead(potPin);
Serial.print("Sensor = ");
Serial.print(sensorValue);
// 2. Map the 10-bit sensor value (0-1023) to the 8-bit PWM range (0-255)
int outputValue = map(sensorValue, 0, 1023, 0, 255);
Serial.print(", Output = ");
Serial.println(outputValue);
// 3. Write the mapped value to the PWM pin
analogWrite(ledPin, outputValue);
delay(20);
}
  • Floating Inputs: If you configure a pin as INPUT and don’t connect it to anything, it will ‘float’ and read random noise. Always use INPUT_PULLUP or an external pull-down resistor for switches.
  • Forgetting Resistors: Never connect an LED directly to an output pin without a current-limiting resistor (e.g., 220Ω). Doing so can burn out the LED or damage the Arduino pin.
  • High Current Loads: Arduino pins can only safely provide about 20mA of current. For devices like motors or relays that need more, you must use a transistor, MOSFET, or relay module to switch the higher current.