Skip to content

Add TWAI receive example #7430

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 4 commits into from
Closed

Add TWAI receive example #7430

wants to merge 4 commits into from

Conversation

designer2k2
Copy link
Contributor

Description of Change

Example showing how to receive messages using the TWAI interface and a CAN transceiver.
It also uses the alerts to show how to set them up and react to them.

It is based on the samples shown in the api: https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-reference/peripherals/twai.html

Tests scenarios

I used an esp32-c3-devkit (ESP32-D0WDQ6) with a SN65HVD230 CAN transceiver.
This was attached between 2 Arduino Nano´s with a MCP2515/MCP2562 CAN interface, whereby they replayed a recording from a quite busy CAN bus.
This replay was then observed by the ESP32 and send with this example to the host.

Example showing how to receive messages using the TWAI interface and a CAN transceiver.
@CLAassistant
Copy link

CLAassistant commented Nov 5, 2022

CLA assistant check
All committers have signed the CLA.

@VojtechBartoska VojtechBartoska added the Type: Example Issue is related to specific example. label Nov 7, 2022
use pdMS_TO_TICKS for twai_read_alerts,
format specifier on hex byte info,
and dedicated if´s instead of else if on alerts to show multiple errors.
@PilnyTomas
Copy link
Contributor

I do not have the required hardware to properly test it. All I can confirm is that it compiles and isn't crashing.

@PilnyTomas PilnyTomas added the Status: Community help needed Issue need help from any member from the Community. label Nov 9, 2022
@VojtechBartoska VojtechBartoska added this to the 2.0.6 milestone Nov 16, 2022
@designer2k2
Copy link
Contributor Author

I added some more details on why alerts happen.

Anything i can help with to prove this is functional?
Here a picture of the testsystem i use (when not running it in a car):
esp32_can_indoor_testbench

@VojtechBartoska
Copy link
Contributor

@designer2k2 Hi, we're watching this and we will include it in upcoming release 2.0.6., release date will be in the 1st half of December.

@Dazza0 Dazza0 self-requested a review November 22, 2022 12:20
@Dazza0 Dazza0 self-assigned this Nov 22, 2022
@VojtechBartoska
Copy link
Contributor

Hello @Dazza0, if you will have some time please help with review of this. We would like to include this in next release. Thanks.

Copy link
Contributor

@Dazza0 Dazza0 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@designer2k2 Thanks for the contribution. Left some comments about how to use the TWAI alerts more effectively.

@designer2k2
Copy link
Contributor Author

Hello @Dazza0, I will incorporate your requests by tomorrow

@designer2k2
Copy link
Contributor Author

Hello @Dazza0, please take a look if the changes are ok like this

@designer2k2 designer2k2 requested review from Dazza0 and removed request for P-R-O-C-H-Y December 3, 2022 10:25
Copy link
Contributor

@Dazza0 Dazza0 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@designer2k2

One more nitpick. Could you squash your commits before we merge? The example and TWAI driver usage LGTM otherwise.

@PilnyTomas @VojtechBartoska

Reading the twai status help to understand why certain alerts happen

Update as requested

- capitals for macros
- using TWAI_ALERT_RX_DATA for polling
- parsing in static function
- (shortened output to speed up output)

move function above loop, define before use
@designer2k2
Copy link
Contributor Author

@Dazza0 i am lost with the squash topic, the github gui only allowed me to squash the last 3.
But i cannot do it on the others, there was a merge in between that somehow blocks this:
grafik

Any way thats possible to do on your end? Or give me a hint how i can resolve the error above?

@Dazza0
Copy link
Contributor

Dazza0 commented Dec 5, 2022

@designer2k2 I think I see where the issue is.

image

It seems like the issue might be coming from this commit. It seems updates from upstream arduino-esp32 somehow got merged into the master branch of your local fork. If your Github GUI supports rebasing, it is usually possible to drop a particular commit during the rebase.

