- At least two nodes must be connected to a CAN bus to make it work (exception to the rule is one node in a loop-back mode).
- Use twisted pair of wires for CAN bus.
- Terminate the CAN bus with 120 Ohm resistors at both ends.
- Try to connect all nodes to the same ground.
- Reduce stab length (distance between the CAN transceiver and the CAN bus lines) for all nodes as much as achievable (keep it less than 30cm).
- Make sure all nodes are set to use the same frequency. Please notice that you cannot use arbitrary frequency. Only selected frequencies are supported.
- Reduce the frequency for all nodes step by step (by selecting commonly used frequencies) until the number of bus errors is zero (or acceptable).
- To set the CAN bus frequency for STM targets in Mbed the following table is used to adjust the sampling point. See the the
can_speed()
function implemented in the can_api.c
file:
// The following table is used to program bit_timing. It is an adjustment of the sample
// point by synchronizing on the start-bit edge and resynchronizing on the following edges.
// This table has the sampling points as close to 75% as possible (most commonly used).
// The first value is TSEG1, the second TSEG2.
static const int timing_pts[23][2] = {
{0x0, 0x0}, // 2, 50%
{0x1, 0x0}, // 3, 67%
{0x2, 0x0}, // 4, 75%
{0x3, 0x0}, // 5, 80%
{0x3, 0x1}, // 6, 67%
{0x4, 0x1}, // 7, 71%
{0x5, 0x1}, // 8, 75%
{0x6, 0x1}, // 9, 78%
{0x6, 0x2}, // 10, 70%
{0x7, 0x2}, // 11, 73%
{0x8, 0x2}, // 12, 75%
{0x9, 0x2}, // 13, 77%
{0x9, 0x3}, // 14, 71%
{0xA, 0x3}, // 15, 73%
{0xB, 0x3}, // 16, 75%
{0xC, 0x3}, // 17, 76%
{0xD, 0x3}, // 18, 78%
{0xD, 0x4}, // 19, 74%
{0xE, 0x4}, // 20, 75%
{0xF, 0x4}, // 21, 76%
{0xF, 0x5}, // 22, 73%
{0xF, 0x6}, // 23, 70%
{0xF, 0x7}, // 24, 67%
};
As you can see, for some speeds the sampling point is closer to 75% than for others. So I think, some speeds are a bit more reliable than others.
Read this thread for a tip how to automatically recover from a bus-off mode (BOM). But please note that in Mbed OS 6 the ABOM
is set by the _can_init_freq_direct
function rather than by the can_init_freq
.