En este artículo explicamos cómo probar la comunicación CAN bus entre dos unidades ESP32 PLC 14 usando el módulo CAN SPI 5V click y Arduino IDE.
Configuración del hardware: conexión del módulo CAN SPI click
El ESP32 PLC 14 dispone de una ranura de comunicación adicional compatible con el CAN SPI click. Conecta los pines H y L entre las dos unidades. Una conexión de dos cables funciona, pero se recomienda un cable CAN bus de 3 puntos para mejor integridad de señal.
Configuración del software: librerías y definiciones de pines
Instala la placa industrialshields-esp32 en el Arduino IDE: ve a Herramientas > Placa > Gestor de placas y busca "industrialshields-esp32". Luego selecciona Herramientas > Placa > Industrial Shields ESP32 > 14 IOS PLC Family.
Descarga e instala la librería MCP_CAN: Sketch > Incluir librería > Añadir biblioteca .ZIP. La librería está disponible en github.com/coryjfowler/MCP_CAN_lib.
Crea un archivo defs.h dentro de una nueva carpeta en tu carpeta de librerías de Arduino, pega las siguientes definiciones y reinicia el Arduino IDE.
#include "MCP23017.h" #define In0 11 #define In1 10 #define In2 12 #define In3 13 #define In4 4 #define In5 6 #define In6 5 #define S0_24v 15 #define S1_24v 14 #define S2_24v 1 #define S3_24v 0 #define Relay 7 #define PWM_click 9 #define INT_click 8 #define INTA 13 // Expander interrupt #define Out0 32 #define Out1 25 #define Out2 26 #define Out3 27 #define CS0 14 // Ethernet #define CS1 4 // Click #define A0420 32 // Analog 4..20mA #define A1420 33 #define A0010 34 // Analog 0..10v #define A1010 35 #define pwrPin 2 #define resetPin 3 #define INT_click 8 #define PWM_click 9 #define INTA 13 // Expander interrupt #define CS0 14 // Ethernet #define CS1 4 // Click #define UART1 0x78 #define Bit0 0x00 // MCP I2C CONFIG const uint8_t sda = 21; const uint8_t scl = 22; uint8_t mcp_i2c_address = 0x20; MCP23017 mcp(mcp_i2c_address);
Sketch de envío CAN
Sube el siguiente sketch a la unidad ESP32 PLC 14 emisora:
#include "defs.h"
#include "Wire.h"
#include <mcp_can.h>
MCP_CAN CAN0(CS1);
byte data[8] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07};
void setup() {
Serial.begin(115200UL);
delay(1000);
pinMode(CS1, OUTPUT);
delay(100);
digitalWrite(CS1, LOW);
delay(1000);
if (!mcp.begin(sda, scl)) {
Serial.print(-1);
while (1);
}
delay(1000);
if (CAN0.begin(MCP_ANY, CAN_500KBPS, MCP_8MHZ) == CAN_OK)
Serial.println("MCP2515 initialized successfully!");
else
Serial.println("Error initializing MCP2515...");
CAN0.setMode(MCP_NORMAL);
}
void loop() {
uint8_t sndStat = CAN0.sendMsgBuf(0x111, 0, 8, data);
if (sndStat == CAN_OK) {
Serial.println("Message sent successfully!");
} else {
Serial.println("Error sending message...");
}
delay(3000);
}
Sketch de recepción CAN
Sube el siguiente sketch a la unidad ESP32 PLC 14 receptora:
#include "defs.h"
#include "Wire.h"
#include <mcp_can.h>
MCP_CAN CAN0(CS1);
long unsigned int rxId;
unsigned char len = 0;
unsigned char rxBuf[8];
char msgString[128];
void setup() {
Serial.begin(115200UL);
delay(1000);
pinMode(CS1, OUTPUT);
delay(100);
digitalWrite(CS1, LOW);
delay(1000);
if (!mcp.begin(sda, scl)) {
Serial.print(-1);
while (1);
}
delay(1000);
if (CAN0.begin(MCP_ANY, CAN_500KBPS, MCP_8MHZ) == CAN_OK)
Serial.println("MCP2515 initialized successfully!");
else
Serial.println("Error initializing MCP2515...");
CAN0.setMode(MCP_NORMAL);
}
void loop() {
CAN0.readMsgBuf(&rxId, &len, rxBuf);
if ((rxId & 0x80000000) == 0x80000000)
sprintf(msgString, "Extended ID: 0x%.8lX DLC: %1d Data:", (rxId & 0x1FFFFFFF), len);
else
sprintf(msgString, "Standard ID: 0x%.3lX DLC: %1d Data:", rxId, len);
Serial.print(msgString);
if ((rxId & 0x40000000) == 0x40000000) {
sprintf(msgString, " REMOTE REQUEST FRAME");
Serial.print(msgString);
} else {
for (byte i = 0; i < len; i++) {
sprintf(msgString, " 0x%.2X", rxBuf[i]);
Serial.print(msgString);
}
}
Serial.println();
delay(500);
}
Una vez que ambos sketches estén en ejecución en unidades ESP32 PLC 14 separadas, abre el Monitor Serie en el receptor para confirmar que los mensajes CAN llegan correctamente.