Alternatively:

  • I could try override your branch from my side. But I think you'll need to explicitly allow that according to Github's docs
  • You could try creating a new branch for these changes (recommended for future PRs). This way you can easily rebase your changes on top the latest master. But unfortunately, I think you'll need to create a new PR for that as I don't think it's possible to retarget an existing PR to a new branch.
  • I can also create that branch/PR for you if you prefer (I'll be sure to keep you as the commit author).

@designer2k2
Copy link
Contributor Author

yes there i clicked on the "Update branch" Button in the Gui, that was not good.

Could you create the branch/PR for me? Its not clear to me on how to do that.

Dazza0 pushed a commit to Dazza0/arduino-esp32 that referenced this pull request Dec 5, 2022
This commit addes an example showing how to receive messages using the TWAI
driver interface and a CAN transceiver. Specifically, the example demonstrates:

- How to configure and install the TWAI drvier
- How to poll for TWAI events (i.e., alerts) using twai_read_alerts()
- How to handle the various events (such as TWAI_ALERT_RX_DATA)

Closes espressif#7430
@VojtechBartoska
Copy link
Contributor

VojtechBartoska commented Dec 5, 2022

@designer2k2 Squashing commits can be done by us when we will merge this so don't worry about that.

Update: I just see it's already done by @Dazza0. :)

Dazza0 pushed a commit to Dazza0/arduino-esp32 that referenced this pull request Dec 5, 2022
This commit addes an example showing how to receive messages using the TWAI
driver interface and a CAN transceiver. Specifically, the example demonstrates:

- How to configure and install the TWAI drvier
- How to poll for TWAI events (i.e., alerts) using twai_read_alerts()
- How to handle the various events (such as TWAI_ALERT_RX_DATA)

Closes espressif#7430
Dazza0 pushed a commit to Dazza0/arduino-esp32 that referenced this pull request Dec 5, 2022
This commit addes an example showing how to receive messages using the TWAI
driver interface and a CAN transceiver. Specifically, the example demonstrates:

- How to configure and install the TWAI drvier
- How to poll for TWAI events (i.e., alerts) using twai_read_alerts()
- How to handle the various events (such as TWAI_ALERT_RX_DATA)

Closes espressif#7430
Dazza0 pushed a commit to Dazza0/arduino-esp32 that referenced this pull request Dec 5, 2022
This commit addes an example showing how to receive messages using the TWAI
driver interface and a CAN transceiver. Specifically, the example demonstrates:

- How to configure and install the TWAI drvier
- How to poll for TWAI events (i.e., alerts) using twai_read_alerts()
- How to handle the various events (such as TWAI_ALERT_RX_DATA)

Closes espressif#7430
@me-no-dev me-no-dev closed this in 9006751 Dec 5, 2022
@davidcyr2000
Copy link

In order to filter out and accept only specific message IDs, the statement "twai_filter_config_t f_config = TWAI_FILTER_CONFIG_ACCEPT_ALL();" has to be replaced with the appropriate "acceptance code and the acceptance mask". This is not well explained in the Espressif documentation. Has anyone managed to successfully code this information to limit the message IDs seen by an Arduino C++ application? If so, please share that part of your code. Thank you!

@Dazza0
Copy link
Contributor

Dazza0 commented Feb 4, 2024

In order to filter out and accept only specific message IDs, the statement "twai_filter_config_t f_config = TWAI_FILTER_CONFIG_ACCEPT_ALL();" has to be replaced with the appropriate "acceptance code and the acceptance mask". This is not well explained in the Espressif documentation. Has anyone managed to successfully code this information to limit the message IDs seen by an Arduino C++ application? If so, please share that part of your code. Thank you!

Please refer to https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-reference/peripherals/twai.html#acceptance-filter

@davidcyr2000
Copy link

Thanks for responding to my question. However, I have read this particular section of the specs 17 times and still don't know how to code the masks and filters. There are several examples on the the Espressif forum and Github, but none that fully explains how to code Arduino C++ that accepts two or more IDs. The examples show shift-left (<<) by various amounts (<<3, <<5, <<21). There is no indication in the documentation that there is more than one acceptance filter (One indication implies there are a possible of up to 8 filters, while the Espressif documentation implies there is only one filter that can be used in single or dual mode (that would allow 2 acceptance codes). If there is the possibility to use more than two filters in single filter mode, then I can add more IDs later. The code I have accumulated, based on various sources, is shown below. If you could adjust this code so it accepts only IDs 743 and 7DF, it would be very much appreciated.

/* ESP32 TWAI receive example.
  Receive messages and sends them over serial.
  Connect a CAN bus transceiver to the RX/TX pins.
  For example: SN65HVD230
  TWAI_MODE_LISTEN_ONLY is used so that the TWAI controller will not influence the bus.
  The API gives other possible speeds and alerts:
  https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-reference/peripherals/twai.html
  Example output:
  -> Message received
  -> Message is in Standard Format
  -> ID is 604
  -> Byte 0 = 0 Byte 1 = f Byte 2 = 13 Byte 3 = 2 Byte 4 = 0 Byte 5 = 0 Byte 6 = 8 Byte 7 = 0
  created 05-11-2022 by Stephan Martin (designer2k2)
*/

#include "driver/twai.h"

//Pins used to connect to CAN bus transceiver:
#define rxPin 4
#define txPin 5
#define CAN_PWM_ADDR		0x743			// address of PWM message from ECU (unsolicited)
	unsigned char rxBuf[8];						// read buffer
	byte data[8] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0xFE};	// write buffer

