Power Delivery Board - USB-C (Qwiic) Hookup Guide a learn.sparkfun.com tutorial

Available online at: http://sfe.io/t1104

Contents

Introduction

USB Type-C brought two significant changes to the USB standard. The reversible connector eliminated the problem of trying to plug the connector in the right way every time. The second major change was allowing the flexibility to have USB power with an adjustable USB voltage from anywhere between 5V and 20V and up to 100W of power. The SparkFun Power Delivery Board takes advantage of the power delivery standard with the use of a standalone controller from STMicroelectronics, the STUSB4500. The controller does all the heavy lifting of power negotiation and provides an easy way to configure over I2C.

SparkFun Power Delivery Board - USB-C (Qwiic)

SparkFun Power Delivery Board - USB-C (Qwiic)

DEV-15801
$26.95
6

Required Materials

To follow along with this guide, you will need the following materials. You may not need everything, depending on what you have. Add it to your cart, read through the guide, and adjust the cart as necessary.

Additional Tools

You will also need a USB Type-C power adapter that supports power delivery and a power delivery Type-C cable which has thicker power wires in the cable. This will minimize voltage drops across the cable and heat up less under high current loads. The Power Delivery Board's voltages and available current output are limited by the power delivery adapter used. The cable and power adapter used in this guide is a 87W USB-C Power Adapter made by Apple, and supports 5.2V, 9V, 14.5V, and 20.3V.

⚡ Note: During testing we noticed a significant delay changing voltages with some power adapters that have both a USB Type-A fast charging plug as well as USB Type-C power delivery plug. We recommend getting a power adapter that supports power delivery that only has a USB Type-C connector.

Power Adapter output voltages highlight

Power Adapter Output Voltages

Suggested Reading

Before continuing on with this guide, you may want to familiarize yourself with some of these topics if they're unfamiliar to you. If you aren't familiar with the Qwiic system, we recommend reading here for an overview.

Qwiic Connect System
Qwiic Connect System

If you aren't familiar with the following concepts, we recommend checking out these tutorials before continuing. Make sure to install the appropriate drivers before uploading code. In this case, we'll need to make sure the CH340 driver are installed for the RedBoard Qwiic.

I2C

An introduction to I2C, one of the main embedded communications protocols in use today.

How to Use a Multimeter

Learn the basics of using a multimeter to measure continuity, voltage, resistance and current.

RedBoard Qwiic Hookup Guide

This tutorial covers the basic functionality of the RedBoard Qwiic. This tutorial also covers how to get started blinking an LED and using the Qwiic system.

How to Install CH340 Drivers

How to install CH340 drivers (if you need them) on Windows, Mac OS X, and Linux.

Hardware Overview

STUSB4500

When it comes to power delivery you have two types of power roles. The first is the provider, also known as the source, which is capable of providing power over the USB power bus. The other role is the consumer, also known as the sink, which draws power from the source.

The STUSB4500 is a USB Type-C and power delivery controller IC for sink applications. The controller is able to negotiate a power delivery contract with a source (ie a power delivery wall wart or power adapter) without the need for an external microcontroller, although you will need a microcontroller to configure the board. With this controller, we are taking advantage of STMicroelectronic's proprietary algorithms and configurable power data objects (PDOs) using integrated non-volatile memory (NVM). Its laundry list of features include:

Understanding how the power negotiation will be covered in the USB-C Power Negotiation section, but for right now, let's go over the board itself.

Power

The Power Delivery board can be powered in one of two ways, either through the USB Type-C connector, or with 3.3V from the Qwiic Connector if you just need to configure a new power delivery profile.

Highlight of Qwiic and USB type c connectors

I2C Pins

To configure the board, you will need an I2C bus. The Qwiic system makes it easy to connect the Power Delivery board to a microcontroller to set the NVM parameters to power your project via the Qwiic connector. Depending on your application, you can also connect to the I2C bus via the plated through holes for SDA and SCL.

Highlight of the Qwiic Connector

Qwiic Connector



Top View Bottom View

I2C PTH Pins

Pins

The board breaks out the following pins:

Pin Name Description
VIN This is the input power pin, which is connected to VBUS on the Type-C connector.
VSNK Power output enabled after successful power negotiation
VDD Optional logic power input, 3.0V - 5.5V
GND Ground
SCL I2C clock input
SDA I2C data input/output
D- USB 2.0 differential pair, negative
D+ USB 2.0 differential pair, positive
Alert I2C interrupt, active low open drain
Reset Reset input, active high
GPIO General purpose output, active low open drain
PDO2 Power contract flag for PDO2, active low open drain
PDO3 Power contract flag for PDO3, active low open drain

