Entorno de hardware: Raspberry Pi 4 Modelo B Rev 1.5 · Debian 12 Bookworm · Kernel 6.12.25
Fecha de prueba: Abril de 2026
Autor: zeruns (https://blog.zeruns.com/)
Este artículo fue escrito por IA, solo para referencia (Hermes Agent + DeepSeek V4 Flash)
Tabla de contenido
- Conceptos básicos de GPIO
- Preparación del entorno y herramientas
- Entrada/salida GPIO (método Shell)
- Entrada/salida GPIO (método Python)
- Comunicación I2C
- Comunicación SPI
- Ejemplo combinado
- Precauciones y solución de problemas
1. Conceptos básicos de GPIO
1.1 ¿Qué es GPIO?
GPIO (General Purpose Input/Output, Entrada/Salida de Propósito General) es un conjunto de pines programables en un microprocesador. Mediante control por software, puedes configurar cada pin como:
- Modo salida: Emitir voltaje alto (3.3V) o bajo (0V), usado para controlar LED, relés, zumbadores, etc.
- Modo entrada: Leer el estado de voltaje externo (alto/bajo), usado para leer botones o señales de sensores
- Función alternativa: Protocolos especiales como I2C, SPI, UART, PWM, etc.
1.2 Disposición de pines del Raspberry Pi 4B
El Raspberry Pi 4B utiliza una cabecera de expansión de 40 pines, con tres formas comunes de numeración:
| Forma de numeración | Descripción | Biblioteca típica |
|---|---|---|
| Pin físico (Board) | Numerados del 1 al 40, comenzando en la esquina superior izquierda con el 1 | RPi.GPIO setmode(GPIO.BOARD) |
| Número BCM (Broadcom) | Numeración del chip GPIO, como GPIO17 | RPi.GPIO setmode(GPIO.BCM), libgpiod |
| Número wiringPi | Numeración personalizada (actualmente obsoleta) | Biblioteca wiringPi |
Diagrama funcional de los 40 pines
┌─────────────────────────────┐
│ 🥝 Diagrama de pines 40 del Raspberry Pi 4B │
3.3V (01) ──● ●── (02) 5V │
GPIO2 (03) ──● ●── (04) 5V │
GPIO3 (05) ──● ●── (06) GND │
GPIO4 (07) ──● ●── (08) GPIO14 (UART TX) │
GND (09) ──● ●── (10) GPIO15 (UART RX) │
GPIO17 (11) ──● ●── (12) GPIO18 (PWM0) │
GPIO27 (13) ──● ●── (14) GND │
GPIO22 (15) ──● ●── (16) GPIO23 │
3.3V (17) ──● ●── (18) GPIO24 │
GPIO10 (19) ──● ●── (20) GND (SPI_MOSI) │
GPIO9 (21) ──● ●── (22) GPIO25 (SPI_MISO) │
GPIO11 (23) ──● ●── (24) GPIO8 (SPI_SCLK) │
GND (25) ──● ●── (26) GPIO7 (SPI_CE0) │
GPIO0 (27) ──● ●── (28) GPIO1 (ID_SDA / I2C) │
GPIO5 (29) ──● ●── (30) GND │
GPIO6 (31) ──● ●── (32) GPIO12 (PWM0) │
GPIO13 (33) ──● ●── (34) GND │
GPIO19 (35) ──● ●── (36) GPIO16 │
GPIO26 (37) ──● ●── (38) GPIO20 │
GND (39) ──● ●── (40) GPIO21 │
└─────────────────────────────┘
Tabla funcional principal de pines Raspberry Pi 4B
| Pin físico | Número BCM | Función | Pin físico | Número BCM | Función |
|---|---|---|---|---|---|
| 1 | — | 3.3V | 2 | — | 5V |
| 3 | GPIO2 | I2C1 SDA | 4 | — | 5V |
| 5 | GPIO3 | I2C1 SCL | 6 | — | GND |
| 7 | GPIO4 | — | 8 | GPIO14 | UART TX |
| 9 | — | GND | 10 | GPIO15 | UART RX |
| 11 | GPIO17 | — | 12 | GPIO18 | PCM_CLK / PWM0 |
| 13 | GPIO27 | — | 14 | — | GND |
| 15 | GPIO22 | — | 16 | GPIO23 | — |
| 17 | — | 3.3V | 18 | GPIO24 | — |
| 19 | GPIO10 | SPI0 MOSI | 20 | — | GND |
| 21 | GPIO9 | SPI0 MISO | 22 | GPIO25 | — |
| 23 | GPIO11 | SPI0 SCLK | 24 | GPIO8 | SPI0 CE0 |
| 25 | — | GND | 26 | GPIO7 | SPI0 CE1 |
| 27 | GPIO0 | ID_SDA (EEPROM) | 28 | GPIO1 | ID_SCL (EEPROM) |
| 29 | GPIO5 | — | 30 | — | GND |
| 31 | GPIO6 | — | 32 | GPIO12 | PWM0 |
| 33 | GPIO13 | PWM1 | 34 | — | GND |
| 35 | GPIO19 | PCM_FS / PWM1 | 36 | GPIO16 | — |
| 37 | GPIO26 | — | 38 | GPIO20 | PCM_DIN |
| 39 | — | GND | 40 | GPIO21 | PCM_DOUT |
1.3 Notas importantes
- Nivel lógico: Los GPIO del Raspberry Pi funcionan a 3.3V, no pueden conectar directamente señales de 5V
- Límite de corriente: Cada GPIO puede entregar aproximadamente 16mA, y el total del conjunto no debe superar los 50mA
- Estado por defecto: La mayoría de los GPIO están en modo entrada por defecto, algunos tienen pull-up/pull-down internos
- Pines 3.3V (01/17): pueden entregar hasta unos 500mA
- Pines 5V (02/04): toman energía directamente del USB-C, su corriente depende del adaptador de alimentación
2. Preparación del entorno y herramientas
2.1 Lista de herramientas instaladas
Este tutorial fue probado en sistema Debian 12 Bookworm, las siguientes herramientas ya están preinstaladas:
| Herramienta/Biblioteca | Versión | Uso |
|---|---|---|
| libgpiod / gpioset / gpioget | 1.6.3 | Control GPIO mediante Shell |
| python3-libgpiod | 1.6.3 | Enlace Python para libgpiod |
| RPi.GPIO | 0.7.2 | Clásica biblioteca Python para GPIO |
| smbus2 | Instalado | Comunicación I2C en Python |
| spidev | Instalado | Comunicación SPI en Python |
| pigpiod | 1.79 | Demonio GPIO (PWM/control remoto) |
| i2c-tools | 4.3 | Herramienta para escanear dispositivos I2C |
2.2 Instalar herramientas necesarias
Si alguna herramienta falta, puedes instalarla con estos comandos:
# Herramientas básicas GPIO
sudo apt install gpiod libgpiod-dev python3-libgpiod
# Herramientas I2C
sudo apt install i2c-tools
# Bibliotecas Python
pip install RPi.GPIO smbus2 spidev gpiozero
# Demonio pigpio (PWM por hardware, recomendado)
sudo apt install pigpio pigpiod
sudo systemctl enable pigpiod --now
2.3 Activar interfaces I2C / SPI
Usa raspi-config para activarlas:
sudo raspi-config
Ruta en el menú:
Interface Options → I2C → Enable → Yes
Interface Options → SPI → Enable → Yes
O bien edita directamente el archivo /boot/firmware/config.txt (Debian 12):
# Agregar manualmente
sudo tee -a /boot/firmware/config.txt <<EOF
dtparam=i2cc_arm=on
dtparam=spi=on
EOF
# Reiniciar para aplicar los cambios
sudo reboot
Verificación de activación exitosa:
# Verificar I2C
ls /dev/i2c*
# Salida: /dev/i2c-20 /dev/i2c-21
# Verificar SPI (tras activarlo)
ls /dev/spi*
# Salida: /dev/spidev0.0 /dev/spidev0.1
2.4 Ver todos los gpiochip
$ gpioinfo
gpiochip0 - 58 líneas:
línea 0: "ID_SDA" no usado entrada activo-alto
línea 1: "ID_SCL" no usado entrada activo-alto
línea 2: "GPIO2" no usado entrada activo-alto
...
El chip BCM2711 del Raspberry Pi 4B proporciona un gpiochip0, con un total de 58 GPIO, pero solo GPIO0-GPIO27 están expuestos a través del conector de 40 pines.
3. Entrada y salida GPIO (mediante Shell)
3.1 Conjunto de herramientas libgpiod
Se recomienda usar las herramientas de libgpiod, que no dependen de wiringPi y representan la solución moderna actual.
Comandos principales:
| Comando | Función | Ejemplo |
|---|---|---|
gpioinfo |
Ver estado de todos los GPIO | gpioinfo |
gpioset |
Establecer nivel de salida GPIO | gpioset 0 17=1 |
gpioget |
Leer nivel de entrada GPIO | gpioget 0 17 |
gpiomon |
Escuchar eventos GPIO | gpiomon 0 17 |
Nota sobre formato: `gpioset =<vaChip generalmente es 0 (gpiochip0), y el pin utiliza la numeración BCM.
3.2 Salida: Encender un LED
Conecta el ánodo del LED (pata larga) a través de una resistencia de 330 Ω al GPIO17 (pin físico 11), y el cátodo (pata corta) a GND (pin físico 9).
# Establecer GPIO17 en alto → LED encendido
gpioset 0 17=1
# Establecer GPIO17 en bajo → LED apagado
gpioset 0 17=0
3.3 Entrada: Leer estado de un botón
Conecta un extremo del botón al GPIO18 (pin físico 12) y el otro extremo a GND (pin físico 14).
# Leer el nivel lógico de GPIO18 (requiere pull-up externa o activar pull-up interna)
gpioget 0 18
# Salida: 1 (no presionado, nivel alto)
# Salida: 0 (presionado, nivel bajo)
3.4 Ver estado de todos los pines
# Mostrar todos los pines
gpioinfo
# Mostrar un pin específico (número BCM 17)
gpioinfo | grep "GPIO17"
# Salida: line 17: "GPIO17" "myapp" output active-high
3.5 Configuración de pull-up/pull-down con gpioset
libgpiod 1.6 permite establecer polarización (bias) durante la solicitud:
# Configurar GPIO17 como salida, inicialmente alto, con pull-up activada
gpioset --bias=enable 0 17=1
4. Entrada/salida GPIO (método Python)
4.1 Usar RPi.GPIO (biblioteca clásica)
RPi.GPIO es la biblioteca Python más utilizada para GPIO, sencilla e intuitiva.
4.1.1 Salida: Parpadeo de LED
import RPi.GPIO as GPIO
import time
# Usar numeración BCM
GPIO.setmode(GPIO.BCM)
# Configurar GPIO17 como salida
GPIO.setup(17, GPIO.OUT)
# Parpadear el LED 5 veces
for _ in range(5):
GPIO.output(17, GPIO.HIGH) # Encender
time.sleep(0.5)
GPIO.output(17, GPIO.LOW) # Apagar
time.sleep(0.5)
# Liberar recursos
GPIO.cleanup()
4.1.2 Entrada: Leer botón
import RPi.GPIO as GPIO
import time
GPIO.setmode(GPIO.BCM)
# GPIO18 como entrada, con resistencia pull-up interna
GPIO.setup(18, GPIO.IN, pull_up_down=GPIO.PUD_UP)
try:
while True:
if GPIO.input(18) == GPIO.LOW:
print("Botón presionado")
else:
print("Botón liberado")
time.sleep(0.1)
except KeyboardInterrupt:
GPIO.cleanup()
GPIO.PUD_UP= pull-up interna (nivel alto por defecto, baja al presionar)
GPIO.PUD_DOWN= pull-down interna (nivel bajo por defecto, sube al presionar)
4.1.3 Salida PWM: Efecto respiración (breathing LED)
import RPi.GPIO as GPIO
import time
GPIO.setmode(GPIO.BCM)
GPIO.setup(18, GPIO.OUT) # GPIO18 soporta PWM por hardware
pwm = GPIO.PWM(18, 1000) # Frecuencia 1 kHz
pwm.start(0) # Ciclo de trabajo inicial 0%
try:
while True:
# Aumentar brillo
for duty in range(0, 101, 5):
pwm.ChangeDutyCycle(duty)
time.sleep(0.05)
# Disminuir brillo
for duty in range(100, -1, -5):
pwm.ChangeDutyCycle(duty)
time.sleep(0.05)
except KeyboardInterrupt:
pwm.stop()
GPIO.cleanup()
4.1.4 Detección por eventos: Lectura de botón por interrupción
import RPi.GPIO as GPIO
import time
GPIO.setmode(GPIO.BCM)
GPIO.setup(18, GPIO.IN, pull_up_down=GPIO.PUD_UP)
def button_callback(channel):
print(f"¡Botón presionado! (pin {channel})")
# Activar al flanco de bajada
GPIO.add_event_detect(18, GPIO.FALLING,
callback=button_callback,
bouncetime=200)
try:
print("Esperando presión del botón...")
time.sleep(60)
except KeyboardInterrupt:
GPIO.cleanup()
4.2 Usar gpiozero (envoltorio avanzado)
gpiozero ofrece una encapsulación orientada a objetos más avanzada, ideal para desarrollo rápido:
# Instalar
pip install gpiozero
from gpiozero import LED, Button, Buzzer
from signal import pause
# LED: parpadeo automático
led = LED(17)
led.blink()
# Botón: encender LED al presionar
btn = Button(18, pull_up=True)
# Método 1: asignación directa
btn.when_pressed = led.on
btn.when_released = led.off
# Método 2: función de devolución personalizada
btn.when_pressed = lambda: print("¡Presionado!")
# Mantener en ejecución
pause()
Componentes integrados en gpiozero:
| Componente | Clase | Descripción |
|---|---|---|
| LED | LED(pin) |
Controlar encendido/parpadeo/efecto respiración |
| Botón | Button(pin, pull_up=True) |
Leer botón, detectar pulsación larga |
| Zumbador | Buzzer(pin) |
Control de zumbador activo |
| Sensor de distancia | DistanceSensor(echo, trigger) |
Sensor ultrasónico HC-SR04 |
| Servomotor | Servo(pin) |
Controlar ángulo del servomotor |
| Motor | Motor(forward, backward) |
Controlar motor DC |
4.3 Usar el enlace Python de libgpiod (operación de bajo nivel)
import gpiod
import time
# Abrir gpiochip0
chip = gpiod.Chip('gpiochip0')
# Obtener GPIO17 y solicitar como salida
line = chip.get_line(17)
line.request(consumer='myapp', type=gpiod.LINE_REQ_DIR_OUT)
# Establecer alto
line.set_value(1)
time.sleep(1)
# Establecer bajo
line.set_value(0)
# Liberar
line.release()
Modo entrada:
import gpiod
chip = gpiod.Chip('gpiochip0')
line = chip.get_line(18)
# Solicitar como entrada con pull-up interna
line.request(consumer='myapp',
type=gpiod.LINE_REQ_DIR_IN,
flags=gpiod.LINE_REQ_FLAG_BIAS_PULL_UP)
value = line.get_value() # 0 o 1
print(f"GPIO18 = {value}")
line.release()
5. Comunicación I2C
5.1 Principios básicos de I2C
I2C (Inter-Integrated Circuit) es un bus de comunicación serial que utiliza dos líneas:
| Señal | Pin | Función |
|---|---|---|
| SCL | GPIO3 (pin físico 5) | Línea de reloj |
| SDA | GPIO2 (pin físico 3) | Línea de datos |
Características:
- Arquitectura maestro-esclavo: Raspberry Pi es el maestro (Master), sensores u otros dispositivos son esclavos (Slave)
- Dirección de 7 bits: Cada esclavo tiene una dirección única (por ejemplo, 0x44)
- Compartición de dispositivos: Múltiples dispositivos en un mismo bus I2C
- Velocidad: Estándar 100 kHz, rápido 400 kHz
5.2 Ver buses I2C disponibles
# Listar buses I2C
$ i2cdetect -l
i2c-20 i2c bcm2711_i2c1 I2C adapter
i2c-21 i2c bcm2711_i2c0 I2C adapter
i2c-20: Corresponde a los pines físicos 3(SDA)/5(SCL) — bus I2C principali2c-21: Corresponde a ID_EEPROM (pines 27/28), generalmente no se utiliza para dispositivos externos
5.3 Escanear dispositivos I2C
# Escanear dispositivos en i2c-20
$ i2cdetect -y 20
0 1 2 3 4 5 6 7 8 9 a b c d e f
00: -- -- -- -- -- -- -- --
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
40: -- 44 -- -- -- -- -- -- -- -- -- -- -- -- -- --
50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
70: -- -- -- -- -- -- -- --
Existe un dispositivo en la dirección
0x44— este es el sensor de temperatura y humedad SHT30 (dirección I2C 0x44).
Si no aparece ningún dispositivo (todo muestra --), significa que no hay dispositivos conectados en el bus.
5.4 Lectura/escritura I2C con smbus2
smbus2 es la biblioteca Python más común para operaciones I2C.
5.4.1 Leer sensor SHT30 de temperatura y humedad
import smbus2
import time
# Dirección I2C del SHT30
SHT30_ADDR = 0x44
# Abrir el bus I2C 20
bus = smbus2.SMBus(20)
# Enviar comando de medición: modo alta precisión
bus.write_i2c_block_data(SHT30_ADDR, 0x2C, [0x06])
time.sleep(0.015) # Esperar finalización de medición (15 ms)
# Leer 6 bytes de datos
data = bus.read_i2c_block_data(SHT30_ADDR, 0x00, 6)
# Calcular temperatura y humedad
temp_raw = ((data[0] << 8) | data[1])
temp = -45 + 175 * temp_raw / 65535.0
hum_raw = ((data[3] << 8) | data[4])
hum = 100 * hum_raw / 65535.0
print(f"Temperatura: {temp:.2f}°C")
print(f"Humedad: {hum:.2f}%")
5.4.2 Empaquetar en función
import smbus2
import time
class SHT30:
def __init__(self, bus_id=20, addr=0x44):
self.bus = smbus2.SMBus(bus_id)
self.addr = addr
def read(self):
"""Leer temperatura y humedad, devuelve (temp en °C, hum en %)"""
self.bus.write_i2c_block_data(self.addr, 0x2C, [0x06])
time.sleep(0.015)
data = self.bus.read_i2c_block_data(self.addr, 0x00, 6)
temp_raw = (data[0] << 8) | data[1]
temp = -45 + 175 * temp_raw / 65535.0
hum_raw = (data[3] << 8) | data[4]
hum = 100 * hum_raw / 65535.0
return round(temp, 2), round(hum, 2)
# Uso
development = SHT30()
t, h = sensor.read()
print(f"{t}°C, {h}%RH")
5.4.3 Operaciones genéricas de lectura/escritura I2C
import smbus2
bus = smbus2.SMBus(20)
addr = 0x44 # Dirección I2C del dispositivo
# Escribir un byte en un registro
bus.write_byte_data(addr, 0x2C, 0x06)
# Leer un byte
value = bus.read_byte_data(addr, 0x00)
# Leer múltiples bytes
data = bus.read_i2c_block_data(addr, 0x00, 6)
# Escribir múltiples bytes
bus.write_i2c_block_data(addr, 0x2C, [0x06])
# Escribir un byte (sin registro)
bus.write_byte(addr, 0x06)
# Leer un byte (sin registro)
value = bus.read_byte(addr)
bus.close()
5.5 Uso de comandos i2cget / i2cset
# Leer registro de estado del SHT30 (1 byte)
$ i2cget -y 20 0x44 0x00
0x65
# Leer 6 bytes de datos brutos
$ i2cget -y 20 0x44 0x00 b 6
6. Comunicación SPI
6.1 Principios básicos de SPI
SPI (Serial Peripheral Interface) es un bus serial síncrono dúplex completo que utiliza cuatro líneas:
| Señal | Pin Raspberry Pi | Función |
|---|---|---|
| MOSI | GPIO10 (pin físico 19) | Salida del maestro, entrada del esclavo |
| MISO | GPIO9 (pin físico 21) | Entrada del maestro, salida del esclavo |
| SCLK | GPIO11 (pin físico 23) | Señal de reloj |
| CE0 | GPIO8 (pin físico 24) | Selección de chip 0 |
| CE1 | GPIO7 (pin físico 26) | Selección de chip 1 |
Características:
- Dúplex completo: transmisión y recepción simultáneas
- Maestro-esclavo: Raspberry Pi es el maestro, puede tener múltiples esclavos (uno por CE)
- Alta velocidad: puede alcanzar decenas de MHz
- Sin direcciones: el esclavo se selecciona mediante la línea CE (chip select)
6.2 Activar SPI y verificar
# Tras activar SPI
$ ls /dev/spi*
/dev/spidev0.0 /dev/spidev0.1
/dev/spidev0.0: Bus SPI0, CE0/dev/spidev0.1: Bus SPI0, CE1
6.3 Lectura/escritura SPI con spidev
pip install spidev
6.3.1 Leer MCP3008 ADC (Convertidor Analógico-Digital de 8 canales)
import spidev
# Abrir SPI
spi = spidev.SpiDev()
spi
#### 6.3.2 Transmisión y recepción de datos SPI genérica
```python
import spidev
spi = spidev.SpiDev()
spi.open(0, 0)
spi.max_speed_hz = 500000
spi.mode = 0
# Enviar y recibir (dúplex completo, enviar 0xFF y leer al mismo tiempo)
data_out = [0xFF, 0x00, 0x55]
data_in = spi.xfer2(data_out) # Enviar 3 bytes, recibir 3 bytes
print(f"Enviado: {[hex(x) for x in data_out]}")
print(f"Recibido: {[hex(x) for x in data_in]}")
# Solo enviar (ignorar resultado recibido)
spi.writebytes([0x01, 0x02, 0x03])
spi.close()
7. Ejemplos prácticos
7.1 Ejemplo 1: Luz de respiración LED + control por botón
import RPi.GPIO as GPIO
import time
GPIO.setmode(GPIO.BCM)
LED_PIN = 17 # BCM 17
BTN_PIN = 18 # BCM 18
GPIO.setup(LED_PIN, GPIO.OUT)
GPIO.setup(BTN_PIN, GPIO.IN, pull_up_down=GPIO.PUD_UP)
pwm = GPIO.PWM(LED_PIN, 500)
pwm.start(0)
running = True # Estado del LED
try:
while True:
if GPIO.input(BTN_PIN) == GPIO.LOW:
running = not running
time.sleep(0.3) # Anti-rebote
if running:
# Efecto respiración
for duty in range(0, 101, 2):
pwm.ChangeDutyCycle(duty)
time.sleep(0.01)
for duty in range(100, -1, -2):
pwm.ChangeDutyCycle(duty)
time.sleep(0.01)
else:
pwm.ChangeDutyCycle(0)
except KeyboardInterrupt:
pwm.stop()
GPIO.cleanup()
7.2 Ejemplo 2: Lectura de temperatura y humedad SHT30 + registro automático
import smbus2
import time
import csv
from datetime import datetime
class SHT30:
def __init__(self, bus_id=20, addr=0x44):
self.bus = smbus2.SMBus(bus_id)
self.addr = addr
def read(self):
self.bus.write_i2c_block_data(self.addr, 0x2C, [0x06])
time.sleep(0.015)
data = self.bus.read_i2c_block_data(self.addr, 0x00, 6)
t = -45 + 175 * ((data[0] << 8) | data[1]) / 65535.0
h = 100 * ((data[3] << 8) | data[4]) / 65535.0
return round(t, 2), round(h, 2)
sensor = SHT30()
# Prueba de lectura
t, h = sensor.read()
print(f"[{datetime.now()}] Temperatura: {t}°C, Humedad: {h}%")
# Registro continuo en CSV (una vez por minuto)
with open('sensor_log.csv', 'w', newline='') as f:
writer = csv.writer(f)
writer.writerow(['Tiempo', 'Temperatura (°C)', 'Humedad (%)'])
for i in range(10): # Registrar 10 veces
t, h = sensor.read()
now = datetime.now().strftime('%H:%M:%S')
writer.writerow([now, t, h])
print(f"[{now}] {t}°C, {h}%")
time.sleep(60)
7.3 Ejemplo 3: gpiozero en un solo paso
from gpiozero import LED, Button
from signal import pause
import time
led = LED(17)
btn = Button(18, pull_up=True)
# Encender al presionar, apagar al soltar
btn.when_pressed = led.on
btn.when_released = led.off
# Doble clic para activar modo parpadeo
press_count = 0
def double_click():
global press_count
press_count += 1
time.sleep(0.3)
if press_count == 2:
led.blink()
print("¡Doble clic! Modo parpadeo activado")
press_count = 0
btn.when_pressed = double_click
pause()
8. Precauciones y solución de problemas
8.1 Conversión de niveles lógicos (3.3V vs 5V)
Los GPIO del Raspberry Pi usan lógica de 3.3V; ¡nunca conectes directamente dispositivos de 5V!
| Escenario | Solución |
|---|---|
| Salida de sensor 5V → entrada Raspberry Pi | Usar módulo convertidor de niveles (ej: TXS0108E) o divisor resistivo |
| Salida Raspberry Pi → entrada dispositivo 5V | Algunos dispositivos 5V aceptan 3.3V como nivel alto (ej: WS2812B) |
| Sensor 3.3V → Raspberry Pi | Conexión directa |
Divisor resistivo (5V → 3.3V):
5V ──┬── R1 (1.8kΩ) ──┬── GPIO del Raspberry Pi
│ │
GND ── R2 (3.3kΩ) ─┘
8.2 Resistencias de pull-up / pull-down
- Pull-up interna: En RPi.GPIO usar
pull_up_down=GPIO.PUD_UP - Pull-down interna: En RPi.GPIO usar
pull_up_down=GPIO.PUD_DOWN - En libgpiod:
gpiod.LINE_REQ_FLAG_BIAS_PULL_UP - Pull-up externa: Resistencia de 4.7kΩ ~ 10kΩ a 3.3V
8.3 Límites de corriente
| Parámetro | Límite |
|---|---|
| Corriente máxima por GPIO | 16mA |
| Total en todos los GPIO | 50mA |
| Corriente total en pines 3.3V | ~500mA |
| Corriente total en pines 5V | Depende de la fuente |
Al conectar un LED directamente, siempre usar una resistencia limitadora de 220Ω ~ 330Ω en serie.
8.4 Errores comunes
| Error | Causa | Solución |
|---|---|---|
RuntimeError: No access to /dev/mem |
Falta de permisos | sudo python3 script.py |
RuntimeError: Pin already in use |
Pin ya usado por otro programa | Verificar /sys/class/gpio/, liberar o reiniciar |
[Errno 13] Permission denied + i2c |
I2C no habilitado o sin permisos | Añadir usuario al grupo i2c |
Could not open /dev/spidev0.0 |
SPI no habilitado | Comprobar /boot/config.txt |
| LED no enciende | Polaridad invertida | Conectar pin largo del LED al GPIO, pin corto a GND |
| Botón se activa erróneamente | Sin anti-rebote | Añadir bouncetime o retardo en código |
8.5 Configuración de permisos
# Añadir usuario actual a los grupos i2c y gpio
sudo usermod -aG i2c,gpio $USER
# Cerrar y volver a abrir sesión para aplicar
echo su - $USER
8.6 Referencias online rápidas
- Documentación oficial GPIO del Raspberry Pi
- Documentación RPi.GPIO
- Documentación gpiozero
- Documentación libgpiod
Autor: zeruns
Este tutorial fue verificado en un Raspberry Pi 4B con Debian 12 Bookworm