CANbus, TWAI using ESP32 Nano and TJA1051

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.

1 Like

Doesn't sound right.
What voltage is "Vin" in your system?

The following assumes you have a genuine TJA1051xxx chip of some kind.
All variants of the TJA1051 chip require 5v. The regular TJA1051 without the T/3 suffix needs a level shifter to down shift the 5v data output to the 3.3v that the ESP32 can handle.

The significantly different TJA1051T/3 variant has a built in level shifter that needs a different wiring configuration. No additional level shifter is required.

It is sending data from the sender and receiving the correct data being sent by the sender on the receiver.

Which is what I could not get to work whether I added resistors or not using the driver/TWAI example from the esp32 Nano board examples.

When attached to the USB the ESP 32 Nano Vin pin supplies 5v, Or in my case 4.7V.

I would say it is a TJA1051, but it is not a genuine one, it is one which says NC on one side and Vio on the other (like the TJA1051T/3). So It all depends on which way you look at it. Literally.

It would be nice to have a genuine TJA1051 or a correct data sheet for the actual TJA1051 concoction I am using.

The breakout board looks like it was designed to be used with both types of chips hence the differing pin labels. You are supposed to use whichever side has the labels appropriate for the chip that has been fitted.

You can tell what chip is fitted on your board by comparing it against the image on the Adafriut web site that shows a genuine T/3 variant.

If yours doesn't have the "/3" then you have a regular TJA1051 which will be putting out a signal way above the 3.3v of the ESP32 and that could potentially damage it. For the high speed CAN signals you are using you'll need to use a proper level shifter such as the 4050 buffer powered by 3.3v. Using resistive dividers or inline resistors isn't going to work.

I have now purchased two of them for further work.

I will add logic level shifters to my current config and report back. I wonder if, the reason the tutorial did not work from the ESP32 Nano library is due to this 5v Trx input as some sort of over voltage protection. I cannot see anything in the library immediately but using the driver/twai.h I would send messages but not receive. I will re-try driver/twai.h when I have placed the shifters.

The voltage from Arduino to Tx is 3.3v, The voltage from Rx to Arduino is 4.6v.

For anybody curious using a voltage divider did work for this example. I am now getting 3.1v from the Rx's to the Arduino esp32 Nano's. And receiving the sent message

This is a simple solution, for a simple one frame can signal whilst I wait for my other TJA1051T/3s to arrive.

Now did with this lower voltage the send and receive work from the Driver/twai.h? No.

A post was split to a new topic: SN65H und Nano ESP32, auf der Gegenseite kommt nichts an