Image of the back of the board with the pins highlighted

IO Pins

Jumpers

The board has a few jumper pads to configure the I2C bus.

Address Select

The default address of the board is 0x28. If you need to adjust the address of the board, you can cut one or both of the address pads labels ADDR0 and ADDR1.

Highlight of the address select jumper

The table below lists the four jumper configurations along with the corresponding hexadecimal device address.

ADDR0 ADDR1 Device Address
Closed Closed 0x28 (default)
Open Closed 0x29
Closed Open 0x2A
Open Open 0x2B

Pull-Up Resistors

The board also includes jumpers to disable the pull-up resistors on the I2C bus. If you are using a few I2C devices on the same bus that already have pull-up resistors on their board, you may want to cut the jumpers to disconnect these pull-up resistors. The Power Delivery board utilizes non-volatile memory, the settings saved to device stay configured even if it loses power, so the only time this board needs to be connected over I2C is to modify the NVM parameters.

Highlighted section of the I2C Pullups

Dimensions

Dimensions of the Board exported from Eagle

USB-C Power Negotiation

Power Data Objects (PDOs)

The STUSB4500 has a set of user defined parameters that can be customized using the NVM re-programming through the I2C interface. This allows for changing the preset configuration of the power delivery interface and define new configurations based on specific application requirements.

On power-up, or after a hard reset, the NVM parameters are copied into the I2C registers and used by the controller during the system operation. After a soft reset, the controller will use the values saved in I2C registers to re-negotiate with the source. The controller can store up to three PDOs, with PDO3 having the highest priority and PDO1 having the lowest. After the NVM parameters have been copied to the I2C registers, the STUSB4500 will ask the source for it's capabilities to find a PDO match.

Each PDO has four parameters as shown in the table below:

Parameter Value Range Notes
Voltage 5 - 20 (V) PDO1 is fixed at 5V and cannot be changed.
Over Voltage Tolerance 5 - 20 (%) Sets the upper voltage tolerance. For example, say this parameter is set to 5% and the voltage is set to 9V. If the supply voltage goes above 9.45V, the output (VSNK) will turn off.
Under Voltage Tolerance 5 - 20 (%) Sets the lower voltage tolerance for PDO2 and PDO3 only. For example, say this parameter is set to 5%, and the voltage is set to 9V. If the supply voltage drops below 8.55V, the output (VSNK) will turn off. PDO1 has a fixed under voltage limit of 3.3V and cannot be changed.
Current 0 - 5 (A) 16 possible values, see setCurrent function in Arduino Library secton for exact values.


Each source might have a slightly different voltages listed on the case. One charger might advertise 12V, while another might advertise 12.3V perhaps to compensate for voltage drop across the cable, while another might say 11.5V to indicate the voltage at the end of the cable under the full load. Most sources though will advertise some combination of 5V, 9V, 12V, 15V, or 20V when negotiating with the consumer.

The current should be the maximum amount of current that the Power Delivery board expects to draw from the source. The STUSB4500 is not able to measure the actual current draw and will allow as much current as the source is able to deliver. If the current parameter is less than or equal to the max current the source advertised, the controller will send a request to source for that power profile. If the voltage or current parameters do not match with one of the capabilities of the source, the controller will try the next PDO to find a match with the source.

If the source accepts the contract, the source will switch from the defaulted VBUS voltage of 5V, to the voltage that was requested, and the VBUS_EN_SINK pin will be pulled low, and enable current to flow through the MOSFET which controls power to the VSNK power output pin.

Power Delivery Contract between Source and Sink

With the "U" in USB standing for Universal, when two devices are connected there are a bunch of messages sent between them to figure out what each device is connected to, and what each device supports. For the sake of simplicity, we're only going to look at the power delivery contract from a high level to understand what's going on.

Image of USB-C's 24 pins

Image courtesy of Chindi.ap, CC BY-SA 4.0

Of the 24 pins of the USB Type-C connector (shown above), the STUSB4500 only connects directly to 10 of these: 4 pins are used for VBUS, another 4 pins to ground, and the 2 channel configuration, or CC, pins. Depending on the cable orientation, one of these CC pins is used to send and receive messages between the sink and source. When a sink device connects to a source, the voltage on the VBUS starts off at 5V, just like the old USB standard.

