Cómo construir un bus CAN con ESP32
El ESP32 se ha convertido en uno de los microcontroladores más populares para proyectos de Internet de las Cosas (IoT), principalmente por su capacidad de conectividad WiFi. Sin embargo, este potente dispositivo no solo destaca por su funcionalidad de conexión a redes, sino que también está equipado con un controlador CAN, que a menudo no recibe la atención que merece. Aprender a utilizar el controlador CAN del ESP32 puede abrir la puerta a aplicaciones innovadoras, especialmente en el ámbito automotriz y de automatización industrial.
En este artículo, exploraremos en profundidad cómo construir una red CAN utilizando el ESP32. Desde los conceptos básicos de CAN hasta la instalación de bibliotecas y la programación de ejemplos prácticos, cubriremos todo lo necesario para que puedas aprovechar al máximo esta tecnología en tus proyectos.
Introducción al sistema CAN Bus
Antes de sumergirnos en la implementación del ESP32 con CAN, es importante entender qué es el sistema CAN y cómo ha revolucionado la industria automotriz. Históricamente, los vehículos contaban con miles de metros de cableado para conectar diversos componentes. Con el aumento de la complejidad de los automóviles, esta solución se volvió inviable.
El sistema CAN, desarrollado por Bosch en 1986, permitió a los fabricantes de automóviles simplificar el cableado al utilizar un solo bus de comunicación para todos los componentes electrónicos. Esto no solo redujo costos, sino que también mejoró la eficiencia en el diseño de vehículos modernos.
Pensando en el cuerpo humano, podemos comparar el sistema CAN con el sistema nervioso, donde cada Unidad de Control Electrónico (ECU) actúa como un órgano que se comunica con otros a través del bus CAN.
Arquitectura y topología del CAN Bus
La topología del bus CAN se basa en dos líneas principales: CAN low y CAN high. Estas líneas están trenzadas para minimizar la interferencia electromagnética y asegurar una comunicación efectiva. Además, el bus debe ser terminado con resistencias de 120 ohmios en ambos extremos para evitar reflexiones de la señal que podrían interrumpir la comunicación.
Señalización en CAN
El sistema CAN emplea cambios de voltaje para transmitir datos. Un estado de Recesivo (2.5V en ambas líneas) indica que el bus está disponible, mientras que un estado Dominante (3.5V en CAN high y 1.5V en CAN low) significa que un nodo está transmitiendo, y otros nodos deben esperar para enviar sus mensajes.
Nodos en la red CAN
Cada nodo en una red CAN está compuesto por un transceptor, un controlador y un microcontrolador:
- Transceptor CAN: Convierte los niveles de voltaje del bus a niveles que el controlador puede entender.
- Controlador CAN: Maneja la transmisión y recepción de mensajes, almacenando datos hasta que un mensaje completo esté disponible.
- Microcontrolador: Interpreta los mensajes recibidos y decide qué mensajes enviar.
Controlador CAN del ESP32: TWAI
El controlador CAN del ESP32 es conocido como TWAI (Two-Wire Automotive Interface). Este controlador es compatible con el estándar CAN 2.0 y permite tanto formatos de 11 bits como de 29 bits para las identificaciones de los mensajes.
Una de las características más importantes del TWAI es su capacidad de manejar errores y su eficiencia en entornos ruidosos, lo cual es crucial para aplicaciones automotrices. Además, permite una comunicación basada en interrupciones, lo que optimiza la gestión de mensajes y eventos sin necesidad de sondear continuamente el estado del bus.
Modos de Operación del TWAI
El controlador TWAI ofrece varios modos de operación:
- Modo Normal: Participa en las actividades del bus, transmitiendo y recibiendo mensajes.
- Modo Sin Confirmación: Permite la transmisión sin necesidad de confirmación de otros nodos.
- Modo Solo Escucha: No transmite, pero puede recibir mensajes para monitorear la red.
Transceptor CAN TJA1050
Aunque el ESP32 cuenta con un controlador CAN integrado, necesita un transceptor externo para conectarse a la red CAN. El TJA1050 de NXP es una excelente opción, ya que cumple con los estándares ISO 11898-2 y permite comunicaciones a alta velocidad de hasta 1Mb/s.
Este transceptor se encarga de adaptar las señales del controlador a los niveles requeridos por el bus físico, asegurando la compatibilidad y la robustez en las comunicaciones.
Conexión de Hardware para la Red CAN
Ahora que conocemos los componentes esenciales, vamos a ver cómo construir una red CAN utilizando el ESP32 y el transceptor TJA1050.
Ejemplo 1: Red CAN de Dos Nodos
En este ejemplo, crearemos una red CAN básica con dos nodos:
- Conectar el pin VCC del TJA1050 al VIN del ESP32.
- Conectar el pin GND al suelo (GND) del ESP32.
- Configurar el TX en GPIO5 y RX en GPIO4 en el ESP32.
- Realizar la misma conexión en el segundo nodo.
Los cables CAN L y CAN H deben ser conectados entre sí. Si bien es ideal utilizar cables trenzados, para pruebas simples en una placa de pruebas pueden usarse cables normales.
Ejemplo 2: Red CAN Multinodo
En este caso, ampliamos nuestra red para incluir múltiples nodos. Cada nuevo nodo puede ser conectado en línea o mediante un cable corto, siempre asegurando que la longitud no exceda las 30 cm desde el bus principal.
Recuerda que si añades más nodos, debes retirar la resistencia de 120 ohmios del último transceptor en la cadena.
Instalación de Bibliotecas
Para trabajar con el controlador TWAI en el ESP32, es recomendable utilizar la biblioteca de CAN de Sandeep Mistry. Esta biblioteca facilita la comunicación y el manejo de mensajes en el bus CAN.
Para instalarla, navega a Sketch > Include Library > Manage Libraries… y busca ‘mcp2515’. Selecciona la biblioteca de Sandeep Mistry y haz clic en Install.
Código de Ejemplo para Transmisión y Recepción
A continuación, se presentan ejemplos de código para el nodo transmisor y el receptor. Estos códigos te permitirán enviar y recibir mensajes a través del bus CAN.
Código para el Nodo Transmisor
Este es el código que debes subir al nodo transmisor:
#include <CAN.h>
#define TX_GPIO_NUM 5
#define RX_GPIO_NUM 4
void setup() {
Serial.begin(115200);
while (!Serial);
delay(1000);
Serial.println("CAN Sender");
CAN.setPins(RX_GPIO_NUM, TX_GPIO_NUM);
if (!CAN.begin(500E3)) {
Serial.println("Starting CAN failed!");
while (1);
}
}
void loop() {
Serial.print("Sending packet ... ");
CAN.beginPacket(0x12);
CAN.write('h');
CAN.write('e');
CAN.write('l');
CAN.write('l');
CAN.write('o');
CAN.endPacket();
Serial.println("done");
delay(1000);
}
Código para el Nodo Receptor
Este es el código que debes cargar en el nodo receptor:
#include <CAN.h>
#define TX_GPIO_NUM 5
#define RX_GPIO_NUM 4
void setup() {
Serial.begin(115200);
while (!Serial);
delay(1000);
Serial.println("CAN Receiver");
CAN.setPins(RX_GPIO_NUM, TX_GPIO_NUM);
if (!CAN.begin(500E3)) {
Serial.println("Starting CAN failed!");
while (1);
}
}
void loop() {
int packetSize = CAN.parsePacket();
if (packetSize) {
Serial.print("Received ");
if (CAN.packetExtended()) {
Serial.print("extended ");
}
Serial.print("packet with id 0x");
Serial.print(CAN.packetId(), HEX);
Serial.print(" and length ");
Serial.println(packetSize);
while (CAN.available()) {
Serial.print((char)CAN.read());
}
Serial.println();
}
}
Demostración Práctica
Una vez que subas los códigos a los respectivos nodos, abre el monitor serial a una tasa de 115200 baudios. El nodo transmisor enviará un paquete CAN cada segundo, y el nodo receptor mostrará en el monitor serial los mensajes recibidos.
Esta práctica te permitirá comprobar la funcionalidad del sistema CAN en tu entorno y te servirá como base para proyectos más complejos en el futuro.
Deja una respuesta
Estos temas te pueden interesar