Configuración del entorno de desarrollo
Para comenzar a trabajar con el núcleo Arduino-Pico en el RP2040 o RP2350, es necesario configurar el IDE de Arduino. Accede a las preferencias y añade la URL del gestor de placas correspondiente. Una vez actualizado el índice, instala el paquete "Raspberry Pi Pico/RP2040" desde el gestor de placas.
Tras la instalación, selecciona tu modelo específico de placa (Pico, Pico W, o variantes RP2350) y el puerto de comunicación adecuado.
Arquitectura de pines GPIO del RP2040
El microcontrolador RP2040 dispone de 26 pines GPIO multifunción, cada uno configurable hasta en 5 modos alternativos. Esta flexibliidad permite asignar periféricos (UART, SPI, I2C, PWM) a diferentes pines físicos según las necesidades del diseño.
| Pin | Función 0 | Función 1 | Función 2 | Función 3 | Función 4 |
|---|---|---|---|---|---|
| GPIO0 | SPI0 RX | UART0 TX | I2C0 SDA | PWM0 A | SIO |
| GPIO1 | SPI0 CSn | UART0 RX | I2C0 SCL | PWM0 B | SIO |
| GPIO26-29 | ADC | SPI1 | I2C1 | PWM | SIO |
Manejo de señales digitales
Configuración de modos de operación
La función pinMode() admite configuraciones avanzadas de resistencia interna y capacidad de corriente:
// Modos de entrada
pinMode(PIN_ENTRADA, INPUT); // Alta impedancia
pinMode(PIN_ENTRADA, INPUT_PULLUP); // Resistencia pull-up interna (~50kΩ)
pinMode(PIN_ENTRADA, INPUT_PULLDOWN); // Resistencia pull-down interna (~50kΩ)
// Modos de salida con control de corriente
pinMode(PIN_SALIDA, OUTPUT); // Corriente por defecto (4mA)
pinMode(PIN_SALIDA, OUTPUT_2MA); // Bajo consumo
pinMode(PIN_SALIDA, OUTPUT_4MA); // Estándar
pinMode(PIN_SALIDA, OUTPUT_8MA); // Alta capacidad
pinMode(PIN_SALIDA, OUTPUT_12MA); // Máxima capacidad
Operaciones de lectura y escritura
// Control de salida
digitalWrite(PIN_RELE, HIGH); // Activar relé
digitalWrite(PIN_RELE, LOW); // Desactivar relé
// Lectura de entrada
bool estado_pulsador = digitalRead(PIN_PULSADOR);
Sistema de interrupciones externas
Todos los pines GPIO del RP2040 pueden generar interrupciones, con detección de flancos configurable a nivel de hardware.
Implementación básica de interrupciones
// Variable volatile para comunicación ISR-loop
volatile bool evento_detectado = false;
uint32_t contador_eventos = 0;
void manejadorInterrupcion() {
// Operación mínima: solo activar bandera
evento_detectado = true;
}
void configuracion() {
Serial.begin(115200);
pinMode(PIN_SENSOR, INPUT_PULLUP);
// Asociar función a interrupción
attachInterrupt(
digitalPinToInterrupt(PIN_SENSOR),
manejadorInterrupcion,
FALLING // Disparo en flanco descendente
);
}
void cicloPrincipal() {
if (evento_detectado) {
evento_detectado = false;
contador_eventos++;
Serial.printf("Evento #%lu detectado\n", contador_eventos);
}
}
Modos de disparo disponibles
RISING: Flanco ascendente (0 → 1)FALLING: Flanco descendente (1 → 0)CHANGE: Cualquier transición de nivelLOW: Nivel bajo sostenido (limitado a ciertos pines)HIGH: Nivel alto sostenido (limitado a ciertos pines)
Conversión analógica-digital (ADC)
El RP2040 integra un ADC de 12 bits con cinco canales: cuatro externos (GPIO26-29) y un canal dedicado al sensor de temperatura interno.
Configuración y lectura del ADC
// Precisión configurable
analogReadResolution(12); // Rango 0-4095 (resolución nativa)
analogReadResolution(10); // Rango 0-1023 (compatibilidad Arduino)
// Lectura con conversión a voltaje
uint16_t valor_crudo = analogRead(CANAL_LUZ);
float voltaje = valor_crudo * 3.3f / 4095.0f;
Lectura del sensor térmico integrado
El sensor de temperatura del RP2040 se basa en una referencia de bandgap de silicio, con compensación de voltaje de alimentación:
// Lectura con referencia por defecto (3.3V)
float temperatura = analogReadTemp();
// Lectura con referencia personalizada (para mayor precisión)
float temp_calibrada = analogReadTemp(3.0f); // Si VREF real es 3.0V
Especificaciones del sensor:
- Rango operativo: -20°C a +85°C
- Precisión típica: ±1°C
- Resolución: aproximadamente 0.05°C/LSB
Técnicas de filtrado y estabilización
Antirrebote por software
volatile bool interrupcion_valida = false;
unsigned long ultimo_tiempo_evento = 0;
const unsigned long TIEMPO_ANTIRREBOTE = 25; // ms
void ISR_con_filtro() {
unsigned long ahora = millis();
if (ahora - ultimo_tiempo_evento > TIEMPO_ANTIRREBOTE) {
ultimo_tiempo_evento = ahora;
interrupcion_valida = true;
}
}
Promediado móvil para ADC
float leerADC_promediado(uint8_t canal, uint8_t muestras) {
uint32_t acumulador = 0;
for (uint8_t i = 0; i < muestras; i++) {
acumulador += analogRead(canal);
delayMicroseconds(10); // Tiempo de establecimiento
}
return (acumulador / (float)muestras) * 3.3f / 4095.0f;
}
Aplicación práctica: Monitor ambiental
#include <Arduino.h>
// Definiciones de hardware
const uint8_t PIN_TERMISTOR = A0; // GPIO26
const uint8_t PIN_FOTORESISTENCIA = A1; // GPIO27
const uint8_t PIN_VENTILADOR = 16; // GPIO16
const uint8_t PIN_INDICADOR = 25; // LED integrado
const uint8_t PIN_ALARMA = 14; // GPIO14 (pulsador/interrupción)
// Variables de estado
volatile bool modo_alarma = false;
float temperatura_umbral = 28.5f;
uint16_t brillo_ambiental = 0;
void activarAlarma() {
modo_alarma = !modo_alarma; // Conmutar estado
}
void inicializarHardware() {
Serial.begin(115200);
// Configurar salidas
pinMode(PIN_VENTILADOR, OUTPUT_8MA);
pinMode(PIN_INDICADOR, OUTPUT);
// Configurar entrada con interrupción
pinMode(PIN_ALARMA, INPUT_PULLUP);
attachInterrupt(digitalPinToInterrupt(PIN_ALARMA), activarAlarma, FALLING);
// Precisión ADC
analogReadResolution(12);
}
float obtenerTemperatura() {
// Conversión del ADC a temperatura (aproximación lineal)
float temp = analogReadTemp();
// Compensación de autocalentamiento del chip
return temp - 0.5f;
}
void controlClimatico(float temp_actual) {
static bool estado_ventilador = false;
if (temp_actual > temperatura_umbral) {
if (!estado_ventilador) {
digitalWrite(PIN_VENTILADOR, HIGH);
digitalWrite(PIN_INDICADOR, HIGH);
estado_ventilador = true;
Serial.println("Ventilador ACTIVADO");
}
} else if (temp_actual < temperatura_umbral - 2.0f) {
if (estado_ventilador) {
digitalWrite(PIN_VENTILADOR, LOW);
digitalWrite(PIN_INDICADOR, LOW);
estado_ventilador = false;
Serial.println("Ventilador DESACTIVADO");
}
}
}
void reportarSensores(float temp, uint16_t luz) {
Serial.printf("Temp: %.2f°C | Luz: %u/4095 | Alarma: %s\n",
temp, luz, modo_alarma ? "ON" : "OFF");
}
void setup() {
inicializarHardware();
Serial.println("Sistema iniciado");
}
void loop() {
// Lectura de sensores
float temperatura = obtenerTemperatura();
brillo_ambiental = analogRead(PIN_FOTORESISTENCIA);
// Lógica de control
controlClimatico(temperatura);
// Verificar bandera de interrupción
if (modo_alarma) {
modo_alarma = false; // Resetear para próxima activación
Serial.println("*** ALARMA MANUAL ACTIVADA ***");
// Acciones adicionales de alarma...
}
// Reporte periódico
reportarSensores(temperatura, brillo_ambiental);
delay(1000);
}
Optimización para aplicaciones de bajo consumo
// Desactivar pines no utilizados para reducir consumo
void desactivarPinesReserva() {
for (uint8_t pin = 2; pin <= 13; pin++) {
pinMode(pin, INPUT_PULLDOWN); // Estado definido, mínima corriente
}
}
// Reducir corriente de salida cuando sea posible
pinMode(PIN_LED_ESTADO, OUTPUT_2MA); // Suficiente para LED indicador
Depuración con PlatformIO
Para proyectos avanzados, PlatformIO ofrece capacidades superiores:
- Crear proyecto con plataforma
raspberrypiy boardpico - Configurar
platformio.inicon opciones de depuración - Utilizar Serial.printf() para formateo eficiente
- Implementar asserts para validación en tiempo de desarrollo
; platformio.ini de ejemplo
[env:pico]
platform = raspberrypi
board = pico
framework = arduino
build_flags = -D SERIAL_USB
monitor_speed = 115200
Resolución de problemas frecuentes
| Síntoma | Causa probable | Solución |
|---|---|---|
| Lecturas ADC erráticas | Referencia de voltaje inestable | Agregar capacitor 100nF en VREF |
| Interrupciones múltiples espurias | Rebote del interruptor | Implementar antirrebote por hardware o software |
| Temperatura incorrecta | Autocalentamiento del RP2040 | Compensar con offset o usar promediado |
| Pines no responden | Conflicto con periférico asignado | Verificar tabla de multiplexación de funciones |