Shortly after the source and sink are connected, the source will advertise it's capabilities as a power source, such as 5V@3A, 9V@2A, and any other power delivery options it's capable of. After that message is received, the controller will look at the PDO options available to find a match. Upon a match, the controller will ask for one of the voltage and current options. After the source accepts, the voltage is then switched to the voltage requested.

To find a match, the STUSB4500 controller first looks at the SNK_PDO_NUMB parameter, which is an integer value between 1 and 3, which corresponds to the highest priority PDO number. If the SNK_PDO_NUMB has a value of 3, it will first check to see if the source is able to provide PDO3, if not it will check PDO2, followed by PDO1. If SNK_PDO_NUMB has a value of 2, it will start by checking PDO2, followed by PDO1, and ignore PDO3. Finally if SNK_PDO_NUMB has a value of 1, it will only check PDO1. The two values the controller looks at to find a match are the voltage and current. As previously mentioned, most of the power delivery adapters will have a combination of 5V, 9V, 12V, 15V, and 20V. The packaging might say 5.2V or 20.3V, but in the capabilities message they'll actually specify 5V or 20V.

The other portion of the contract is the current being requested. If the voltage is accepted, but is only capable of delivering 1.5A of current at that voltage, but 2.0A of current was requested, that contract will be rejected by the source even though the source was capable of supplying that voltage. Alternatively, requesting 0.5A of current with a source capable of delivering 1.5A will be accepted. The amount of current requested should be about is expected for the project, but the source will allow the sink to draw more current than requested, up to the limit of that power delivery option.

Hardware Hookup

This is an I2C based board, which allows us to include a Qwiic connector on the breakout board. Hooking up the device is easy, just plug one end of the Qwiic cable into the Power Delivery board and the other to your development board. In this case it's the RedBoard Qwiic.

redboard qwiic with power delivery board

Note: If you've never connected an CH340 device to your computer before, you may need to install drivers for the USB-to-serial converter. Check out our section on How to Install CH340 Drivers" for help with the installation.

How to Install CH340 Drivers

August 6, 2019

How to install CH340 drivers (if you need them) on Windows, Mac OS X, and Linux.

Suppling power to your project can be accomplished in couple of ways. The board provides breadboard friendly 0.1 inch spacing, along with 3.5mm screw terminal spacing. If you're new to soldering, refer to our How To Solder Tutorial.

Highlight of output power pins

After the board has been configured, the Qwiic connector can be removed, and the board will remember the settings even after power is disconnected. With those connections out of the way, it's time to configure the board!

Arduino Library

Note: This example assumes you are using the latest version of the Arduino IDE on your desktop. If this is your first time using Arduino, please review our tutorial on installing the Arduino IDE. If you have not previously installed an Arduino library, please check out our installation guide.

SparkFun has written a library to control the Power Delivery board for the STUSB4500. You can obtain this library through the Arduino Library Manager. By searching for STUSB4500, you should see one written by SparkFun Electronics and you should be able to install the latest version. If you prefer downloading libraries manually, you can grab them from the GitHub Repository.

Download the SparkFun Power Delivery Board - USB-C Arduino Library (ZIP)

Functions

The library has a ton of functions available for reading each of the NVM parameters for the Power Delivery board. Below is a list of the functions available along with a description of what each function does and how to use it.

ADDR0 ADDR1 Device Address
Closed Closed 0x28 (default)
Open Closed 0x29
Closed Open 0x2A
Open Open 0x2B


Pin State
Description
Configuration1 VBUS_EN_SNK Hi-Z No Source Attached
0 Source Attached
POWER_OK2 Hi-Z No functionality
POWER_OK3 Hi-Z No functionality
Configuration2 VBUS_EN_SNK Hi-Z No Source Attached
0 Source Attached
POWER_OK2 Hi-Z No explicit PD contract
0 PD explicit contract with PDO2
POWER_OK3 Hi-Z No explicit PD contract
0 PD explicit contract with PDO3
Configuration3 VBUS_EN_SNK Hi-Z No Source Attached
0 Source Attached
POWER_OK2 Hi-Z No source attached or source supplies default USB Type-C current at 5V when source attached.
0 Source supplies 3.0A USB Type-C current at 5V when source is attached.
POWER_OK3 Hi-Z No source attached or source supplies default USB Type-C current at 5V when source attached.
0 Source supplies 1.5A USB Type-C current at 5V when source is attached.

