On This Page

CAN bus

What is your CAN bus utilization? 🔗

The Driver Station and the DS Logs will show you your CAN bus utilization rate. Often this is a fuzzy line that ranges up to 100%. This doesn’t necessarily mean that your CAN bus utilization is actually that high. The real value can be seen by zooming in (in the DS Log Viewer) to find the common, stable value. Typically it will be near the bottom of the fuzzy band.

How much is too high? 70% is fine. If you’re going much higher than that, you’re likely to be experiencing lost packets and various errors. If not, you should look elsewhere for your problem.

There are four main ways to fix a high CAN utilization. At a competition, they should probably be tried in this order.

Check your wiring 🔗

See CAN wiring basics

Adjusting frame rates 🔗

If you are having problems with high CAN bus utilization, consider turning down the frame rate. These are not general recommendations! Don’t do it if you’re not having trouble!

Motor controllers will typically have multiple types of status frame that can be controlled separately. Status frames have multiple uses:

The motor safety watchdog is an important case. It is recommended that you do not set such frames over 45ms. This means that you can drop the occasional frame without triggering it.

If a motor is under power/voltage control, or is using firmware PID control with no follower, then status frames can be less frequent.

REV Spark MAX 🔗

The Spark MAX has five different types of periodic status frame, but I believe a typical FRC setup will only use the first three.

E.g.

// Maximum reasonable values
leader.setPeriodicFrameRate(PeriodicFrame.kStatus0, 20);
leader.setPeriodicFrameRate(PeriodicFrame.kStatus1, 50);
leader.setPeriodicFrameRate(PeriodicFrame.kStatus2, 50);
follower.setPeriodicFrameRate(PeriodicFrame.kStatus0, 45);
follower.setPeriodicFrameRate(PeriodicFrame.kStatus1, 500);
follower.setPeriodicFrameRate(PeriodicFrame.kStatus2, 500);

CTRE Phoenix (e.g. Talon/Falcon, Pigeon, CANcoder) 🔗

Motor controllers (Talon/Falcon) 🔗

Ten different types, but two important ones:

// Maximum reasonable values
leader.setStatusFramePeriod(StatusFrameEnhanced.Status_1_General, 20);
leader.setStatusFramePeriod(StatusFrameEnhanced.Status_2_Feedback0, 50);
follower.setStatusFramePeriod(StatusFrameEnhanced.Status_1_General, 45);
follower.setStatusFramePeriod(StatusFrameEnhanced.Status_2_Feedback0, 500);

Switch motors to PWM 🔗

WPILIB How to wire PWM cables

  private final PWMSparkMax m_leftDrive = new PWMSparkMax(0);
  private final PWMSparkMax m_rightDrive = new PWMSparkMax(1);

Pass to DifferentialDrive or call .set().

Similarly for PWMTalonFX (Falcon 500) and PWMTalonSRX.

WPILIB Using PWN Motor Controllers

Additional hardware 🔗

CANivore 🔗

Might help. Introduces its own complexity. Doesn’t work with sysid.

CTRE Canivore Hardware Manual

CTRE Bring Up: CANivore

    TalonFX motor = new TalonFX(deviceNumber, canivoreName);

References and further reading 🔗