5.0 Essential Hardware Interaction: I/O Operations
The primary purpose of an Arduino is to interact with the physical world. It achieves this by reading data from sensors and controlling external components like LEDs, motors, and relays. This section covers the fundamental functions for configuring and controlling the board’s general-purpose input/output (GPIO) pins, which are the gateway between your code and your electronic circuits.
5.1 Pin Configuration and Digital I/O
By default, Arduino pins are configured as inputs, but they can be explicitly set as either inputs or outputs to suit the needs of your circuit.
- Pins Configured as INPUT When a pin is configured as an INPUT, it is said to be in a high-impedance state. This means it makes extremely small demands on the circuit it is sampling, equivalent to a 100 megaohm resistor. This high-impedance state makes the pin very sensitive to electrical noise. If a pin is left floating (unconnected), it may report seemingly random changes in state as it picks up ambient electrical noise.
- To solve this, pull-up resistors are often used to steer an input pin to a known state (HIGH) when no input is present. The ATmega chip on the Arduino has built-in 20kΩ pull-up resistors that can be enabled in software. To do this, configure the pin with pinMode(pin, INPUT_PULLUP). This inverts the pin’s behavior: it will read HIGH when the circuit is open and LOW when it is connected to ground.
- Pins Configured as OUTPUT When a pin is configured as an OUTPUT, it is in a low-impedance state, meaning it can provide a substantial amount of current to other circuits. ATmega pins can source (provide positive current) or sink (provide negative current) up to 40 mA. This is enough to brightly light an LED (with a series resistor) but is not sufficient to run high-current devices like motors or relays directly.
5.2 Core I/O Functions
Three core functions are used for most basic input and output operations.
This function configures a specific pin to behave as either an input or an output. It is typically called in the setup() function.
- Syntax:
- Parameters:
- pin: The number of the pin to configure.
- mode: Can be INPUT, OUTPUT, or INPUT_PULLUP.
This function writes a HIGH or a LOW value to a digital pin that has been configured as an OUTPUT.
- Syntax:
- Parameters:
- pin: The number of the pin to write to.
- value: HIGH (which corresponds to 5V or 3.3V, depending on the board) or LOW (0V).
This function reads the voltage on one of the analog input pins (A0-A5 on the UNO). The Arduino contains a 10-bit analog-to-digital converter (ADC), which maps input voltages between 0 and the operating voltage (5V or 3.3V) into integer values between 0 and 1023.
- Syntax:
- Parameters:
- pin: The number of the analog input pin to read from (e.g., A0, A1).
5.3 Pulse Width Modulation (PWM)
Pulse Width Modulation (PWM) is a powerful technique that allows you to generate a simulated analog output using a digital pin. It works by creating a square wave—a signal that switches between ON (HIGH) and OFF (LOW) at a fixed frequency—and varying the portion of time the signal spends in the ON state.
- On-Time: The duration the signal is high.
- Off-Time: The duration the signal is low.
- Period: The sum of the on-time and off-time.
- Duty Cycle: The percentage of the period that the signal is high. A 0% duty cycle is always off, a 100% duty cycle is always on, and a 50% duty cycle is high for half the period.
The analogWrite(pin, value) function is used to generate a PWM wave on specific pins, which are marked with a tilde (~) on most Arduino boards (e.g., pins 3, 5, 6, 9, 10, and 11 on the UNO; pins 2-13 and 44-46 on the Mega).
- Syntax:
- Parameters:
- pin: The PWM-capable pin to write to.
- value: The duty cycle, specified as an integer from 0 (0% duty cycle) to 255 (100% duty cycle).
5.4 Advanced I/O:
The analogReference() function configures the reference voltage used for analog inputs. This is the maximum voltage value that the analogRead() function will map to its top value of 1023.
- Available Reference Types:
- DEFAULT: The default analog reference of 5V (on 5V boards) or 3.3V (on 3.3V boards).
- INTERNAL: A built-in reference, equal to 1.1V on the ATmega328 (UNO) or 2.56V on the ATmega8.
- INTERNAL1V1: A built-in 1.1V reference (Arduino Mega only).
- INTERNAL2V56: A built-in 2.56V reference (Arduino Mega only).
- EXTERNAL: The voltage applied to the AREF pin (0 to 5V only) is used as the reference.
Critical Warning: If you are using an external reference on the AREF pin, you must call analogReference(EXTERNAL) before you call analogRead(). Otherwise, you will short the active internal reference voltage to the AREF pin, which can permanently damage the microcontroller.
Now that you can control the physical I/O pins, the next step is to explore the pre-built software libraries that simplify more complex tasks.