*

Note: For configuration 3: "Source supplies 1.5A/3.0A USB Type-C current at 5V when source is attached" is based on what the source advertises when the cable is connected and does not indicate that the output voltage is actually 5V.
Value GPIO Function Function Value Description
0 Software Controlled GPIO The output state is controlled by the value stored in bit-0 of I2C register 0x2D Hi-Z When the value of bit-0 is 0 (default at start-up)
0 When the value of bit-0 is 1
1 Error Recovery Hardware fault detection such as over temperature, over voltage on the CC pins, or after a hard reset Hi-Z No hardware fault detected
0 Hardware fault detected
2 Debug Debug accessory detection (Refer to section 3.8 of datasheet for more information) Hi-Z No debug accessory detected
0 Debug accessory detected
3 Sink Power Indicates USB Type-C current capability advertised by the source Hi-Z Source supplies default or 1.5A USB Type-C current at 5V
0 Source supplies 3.0A USB Type-C current at 5V

*

Note: For value 3 - Sink Power: "Source supplies 1.5A/3.0A USB Type-C current at 5V when source is attached" is based on what the source advertises when the cable is connected and does not indicate that the output voltage is actually 5V.

Arduino Library Examples

In these examples, we'll connect our Power Delivery board to a RedBoard Qwiic using a Qwiic cable. The Type-C power adapter used in these examples is an Apple 87W USB-C Power Adapter which has an output of 20.3V/4.3A, or 14.5V/2A, or 9V/3A, or 5.2V/2.4A.

Example 1: Reading the NVM Values

In this first example we'll see what settings are currently saved in the board. For this example you don't need to connect to your USB cable, the only connection needed is VDD, GND, SCL, and SDA (which the Qwiic cable will provide).

After the library has been installed, access the first example from your Arduino menu by clicking on: File > Examples > SparkFun STUSB4500 > Example1-ReadParameters. Select your board (in this case Arduino Uno) and COM port that the board enumerated to. Hit the upload button. Open the serial monitor at 115200 baud to see what the current settings are.

Photo of COM port after read parameters example has been uploaded

The STUSB4500 is able to store up to three power data objects, or PDOs. Each PDO contains the voltage and current to be requested, along with the voltage tolerance. We can see that the PDO number parameter is set to 3, which means that when we plug in the power adapter, the board will first try to find a power option that matches PDO3, which has a voltage of 20.00V, and maximum current draw of 1.0A. If the power adapter is able to provide at least 1.0A of current at 20.00V, the contract will be accepted by the source and switch to the higher voltage. If the output voltage falls outside of the tolerance window of +10% or -20% (16-22V), the sink controller will disconnect from the source and reset. However, if PDO3 does not match with the source, it will try PDO2's parameters, and if a match is still not made the voltage would stay at 5V.

Flex current is set to 2.00A, but since none of the PDOs have a current set to 0, that value will not be used. We also see that the board is not expecting an external source of power, nor does it expect the source to support USB communication. The Configuration OK GPIOs are set to 2, which will mean that when a source is connected, if the contract for PDO2 or PDO3 is accepted, the LED corresponding to that PDO will turn on. GPIO control is set to 1, which means the GPIO LED is currently configured for error recovery indication. The enable power only above 5V bit is not set, so the output voltage will briefly be at 5V, but will increase after a contract is accepted. Lastly we see that the request source current bit is not set.

Now that we know what the board is configured for, in our next example we'll configure the board based on the capabilities of our power adapter.

Example 2: Setting NVM Values

In this example we'll modify the NVM values. The code listed below is NOT the same as the SetParameters example in Arduino - below we set actual values, whereas the SetParameters example is a template for your future use.

For this example we'll need to use a power delivery source, which is a 87W USB-C Power Adapter made by Apple, but there are plenty of other adapters available that provide a range of voltages. The power adapter should have a label that describes the input and output power capabilities as shown below.

Photo of apple charger

The input power is 100-240 VAC and up to 1.5A of primary current. The output can provide one of the following: 20V/4.3A, or 15V/2A, or 9V/3A, or 5V/2.4A. Based on these options, let's change the voltage to 15V. That voltage option is able to draw up to 2A of current. The current requested can only go up to that value for the power delivery contract to be accepted. The increased voltage of 15.3V instead of 15.0V is labeled based on the actual output voltage, but the source should advertise 15.0V. The increase is to compensate for voltage drop across the cable under heavy current draw. The settings we're going to change though are:

