Hello,
I am posting to hopefully spare other some time.
I spent the past week trying to get the ESP32 Nano and the TJA1051 Can Transceivers working. The TWAI examples which came with the board did not give me much hope, I would get the controller running, messages sent but nothing received on the other side.
I tried to set up send/receive using the 2 xMCP2515 and 2x ESP32 Nano's. Then using the MCP2515.h library I got the boards sending and receiving.
Next Using and ESP32-S3- WROOM and a ESP32-WROOM-32U I followed a tutorial to set up a sender and receiver using the TJA1051 transceivers... Using the library ESP32-TWAI-CAN.hpp. Again this worked.
Next I placed the TJA1051 RX/TX pins to pin D9(RX) and D8(TX) on the Arduino ESP32 Nano.
Arduino nano esp32 wiring:
- Vin to Breadboard +
- GND to Breadboard -
- D9 to RX on TJA1051
- D8 to TX on TJA1051
TJA1051 wiring:
- VCC to breadboard +
- GND to breadboard -
- RX to D9 arduino
- TX to D8 arduino
- CAN H to CAN H on other TJA1051
- CAN L to CAN L on other TJA1051
Providing USB power to one of the Arduinos will supply power across the + of the breadboard. I believe you cannot program 2 ESP32 Nanos at once on the same PC due to it using DFU. (source: Can't upload to more than 1 nano esp32 "dfu-util: More than one DFU capable USB device found!")
In the Arduino IDE I went to tools ---> Pin Numbering;----> By GPIO number (legacy).
From looking at the ESP32 Nano pinout D9 is GPIO 18 and D8 is GPIO 17. I first uploaded the sender, checked it worked, then programmed the receiver.
Below is the code I used for the Sender:
#include <ESP32-TWAI-CAN.hpp>
#define CAN_TX 17 // Connects to CTX
#define CAN_RX 18 // Connects to CRX
CanFrame rxFrame; // Create frame to read
void setup() {
// Set up serial for debugging
Serial.begin(115200);
delay(500);
// Set the pins
ESP32Can.setPins(CAN_TX, CAN_RX);
Serial.println("test3");
// Start the CAN bus at 500 kbps
if(ESP32Can.begin(ESP32Can.convertSpeed(500))) {
Serial.println("CAN bus started!");
} else {
Serial.println("CAN bus failed!");
}
}
void loop() {
canSender(); // call function to send data through CAN
//canReceiver(); // call function to recieve data through CAN
}
void canSender() {
// send packet: id is 11 bits, packet can contain up to 8 bytes of data
Serial.print("Sending packet ... ");
CanFrame testFrame = { 0 };
testFrame.identifier = 0x12; // Sets the ID
testFrame.extd = 0; // Set extended frame to false
testFrame.data_length_code = 8; // Set length of data - change depending on data sent
testFrame.data[0] = '1'; // Write data to buffer. data is not sent until writeFrame() is called.
testFrame.data[1] = '2';
testFrame.data[2] = '3';
testFrame.data[3] = '4';
testFrame.data[4] = '5';
testFrame.data[5] = '6';
testFrame.data[6] = '7';
testFrame.data[7] = '8';
ESP32Can.writeFrame(testFrame); // transmit frame
Serial.println("done");
}
Receiver
#include <ESP32-TWAI-CAN.hpp>
#define CAN_TX 17 // Connects to CTX
#define CAN_RX 18 // Connects to CRX
CanFrame rxFrame; // Create frame to read
void setup() {
// Set up serial for debugging
Serial.begin(115200);
delay(500);
// Set the pins
ESP32Can.setPins(CAN_TX, CAN_RX);
Serial.println("test3");
// Start the CAN bus at 500 kbps
if(ESP32Can.begin(ESP32Can.convertSpeed(500))) {
Serial.println("CAN bus started!");
} else {
Serial.println("CAN bus failed!");
}
}
void loop() {
// canSender(); // call function to send data through CAN
canReceiver(); // call function to recieve data through CAN
}
void canReceiver() {
// try to parse packet
if(ESP32Can.readFrame(rxFrame, 700)) { // 1000 is the timeout value
// Communicate that a packet was recieved
Serial.printf("Received frame: %03X \r\n", rxFrame.identifier);
// Communicate packet information
for(int i = 0; i <= rxFrame.data_length_code - 1; i ++) {
Serial.print((char) rxFrame.data[i]); // Transmit value from the frame
}
} else {
Serial.println("No frame recieved");
}
}
I hope this helps someone.