My team and me are developing our own CAN-Bus adapter. For now, based on the ESP32's integrated CAN-controller, later using an MCP2518fd. I wonder about the best way to auto-detect the configured bitrate on the bus.

Assuming that there is at least one other device on the Bus which is not configured for listen-only (i.e. will ACK every frame), shouldn't it be possible to send a probe message and check whether we sense an ACK? If not, try another rate and do again?

Note that we don't want to introduce extra-loopback-wiring for that.

  • 1
    \$\begingroup\$ You should get it, but will your CAN transceiver would return the ACK back to your controller? \$\endgroup\$
    – LordTeddy
    Commented May 16, 2023 at 14:41
  • \$\begingroup\$ @LordTeddy I would think so. AFAIK being able to sense ACKs is a requirement for managing the bus health. All CAN controllers are required to leave the bus, if they sense too many errors (bit, stuff, crc, ACK). \$\endgroup\$ Commented May 16, 2023 at 14:47
  • 1
    \$\begingroup\$ Yes, in general this is possible and has been done before (this document is about CANopen but also applies to vanilla CAN). Both active and passive detection are possible (the latter if there is already traffic on the bus you can sense). Without details on your CAN controller and bus setup, it's impossible to say more. \$\endgroup\$
    – TypeIA
    Commented May 16, 2023 at 14:54
  • 1
    \$\begingroup\$ Since it has not been proved impossible, and it seems that it has been already done before, you might want to edit the question to omit the "is it possible" part, as they rarely get great answers. \$\endgroup\$
    – Justme
    Commented May 16, 2023 at 15:12

2 Answers 2


For the records: I now have implemented this in a way where I can toggle between active and passive detection mode.

For both modes, I iterate over all possible bitrates with the chance of an early exit, if I receive a packet. In passive mode, I just configure the TWAI* controller to one of the bitrates, read alerts for up to one second, and inspect them. If I receive any bit error, I continue to the next bitrate. If I receive a valid frame, this is it.

* TWAI: Two-wire Automotive Interface (essentially CAN)

Active mode works the same except before reading the alerts, I'm sending an empty (DLC=0) frame to some identifier to trigger the alerts. The early exit is when I didn't see any bit errors after sending the frame.

Both variants work well, however the passive mode suffers from two problems:

  • If there is seldom traffic on the bus, we might miss it (depending on the read alert timeout) and fail.
  • If there is no traffic at all, we will definitely fail.

For our typical vehicle configurations, passive detection usually takes 2-3 seconds while active detection takes less than 100ms.

I did not see any adverse effects of using active detection yet.


The problem with this is that if you send a message with the wrong baudrate, you'll get some form or bit stuffing error. The CAN controller will then automatically try to resend, which causes 2 problems:

  • You disrupt the bus traffic severely.
  • You will end up in error passive/bus off state very quickly.

Not a good idea.

It is very easy to implement this in a non-distruptive way by routing the CAN rx line from the transceiver to an input capture timer pin on your MCU. Then simply measure the time from edge to edge, +/- some tolerance. Save the shortest measured bit length and let the measurement run for at least 600us = slowest baudrate 10kbps times 6 bit lengths, after which a stuffing bit is guaranteed. Optionally only allow the standardized baudrates as result.

This requires CAN traffic to be present on the bus however.

And this method doesn't only work for CAN but for any serial bus like UART etc.

  • \$\begingroup\$ Thanks, this is an interesting approach, although the 2 problems you mentioned are not shying me away, since this is what all OBD2 adapters also do (albeit on a higher level) during auto-protocol detection: Trying various bitrates and sending certain messages, then waiting for a device to answer. \$\endgroup\$ Commented May 16, 2023 at 15:30
  • \$\begingroup\$ I quite like this method as it scales to microcontrollers without auto-baud rate detection built into the peripheral (i.e. some STM32 UART peripherals have ABR). If your uC doesn't have UART RX and a timer peripheral mapped to the same pin, you could also short two pins together and ensure in software that one pin is always in Hi-Z mode \$\endgroup\$
    – Ocanath
    Commented May 16, 2023 at 17:43

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.