Copy the code below into your Arduino IDE and upload it to your board. After the code has been uploaded, open your serial port and verify the changes were applied.

language:c
/*
  Writing New Settings to the STUSB4500 Power Delivery Board
  By: Alex Wende
  SparkFun Electronics
  Date: February 6th, 2020
  License: This code is public domain but you buy me a beer if you use this and we meet someday (Beerware license).
  Feel like supporting our work? Buy a board from SparkFun!
  https://www.sparkfun.com/products/15801

  This example demonstrates how to write new NVM settings to the STUSB4500

  Quick-start:
  - Use a SparkFun RedBoard Qwiic -or- attach the Qwiic Shield to your Arduino/Photon/ESP32 or other
  - Upload example sketch
  - Plug the Power Delivery Board onto the RedBoard/shield
  - Open the serial monitor and set the baud rate to 115200
  - The RedBoard will connect to the Power Delivery Board over I2C write the settings:
    * PDO Number: 3
    * PDO3 Voltage: 15.00V
    * PDO3 Current: 0.5A
    * PDO3 Under Voltage Lock Out: 20%
    * PDO3 Over Voltage Lock Out: 20%
  - After the settings are written, the old settings are printed out and then the new settings are printed  
*/
// Include the SparkFun STUSB4500 library.
// Click here to get the library: http://librarymanager/All#SparkFun_STUSB4500

#include <Wire.h>
#include <SparkFun_STUSB4500.h>

STUSB4500 usb;

void setup()
{
  Serial.begin(115200);
  Wire.begin(); //Join I2C Bus
  delay(500);

  /* The Power Delivery board uses the default settings with address 0x28 using Wire.

     Opionally, if the address jumpers are modified, or using a different I2C bus,
     these parameters can be changed here. E.g. usb.begin(0x29,Wire1)

     It will return true on success or false on failure to communicate. */
  if(!usb.begin())
  {
    Serial.println("Cannot connect to STUSB4500.");
    Serial.println("Is the board connected? Is the device ID correct?");
    while(1);
  }

  Serial.println("Connected to STUSB4500!");
  delay(100);

  float voltage, current;
  byte lowerTolerance, upperTolerance, pdoNumber;

  pdoNumber = usb.getPdoNumber();
  voltage = usb.getVoltage(3);
  current = usb.getCurrent(3);
  lowerTolerance = usb.getLowerVoltageLimit(3);
  upperTolerance = usb.getUpperVoltageLimit(3);

  /* Since we're going to change PDO3, we'll make sure that the
     STUSB4500 tries PDO3 by setting PDO3 to the highest priority. */
  usb.setPdoNumber(3);

  /* PDO3
   - Voltage 5-20V
   - Current value for PDO3 0-5A, if 0 used, FLEX_I value is used
   - Under Voltage Lock Out (setUnderVoltageLimit) 5-20%
   - Over Voltage Lock Out (setUpperVoltageLimit) 5-20%
  */
  usb.setVoltage(3,15.0);
  usb.setCurrent(3,0.5);
  usb.setLowerVoltageLimit(3,20);
  usb.setUpperVoltageLimit(3,20);

  /*Write and save settings to STUSB4500*/
  usb.write();

  /*Read settings saved to STUSB4500*/
  usb.read();

  Serial.println();

  /*Print old setting*/
  Serial.println("Original Values:");
  Serial.print("PDO Number: ");
  Serial.println(pdoNumber);
  Serial.print("Voltage3 (V): ");
  Serial.println(voltage);
  Serial.print("Current3 (A): ");
  Serial.println(current);
  Serial.print("Lower Voltage Tolerance3 (%): ");
  Serial.println(lowerTolerance);
  Serial.print("Upper Voltage Tolerance3 (%): ");
  Serial.println(upperTolerance);

  Serial.println();

  /*Print new settings*/
  Serial.println("New Values:");
  Serial.print("PDO Number: ");
  Serial.println(usb.getPdoNumber());
  Serial.print("Voltage3 (V): ");
  Serial.println(usb.getVoltage(3));
  Serial.print("Current3 (A): ");
  Serial.println(usb.getCurrent(3));
  Serial.print("Lower Voltage Tolerance3 (%): ");
  Serial.println(usb.getLowerVoltageLimit(3));
  Serial.print("Upper Voltage Tolerance3 (%): ");
  Serial.println(usb.getUpperVoltageLimit(3));
}

