viernes, 15 de agosto de 2025

SPI: El Protocolo de Comunicación Rápida para IoT

Comunicación SPI entre dispositivos

SPI: El Protocolo de Comunicación Rápida para IoT

🚀 ¿Qué es SPI?

SPI (Serial Peripheral Interface) es un protocolo de comunicación síncrona desarrollado por Motorola que permite la comunicación de alta velocidad entre microcontroladores y periféricos. A diferencia de I2C o UART, SPI está diseñado para velocidad y es ideal para sensores, pantallas, memorias y módulos RF en proyectos IoT.


📌 Características principales

  • Comunicación full-duplex (datos simultáneos en ambas direcciones)
  • Velocidades muy altas (hasta varios MHz)
  • Protocolo maestro-esclavo con un dispositivo maestro controlando múltiples esclavos
  • 4 líneas de comunicación (MOSI, MISO, SCK, CS/SS)

🔌 Pines y conexiones

SPI utiliza 4 líneas principales:

  • MOSI (Master Out Slave In): Datos del maestro al esclavo
  • MISO (Master In Slave Out): Datos del esclavo al maestro
  • SCK (Serial Clock): Señal de reloj generada por el maestro
  • CS/SS (Chip Select/Slave Select): Selección de dispositivo esclavo
Maestro (ESP32)    →    Esclavo (Sensor)
MOSI (Pin 23)      →    MOSI/DIN
MISO (Pin 19)      ←    MISO/DOUT
SCK  (Pin 18)      →    SCK/CLK
CS   (Pin 5)       →    CS/SS

⚡ Ventajas de SPI en IoT

  1. Alta velocidad: Ideal para pantallas, cámaras y sensores de alta frecuencia
  2. Full-duplex: Envío y recepción simultánea de datos
  3. Simple implementación: Sin direccionamiento complejo como I2C
  4. Bajo overhead: Sin bits de start/stop como UART

🛠️ Dispositivos comunes que usan SPI

  • Pantallas: TFT, OLED, E-Paper
  • Memorias: EEPROM, Flash, tarjetas SD
  • Sensores: Acelerómetros, giroscopios, barómetros
  • Módulos RF: NRF24L01, LoRa SX1278
  • Convertidores: ADC/DAC externos

💻 Ejemplo práctico: ESP32 + Sensor MPU6050

#include <SPI.h>

#define CS_PIN 5

void setup() {
  Serial.begin(115200);
  SPI.begin();
  pinMode(CS_PIN, OUTPUT);
  digitalWrite(CS_PIN, HIGH); // CS inactivo por defecto
}

void loop() {
  // Seleccionar dispositivo
  digitalWrite(CS_PIN, LOW);
  
  // Enviar comando para leer WHO_AM_I (0x75)
  SPI.transfer(0x75 | 0x80); // Bit 7 = 1 para lectura
  uint8_t whoami = SPI.transfer(0x00); // Leer respuesta
  
  // Deseleccionar dispositivo
  digitalWrite(CS_PIN, HIGH);
  
  Serial.print("WHO_AM_I: 0x");
  Serial.println(whoami, HEX);
  
  delay(1000);
}

🔄 Modos de SPI

SPI tiene 4 modos definidos por la polaridad (CPOL) y fase (CPHA) del reloj:

ModoCPOLCPHADescripción
000Reloj bajo en reposo, datos en flanco ascendente
101Reloj bajo en reposo, datos en flanco descendente
210Reloj alto en reposo, datos en flanco descendente
311Reloj alto en reposo, datos en flanco ascendente

📊 SPI vs otros protocolos

ProtocoloVelocidadPinesDispositivosComplejidad
SPIMuy alta4+nMúltiplesBaja
I2CMedia2MúltiplesMedia
UARTBaja21 a 1Muy baja

🎯 Consejos para usar SPI en IoT

  1. Cables cortos: SPI es sensible al ruido a altas velocidades
  2. Alimentación estable: Usa condensadores de desacoplo
  3. Pull-ups en CS: Evita estados flotantes
  4. Documentación: Siempre revisa el datasheet del sensor
  5. Nivel lógico: Verifica compatibilidad 3.3V/5V

🔧 Configuración avanzada en ESP32

SPISettings settingsA(1000000, MSBFIRST, SPI_MODE0);

void readSensor() {
  SPI.beginTransaction(settingsA);
  digitalWrite(CS_PIN, LOW);
  
  // Tu código aquí
  
  digitalWrite(CS_PIN, HIGH);
  SPI.endTransaction();
}

🚨 Problemas comunes

  1. CS mal conectado: Verifica las conexiones de Chip Select
  2. Modo SPI incorrecto: Consulta el datasheet del dispositivo
  3. Velocidad muy alta: Reduce la frecuencia del reloj
  4. Cables largos: Mantén las conexiones cortas y blindadas

SPI es fundamental en IoT para aplicaciones que requieren alta velocidad y bajo latency. Su simplicidad y rendimiento lo convierten en la opción ideal para sensores críticos, pantallas y almacenamiento en proyectos IoT profesionales.