How do I use GPIO pins?

 Using GPIO (General-Purpose Input/Output) pins is fundamental in embedded systems and microcontroller projects. Below is a step-by-step guide on how to use them for both input and output operations, with examples for popular platforms like Arduino, ESP32, and Raspberry Pi.




1. Understanding GPIO Basics

  • GPIO pins can be configured as:

    • Digital Input (read a button or sensor).

    • Digital Output (control an LED or relay).

    • Analog Input (read sensors like potentiometers, ADC required).

    • PWM Output (dim LEDs, control servo motors).

    • Special Functions (I2C, SPI, UART for communication).


2. Setting Up GPIO Pins

A. Arduino (AVR/ARM)

Digital Output (Control an LED)

cpp
void setup() {
  pinMode(13, OUTPUT);  // Set pin 13 as output
}

void loop() {
  digitalWrite(13, HIGH);  // Turn LED ON
  delay(1000);
  digitalWrite(13, LOW);   // Turn LED OFF
  delay(1000);
}

Digital Input (Read a Button)

cpp
void setup() {
  pinMode(2, INPUT_PULLUP);  // Enable internal pull-up resistor
  Serial.begin(9600);
}

void loop() {
  int buttonState = digitalRead(2);
  Serial.println(buttonState);  // Prints 1 (HIGH) when open, 0 (LOW) when pressed
  delay(100);
}

Analog Input (Read a Potentiometer)

cpp
void setup() {
  Serial.begin(9600);
}

void loop() {
  int sensorValue = analogRead(A0);  // Read from analog pin A0
  Serial.println(sensorValue);       // Value between 0-1023 (10-bit ADC)
  delay(100);
}

PWM Output (Dim an LED)

cpp
void setup() {
  pinMode(9, OUTPUT);  // PWM-capable pin (~)
}

void loop() {
  analogWrite(9, 128);  // 50% duty cycle (0-255)
  delay(1000);
}

B. ESP32 (Wi-Fi/BLE Microcontroller)

Digital Output (Blink an LED)

cpp
void setup() {
  pinMode(2, OUTPUT);  // Built-in LED on ESP32 DevKit
}

void loop() {
  digitalWrite(2, HIGH);
  delay(500);
  digitalWrite(2, LOW);
  delay(500);
}

Analog Input (ESP32 has 12-bit ADC)

cpp
void setup() {
  Serial.begin(115200);
}

void loop() {
  int sensorValue = analogRead(34);  // Use GPIO34 (ADC1_CH6)
  Serial.println(sensorValue);       // 0-4095 (12-bit resolution)
  delay(100);
}

PWM (LEDC Library for ESP32)

cpp
const int ledPin = 2;  // GPIO2
const int freq = 5000; // PWM frequency
const int channel = 0; // PWM channel (0-15)
const int resolution = 8; // 8-bit (0-255)

void setup() {
  ledcSetup(channel, freq, resolution);
  ledcAttachPin(ledPin, channel);
}

void loop() {
  for (int dutyCycle = 0; dutyCycle <= 255; dutyCycle++) {
    ledcWrite(channel, dutyCycle);  // Fade LED
    delay(10);
  }
}

C. Raspberry Pi (Linux SBC)

Using Python (RPi.GPIO Library)

Digital Output (Blink an LED)

python
import RPi.GPIO as GPIO
import time

GPIO.setmode(GPIO.BCM)  # Use Broadcom pin numbering
GPIO.setup(17, GPIO.OUT)  # GPIO17 as output

try:
    while True:
        GPIO.output(17, GPIO.HIGH)  # LED ON
        time.sleep(1)
        GPIO.output(17, GPIO.LOW)   # LED OFF
        time.sleep(1)
except KeyboardInterrupt:
    GPIO.cleanup()  # Reset GPIO

Digital Input (Read a Button)

python
import RPi.GPIO as GPIO
import time

GPIO.setmode(GPIO.BCM)
GPIO.setup(27, GPIO.IN, pull_up_down=GPIO.PUD_UP)  # Enable pull-up

try:
    while True:
        if GPIO.input(27) == GPIO.LOW:
            print("Button Pressed!")
        time.sleep(0.1)
except KeyboardInterrupt:
    GPIO.cleanup()

PWM (Software PWM on Raspberry Pi)

python
import RPi.GPIO as GPIO
import time

GPIO.setmode(GPIO.BCM)
GPIO.setup(18, GPIO.OUT)

pwm = GPIO.PWM(18, 1000)  # 1kHz frequency
pwm.start(50)  # 50% duty cycle

try:
    while True:
        pass
except KeyboardInterrupt:
    pwm.stop()
    GPIO.cleanup()

3. Common Mistakes & Fixes

IssueSolution
LED not lighting upCheck polarity (long leg = anode)
Button always reads HIGH/LOWUse INPUT_PULLUP or external resistor
Analog readings noisyAdd a capacitor (0.1µF) between sensor and GND
PWM not workingEnsure the pin supports PWM (marked with ~ on Arduino)
ESP32 ADC inaccurateUse analogReadMilliVolts() for better precision

4. Advanced GPIO Uses

  • Interrupts (trigger actions on button press without polling).

  • Multiplexing (drive many LEDs with fewer pins).

  • Bit-banging protocols (custom I2C/SPI/UART if hardware peripherals are unavailable).


Final Tips

  • Always check pinout diagrams (e.g., Arduino Uno vs. ESP32).

  • Use logic level shifters when interfacing 3.3V and 5V devices.

  • For high-current loads (motors, relays), use a transistor/MOSFET driver.

评论

此博客中的热门博文

How To Connect Stm32 To PC?

How do you set up ADC (Analog-to-Digital Converter) in STM32?

What are the common HDL languages used in FPGA design?