void loop()
{
}

After the code has uploaded, open the serial monitor at 115200 baud and make sure the settings were applied, as shown below.

Photo of COM port after NVM parameters write example has been uploaded

Reset the Power Delivery board and connect the USB-C cable. If the contract was accepted, the yellow LED for PDO3 should be on. With a multimeter, verify the voltage is around 15V as shown below. If the LED turns off, press the reset button and board should switch to the correct voltage.

photo showing yellow led and 15V output

Click the image for a closer view.

Example 3: Changing Voltages on the Fly

In this example we will use the soft reset function to force the STUSB4500 to re-negotiate with the power delivery source. Using the same power supply as the previous example, we have 5, 9, 12, 15, and 20V available. If you’re following along from the previous example, the Power Delivery board will initially negotiate for 15V, then the voltage will change to 9V, followed by 12V, and then 5V before looping back to 9V about every three seconds.

Copy the code below into your Arduino IDE and upload to your board, or you can load Example 4-ChangingVoltages from the examples menu for the SparkFun STUSB4500 library.

language:c
/*
  Changing Output Voltage on the Fly
  By: Alex Wende
  SparkFun Electronics
  Date: February 16th, 2021
  License: This code is public domain but you buy me a beer if you use this and we meet someday (Beerware license).
  Feel like supporting our work? Buy a board from SparkFun!
  https://www.sparkfun.com/products/15801

  This example demonstrates how to change the STUSB4500 output voltage without cycling power or pressing the
  reset button for the STUSB4500. Note that the STUSB4500 is not a voltage regulator, the voltages the board is 
  capable of outputting are only those supported by the USB-C power adapter connected.

  Quick-start:
  - Use a SparkFun RedBoard Qwiic -or- attach the Qwiic Shield to your Arduino/Photon/ESP32 or other
  - Modify the voltages to match those supported by the power adapter (most common are 5,9,12,15,20V)
  - Upload the sketch
  - Plug the Power Delivery Board onto the RedBoard/shield
  - Open the serial monitor and set the baud rate to 115200
  - The RedBoard will connect to the Power Delivery Board over I2C and print out all of the settings saved.
*/

// Include the SparkFun STUSB4500 library.
// Click here to get the library: http://librarymanager/All#SparkFun_STUSB4500

#include <Wire.h>
#include <SparkFun_STUSB4500.h>

STUSB4500 usb;