void setup() {
  // Start Serial:
  Serial.begin(115200);

  //Initialize configuration structures using macro initializers
  twai_general_config_t g_config = TWAI_GENERAL_CONFIG_DEFAULT((gpio_num_t)txPin, (gpio_num_t)rxPin, TWAI_MODE_LISTEN_ONLY);
  twai_timing_config_t t_config = TWAI_TIMING_CONFIG_500KBITS();  //Look in the api-reference for other speed sets.
  twai_filter_config_t f_config = TWAI_FILTER_CONFIG_ACCEPT_ALL();
  
// Configure acceptance code and mask for ID 0x743
	f_config.acceptance_code = 0x743 << 5;	// acceptance code for ID 743	
	f_config.acceptance_mask = 0x743 << 5;	// Mask with 11 bits set to 1 for full acceptance
	f_config.single_filter = true;			// single filter if "1", dual filter if "0"

// Configure acceptance code and mask for ID 0x7DF
	f_config.acceptance_code |= 0x7DF << 5; // Use bitwise OR to add the new acceptance code

/*  //Install TWAI driver (ChatGPT code) ***********************************************************
  if (twai_driver_install(&g_config, &t_config, &f_config) == ESP_OK) {
    Serial.println("Driver installed");
  } else {
    Serial.println("Failed to install driver");
    return;
  }
*/
  //Start TWAI driver
  if (twai_start() == ESP_OK) {
    Serial.println("Driver started");
  } else {
    Serial.println("Failed to start driver");
    return;
  }

  //Reconfigure alerts to detect Bus-Off error and RX queue full states
  uint32_t alerts_to_enable = TWAI_ALERT_ERR_PASS | TWAI_ALERT_BUS_ERROR | TWAI_ALERT_RX_QUEUE_FULL;
  if (twai_reconfigure_alerts(alerts_to_enable, NULL) == ESP_OK) {
    Serial.println("CAN Alerts reconfigured");
  } else {
    Serial.println("Failed to reconfigure alerts");
  }

}

void loop() 
{ //Check if alert happened
  uint32_t alerts_triggered;
  twai_read_alerts(&alerts_triggered, 1);
  if (alerts_triggered & TWAI_ALERT_ERR_PASS) {
    Serial.println("Alert: TWAI controller has become error passive.");
  } else if (alerts_triggered & TWAI_ALERT_BUS_ERROR) {
    Serial.println("Alert: A (Bit, Stuff, CRC, Form, ACK) error has occurred on the bus.");
  } else if (alerts_triggered & TWAI_ALERT_RX_QUEUE_FULL) {
    Serial.println("Alert: The RX queue is full causing a received frame to be lost.");
  }

  //Wait for message to be received:
  twai_message_t message;
  if (twai_receive(&message, pdMS_TO_TICKS(1000)) == ESP_OK) {
    Serial.println("Message received");
	twai_message_t message;
		
  } else {
    Serial.println("No message received");
    return;
  }

  //Process received message
  if (message.extd) {
    Serial.println("Message is in Extended Format");
  } else {
    Serial.println("Message is in Standard Format");
  }
  Serial.printf("ID is %x\n", message.identifier);
	if (!(message.rtr)) 
	{
	  
		if (message.identifier = CAN_PWM_ADDR)
		{	for (int i = 0; i < 8; i++)	
			{	Serial.printf("Byte %d = %x ", i, message.data[i]);
				rxBuf[i] = message.data[i];
			}
			Serial.println("");
// put application logic here to process the received message ID 743
		}
    }
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Status: Community help needed Issue need help from any member from the Community. Type: Example Issue is related to specific example.
Projects
Development

Successfully merging this pull request may close these issues.

7 participants