- FRC Game Manual
- FRC Game Q&A

# Power Distribution Module

The CTRE Power Distribution Panel (PDP) and Rev Power Distribution Hub (PDH) can use their CAN connectivity to communicate a wealth of status information regarding the robot’s power use to the roboRIO, for use in user code. This has the capability to report current temperature, the bus voltage, the total robot current draw, the total robot energy use, and the individual current draw of each device power channel. This data can be used for a number of advanced control techniques, such as motor torque limiting and brownout avoidance.

## Creating a Power Distribution Object

To use the either Power Distribution module, create an instance of the `PowerDistribution` class (Java, C++, `Python`). With no arguments, the Power Distribution object will be detected, and must use CAN ID of 0 for CTRE or 1 for REV. If the CAN ID is non-default, additional constructors are available to specify the CAN ID and type.

JAVA

    PowerDistribution examplePD = new PowerDistribution();
    PowerDistribution examplePD = new PowerDistribution(0, ModuleType.kCTRE);
    PowerDistribution examplePD = new PowerDistribution(1, ModuleType.kRev);

C++

    PowerDistribution examplePD{};
    PowerDistribution examplePD{0, frc::PowerDistribution::ModuleType::kCTRE};
    PowerDistribution examplePD{1, frc::PowerDistribution::ModuleType::kRev};

PYTHON

    from wpilib import PowerDistribution
    examplePD = PowerDistribution()
    examplePD = PowerDistribution(0, PowerDistribution.ModuleType.kCTRE)
    examplePD = PowerDistribution(1, PowerDistribution.ModuleType.kRev)

Note: it is not necessary to create a PowerDistribution object unless you need to read values from it. The board will work and supply power on all the channels even if the object is never created.

## Reading the Bus Voltage

JAVA

        // Get the voltage going into the PDP, in Volts.
        // The PDP returns the voltage in increments of 0.05 Volts.
        double voltage = m_pdp.getVoltage();
        SmartDashboard.putNumber("Voltage", voltage);

C++

        // Get the voltage going into the PDP, in Volts.
        // The PDP returns the voltage in increments of 0.05 Volts.
        double voltage = m_pdp.GetVoltage();
        frc::SmartDashboard::PutNumber("Voltage", voltage);

PYTHON

            # Get the voltage going into the PDP, in Volts.
            # The PDP returns the voltage in increments of 0.05 Volts.
            voltage = self.pdp.getVoltage()
            wpilib.SmartDashboard.putNumber("Voltage", voltage)

Monitoring the bus voltage can be useful for (among other things) detecting when the robot is near a brownout, so that action can be taken to avoid brownout in a controlled manner. See the roboRIO Brownouts document for more information.

## Reading the Temperature

JAVA

        // Retrieves the temperature of the PDP, in degrees Celsius.
        double temperatureCelsius = m_pdp.getTemperature();
        SmartDashboard.putNumber("Temperature", temperatureCelsius);

C++

        // Retrieves the temperature of the PDP, in degrees Celsius.
        double temperatureCelsius = m_pdp.GetTemperature();
        frc::SmartDashboard::PutNumber("Temperature", temperatureCelsius);

PYTHON

            # Retrieves the temperature of the PDP, in degrees Celsius.
            temperatureCelsius = self.pdp.getTemperature()
            wpilib.SmartDashboard.putNumber("Temperature", temperatureCelsius)

Monitoring the temperature can be useful for detecting if the robot has been drawing too much power and needs to be shut down for a while, or if there is a short or other wiring problem.

## Reading the Total Current, Power, and Energy

JAVA

        // Get the total current of all channels.
        double totalCurrent = m_pdp.getTotalCurrent();
        SmartDashboard.putNumber("Total Current", totalCurrent);

        // Get the total power of all channels.
        // Power is the bus voltage multiplied by the current with the units Watts.
        double totalPower = m_pdp.getTotalPower();
        SmartDashboard.putNumber("Total Power", totalPower);

        // Get the total energy of all channels.
        // Energy is the power summed over time with units Joules.
        double totalEnergy = m_pdp.getTotalEnergy();
        SmartDashboard.putNumber("Total Energy", totalEnergy);

C++

        // Get the total current of all channels.
        double totalCurrent = m_pdp.GetTotalCurrent();
        frc::SmartDashboard::PutNumber("Total Current", totalCurrent);

        // Get the total power of all channels.
        // Power is the bus voltage multiplied by the current with the units Watts.
        double totalPower = m_pdp.GetTotalPower();
        frc::SmartDashboard::PutNumber("Total Power", totalPower);

        // Get the total energy of all channels.
        // Energy is the power summed over time with units Joules.
        double totalEnergy = m_pdp.GetTotalEnergy();
        frc::SmartDashboard::PutNumber("Total Energy", totalEnergy);

PYTHON

            # Get the total current of all channels.
            totalCurrent = self.pdp.getTotalCurrent()
            wpilib.SmartDashboard.putNumber("Total Current", totalCurrent)

            # Get the total power of all channels.
            # Power is the bus voltage multiplied by the current with the units Watts.
            totalPower = self.pdp.getTotalPower()
            wpilib.SmartDashboard.putNumber("Total Power", totalPower)

            # Get the total energy of all channels.
            # Energy is the power summed over time with units Joules.
            totalEnergy = self.pdp.getTotalEnergy()
            wpilib.SmartDashboard.putNumber("Total Energy", totalEnergy)

Monitoring the total current, power, and energy can be useful for controlling how much power is being drawn from the battery, both for preventing brownouts and ensuring that mechanisms have sufficient power available to perform the actions required. Power is the bus voltage multiplied by the current with the units Watts. Energy is the power summed over time with units Joules.

## Reading Individual Channel Currents

The PDP/PDH also allows users to monitor the current drawn by the individual device power channels. You can read the current on any of the 16 PDP channels (0-15) or 24 PDH channels (0-23).

JAVA

        // Get the current going through channel 7, in Amperes.
        // The PDP returns the current in increments of 0.125A.
        // At low currents the current readings tend to be less accurate.
        double current7 = m_pdp.getCurrent(7);
        SmartDashboard.putNumber("Current Channel 7", current7);

C++

        // Get the current going through channel 7, in Amperes.
        // The PDP returns the current in increments of 0.125A.
        // At low currents the current readings tend to be less accurate.
        double current7 = m_pdp.GetCurrent(7);
        frc::SmartDashboard::PutNumber("Current Channel 7", current7);

PYTHON

            # Get the current going through channel 7, in Amperes.
            # The PDP returns the current in increments of 0.125A.
            # At low currents the current readings tend to be less accurate.
            current7 = self.pdp.getCurrent(7)
            wpilib.SmartDashboard.putNumber("Current Channel 7", current7)

Monitoring individual device current draws can be useful for detecting shorts or stalled motors.

## Using the Switchable Channel (PDH)

The REV PDH has one channel that can be switched on or off to control custom circuits.

JAVA

    examplePD.setSwitchableChannel(true);
    examplePD.setSwitchableChannel(false);

C++

    examplePD.SetSwitchableChannel(true);
    examplePD.SetSwitchableChannel(false);

PYTHON

    examplePD.setSwitchableChannel(True)
    examplePD.setSwitchableChannel(False)