SmartDashboard#
Overview#
In this section we will be going over
- What SmartDashboard is and how it connects to your dashboard
- How to put (publish) data from the robot to the dashboard
- How to get (read) data from the dashboard on the robot
- Common patterns: telemetry display and live tuning
What is SmartDashboard#
- SmartDashboard is a WPILib class that lets your robot publish and read values over NetworkTables — a key-value store shared between the robot and any connected driver-station application
- Every value is stored under a key, which is a string name you choose — both the robot code and the dashboard use the same key to refer to the same value
- Data you publish appears on any dashboard that reads NetworkTables, including Elastic, Shuffleboard, and the built-in SmartDashboard app — no code changes are needed to switch between them
- You publish data using
putmethods and read it back usinggetmethods
Tip
To use SmartDashboard, add this import to any file that calls it:
Putting Data#
Use put methods to send data from the robot to the dashboard. Call these in a periodic method so the dashboard always shows the current values.
putNumber#
Publishes a double value under a key. Use this for any numeric sensor reading such as encoder positions, velocities, or voltages.
SmartDashboard.putNumber("Drive Encoder Count", encoder.getPosition());
SmartDashboard.putNumber("Shooter RPM", shooter.getVelocity());
putBoolean#
Publishes a boolean value. Use this for limit switches, sensors, and any true/false state on the robot.
SmartDashboard.putBoolean("Shooter Switch", shooter.isAtLimit());
SmartDashboard.putBoolean("Is Intaking", isIntaking);
putString#
Publishes a String. Use this for robot state names, mode descriptions, or any text you want to display.
SmartDashboard.putString("Robot State", "Idle");
SmartDashboard.putString("Drive Mode", "Arcade");
putData#
Publishes a Command as a clickable button on the dashboard, or a Sendable object (such as a subsystem or PID controller) as an interactive widget.
// Add a button to run a command from the dashboard
SmartDashboard.putData("Reset Drive Encoder", new DriveResetEncoder());
SmartDashboard.putData("Shoot", new ShootCommand());
// Send a subsystem for its built-in widget
SmartDashboard.putData("Drivetrain", m_drivetrain);
Tip
Commands registered with putData show up as buttons in Elastic and Shuffleboard. Clicking the button schedules the command on the robot — useful for testing subsystems during development without needing driver input.
Getting Data#
Use get methods to read values from the dashboard into the robot. Every get method requires a default value, which is returned when the key does not exist yet or no dashboard has sent a value.
getNumber#
Returns a double stored under the given key.
double voltage = SmartDashboard.getNumber("Feeder Voltage", 6.0);
motor.setVoltage(voltage);
getBoolean#
Returns a boolean stored under the given key.
getString#
Returns a String stored under the given key.
Always Provide a Safe Default
The default value is used the very first time the code runs, before any dashboard is connected. Choose a default that keeps the robot safe — for example, a voltage of 0.0 rather than a large value — so the robot behaves correctly even if the dashboard has never sent a value.
Common Patterns#
Telemetry — Monitoring Robot State#
The most common use of SmartDashboard is publishing sensor data so you can watch what the robot is doing in real time.
- In the constructor, register command buttons with
putData - In the update method, publish sensor readings with
putNumberandputBoolean - Call
update()at the end of each periodic method inRobot.java
public class Telemetry extends Subsystem {
// Put methods for controlling this subsystem
// here. Call these from Commands.
public Telemetry() {
// Drivetrain
SmartDashboard.putData("Reset Drive Encoder", new DriveResetEncoder());
// Shooter
SmartDashboard.putData("Shooter Up", new ShooterUp());
SmartDashboard.putData("Shooter Down", new ShooterDown());
SmartDashboard.putData("Shooter Up Auto", new ShooterUpAuto());
}
public void update() {
// Drivetrain
SmartDashboard.putNumber("Drive Encoder Count", Robot.m_drivetrain.getDriveEncoderCount());
// Shooter
SmartDashboard.putBoolean("Shooter Switch", Robot.m_shooter.isShooterSwitchClosed());
}
@Override
public void initDefaultCommand() {
// Set the default command for a subsystem here.
// setDefaultCommand(new MySpecialCommand());
}
}
Why call update() in periodic methods instead of robotPeriodic?
robotPeriodic runs at the very start of every loop, before the command scheduler runs. Putting update() there means the displayed values lag one cycle behind. By calling update() in disabledPeriodic, autonomousPeriodic, and teleopPeriodic, the dashboard reflects the most current values after all commands have finished executing for that loop.
Live Tuning — Adjusting Values Without Redeploying#
SmartDashboard lets you change a value on a running robot from the dashboard and see the effect immediately, without redeploying code. The pattern is:
- In the constructor, call
putNumberonce to publish the starting value so the dashboard shows it right away - In your methods, call
getNumbereach time you need the value instead of using a hardcoded constant
public class MySubsystem extends SubsystemBase {
private static final double DEFAULT_VOLTAGE = 6.0;
public MySubsystem() {
// Publish starting value once so the dashboard shows it immediately
SmartDashboard.putNumber("Motor Voltage", DEFAULT_VOLTAGE);
}
public void run() {
// Read the current dashboard value every time
double voltage = SmartDashboard.getNumber("Motor Voltage", DEFAULT_VOLTAGE);
motor.setVoltage(voltage);
}
}
Only call putNumber once when live tuning
In the live tuning pattern, only call put in the constructor. Calling put inside a periodic method or run() will overwrite whatever value the dashboard operator entered, making live tuning impossible.
Tip
Once you've found values you're happy with, copy them back into your Constants.java file so they are permanently saved. Dashboard values are not persisted between robot reboots unless you use the Preferences API — see RobotPreferences for long-term storage.