esp32-spi

Cómo usar el bus SPI en un ESP32

El Bus SPI es un protocolo de comunicación síncrona utilizado para transferir datos entre un microcontrolador y otros dispositivos, como sensores, pantallas, memorias y periféricos.

A diferencia de otros protocolos, el bus SPI utiliza múltiples líneas de comunicación, permitiendo una alta velocidad de transferencia y una flexibilidad excepcional.

El puerto SPI es principalmente usado por alta capacidad de transmitir datos. Por este motivo lo encontraréis en dispositivos que requieran gran cantidad de datos por segundo, como dispositivos de almacenamiento (memorias, SD) y pantallas.

El bus SPI en el ESP32

El ESP32, ESP32-S2 y ESP32-S3 tienen cuatro controladores SPI, mientras que el ESP32-C3 tiene tres.

Su uso en el entorno de Arduino es muy similar al que encontraríamos en un Arduino convencional. Las funcionalidades están definidas en la biblioteca SPI.h, bajo el objeto SPIClass.

void setup() {
  // Inicializar comunicación SPI
  SPI.begin();
}

El mayor lio lo vamos a tener con los pines y sus denominaciones. Pero, tenemos la ventaja de que en el caso del ESP32, podemos reasignar los pines.

Si miramos el ESP32, ESP32-S2 y ESP32-S3 tienen cuatro controladores, llamados SPI0, SPI1, SPI2 y SPI3.

  • SPI0 y SPI1 se usan para la comunicación con la memoria Flash. Así que no se tocan.
  • SPI2 y SPI3 quedan libres para el usuario.

Esto deja dos controladores SPI libres para poderlos usar (uno en el ESP32-C3).

Por otro lado, al SPI2 se le denomina HSPI y al SPI3 se le denomina VSPI. ¿Qué significan la H y la V? Absolutamente nada, son iguales en características.

De hecho buscad en internet, que hay preguntas y respuestas graciosas sobre que significa H y V (me gusta la de Henry y Victor).

En el caso del ESP32

SPIMOSIMISOSCKCS
HSPIGPIO 13GPIO 12GPIO 14GPIO 15
VSPIGPIO 23GPIO 19GPIO 18GPIO 5

En el caso del ESP32-S3

SPIMOSIMISOSCKCS
HSPIGPIO 35GPIO 37GPIO 37GPIO -
VSPIGPIO 11GPIO 13GPIO 12GPIO 10

Pero lo mismo, yo me encargaría de definirlos a manopla

SPIClass vspi = SPIClass(VSPI);

MySPI.begin(VSPI_SCLK, VSPI_MISO, VSPI_MOSI, VSPI_SS);

Las constantes VSPI y HSPI son integer que están definidas en el Core de Arduino. Son diferentes para cada variante del ESP32, así que usad la constante en lugar de un número.

ModeloHSPIVSPI
ESP3213
ESP32-S223
ESP32-S323
ESP32-C313

Cómo usar SPI en ESP32 en el entorno de Arduino

El uso del bus I2C en el ESP32 en el entorno de Arduino es muy similar a hacerlo en un Arduino convencional. Ahí van unos ejemplos.

Enviar Datos

byte dataToSend = 0xAA;
byte receivedData;

digitalWrite(SS, LOW);  // Bajar línea CS/SS para seleccionar el dispositivo
receivedData = SPI.transfer(dataToSend);  // Enviar y recibir datos
digitalWrite(SS, HIGH); // Subir línea CS/SS para finalizar la comunicación

Usando múltiples SPI en el ESP32

Como hemos dicho, el ESP32, ESP32-S2 y ESP32-S3 tienen dos controladores de I2C, por lo que podemos crear dos redes de dispositivos simultáneas.

#include <SPI.h>

#define HSPI 2  // 2 para S2 y S3, 1 para S1
#define VSPI 3

// reemplazar por los pines que queráis usar
const int HSPI_MISO = 0;
const int HSPI_MOSI = 0;
const int HSPI_SCLK = 0;
const int HSPI_SS = 0;

const int VSPI_MISO = 0;
const int VSPI_MOSI = 0;
const int VSPI_SCLK = 0;
const int VSPI_SS = 0;

SPIClass vspi = SPIClass(VSPI);
SPIClass hspi = SPIClass(HSPI);

void setup()
{ 
  vspi.begin(VSPI_SCLK, VSPI_MISO, VSPI_MOSI, VSPI_SS);
  hspi.begin(HSPI_SCLK, HSPI_MISO, HSPI_MOSI, HSPI_SS);
}

void loop()
{
  delay(1000);  // do nothing
}