void setup() 
{
  Serial.begin(115200);
  Wire.begin(); //Join I2C bus

  delay(500);

  /* The Power Delivery board uses the default settings with address 0x28 using Wire.

     Opionally, if the address jumpers are modified, or using a different I2C bus,
     these parameters can be changed here. E.g. usb.begin(0x29,Wire1)

     It will return true on success or false on failure to communicate. */
  if(!usb.begin())
  {
    Serial.println("Cannot connect to STUSB4500.");
    Serial.println("Is the board connected? Is the device ID correct?");
    while(1);
  }

  Serial.println("Connected to STUSB4500!");
  delay(100);

  /* Read the settings saved to the NVM map*/
  usb.read();

  /* Read the Power Data Objects (PDO) highest priority */
  Serial.print("PDO Number: ");
  Serial.println(usb.getPdoNumber());

  /* Read settings for PDO1 */
  Serial.println();
  Serial.print("Voltage1 (V): ");
  Serial.println(usb.getVoltage(1));
  Serial.print("Current1 (A): ");
  Serial.println(usb.getCurrent(1));
  Serial.print("Lower Voltage Tolerance1 (%): ");
  Serial.println(usb.getLowerVoltageLimit(1));
  Serial.print("Upper Voltage Tolerance1 (%): ");
  Serial.println(usb.getUpperVoltageLimit(1));
  Serial.println();

  /* Read settings for PDO2 */
  Serial.print("Voltage2 (V): ");
  Serial.println(usb.getVoltage(2));
  Serial.print("Current2 (A): ");
  Serial.println(usb.getCurrent(2));
  Serial.print("Lower Voltage Tolerance2 (%): ");
  Serial.println(usb.getLowerVoltageLimit(2));
  Serial.print("Upper Voltage Tolerance2 (%): ");
  Serial.println(usb.getUpperVoltageLimit(2));
  Serial.println();

  /* Read settings for PDO3 */
  Serial.print("Voltage3 (V): ");
  Serial.println(usb.getVoltage(3));
  Serial.print("Current3 (A): ");
  Serial.println(usb.getCurrent(3));
  Serial.print("Lower Voltage Tolerance3 (%): ");
  Serial.println(usb.getLowerVoltageLimit(3));
  Serial.print("Upper Voltage Tolerance3 (%): ");
  Serial.println(usb.getUpperVoltageLimit(3));
  Serial.println();

  /* Read the flex current value */
  Serial.print("Flex Current: ");
  Serial.println(usb.getFlexCurrent());

  /* Read the External Power capable bit */
  Serial.print("External Power: ");
  Serial.println(usb.getExternalPower());

  /* Read the USB Communication capable bit */
  Serial.print("USB Communication Capable: ");
  Serial.println(usb.getUsbCommCapable());

  /* Read the POWER_OK pins configuration */
  Serial.print("Configuration OK GPIO: ");
  Serial.println(usb.getConfigOkGpio());

  /* Read the GPIO pin configuration */
  Serial.print("GPIO Control: ");
  Serial.println(usb.getGpioCtrl());

  /* Read the bit that enables VBUS_EN_SNK pin only when power is greater than 5V */
  Serial.print("Enable Power Only Above 5V: ");
  Serial.println(usb.getPowerAbove5vOnly());

  /* Read bit that controls if the Source or Sink device's 
     operating current is used in the RDO message */
  Serial.print("Request Source Current: ");
  Serial.println(usb.getReqSrcCurrent());
}

void loop()
{
  /*
   * The output voltage shouldn't change yet. This is because
   * the soft reset function needs to called to take affect.
  */
  Serial.println("\nSet PDO3 to 9V (nothing should happen)");
  usb.setPdoNumber(3); //Make sure PDO3 is set to the highest priority for this example
  usb.setVoltage(3,9.0);
  delay(3000);

  // Now the voltage should change to 9V after calling the softReset function
  Serial.println("Performing a soft reset should now let the voltage change");
  usb.softReset();
  delay(3000);

  // Let's try changing to 12V now
  Serial.println("Setting PDO3 to 12V");
  usb.setVoltage(3,12.0);
  usb.softReset();
  delay(3000);

  /* 
   *  Instead of writing a voltage, you can also just change the PDO number,
   *  and then call softReset.
   *  
   *  USB PD must be able to support at least 5V. As a result, PDO1 is fixed
   *  at 5V and cannot be changed. Switching to PDO1 is a fast and easy way
   *  swap to 5V without having to set the voltage to 5V.
  */
  Serial.println("Switching to PDO1");
  usb.setPdoNumber(1);
  usb.softReset();
  delay(3000);
}

After the code has been uploaded, open the serial monitor at 115200 baud, and you should see something like this:

Photo of serial monitor after changing the voltages

The softReset function forces the STUSB4500 to re-negotiate with the source using the values saved in the I2C registers, not the NVM registers. When the voltage is changed in the highest priority PDO register and a soft reset is performed the Power Delivery board re-negotiates with new voltage and current values. If you want to flip between the three different PDO values, you can change the value of the setPdoNumber function instead changing the voltage or current values.

It’s important to mention that these values are not saved to the NVM registers unless the write function is called. So after a hard reset using the reset button or pin, or after a power cycle, the values saved in the NVM registers get copied into the PDO registers.

Troubleshooting

Resources and Going Further

Can't get enough details of our Power Delivery Board? Check out these resources:

Need inspiration? Check out some of our power-related tutorials:

INA169 Breakout Board Hookup Guide

How to interface with the INA169 Breakout Board to measure current.

Wireless Joystick Hookup Guide

A hookup guide for the SparkFun Wireless Joystick Kit.

Nuclear Battery Assembly Guide

How to put together your BYOT (Bring Your Own Tritium) Nuclear Battery Kit!

Qwiic Quad Relay Hookup Guide

SparkFun’s Qwiic Quad Relay is a product designed for switching not one but four high powered devices from your Arduino or other low powered microcontroller using I2C.

learn.sparkfun.com | CC BY-SA 3.0 | SparkFun Electronics | Niwot, Colorado