Lab 03b: Power

The questions below are due on Tuesday February 20, 2018; 08:25:00 PM.

Partners: You have not yet been assigned a partner for this lab.
You are not logged in.

If you are a current student, please Log In for full access to the web site.
Note that this link will take you to an external site ( to authenticate, and then you will be redirected back to this page.

Music for this Lab


A portion of today's Lab will involve bright flashing lights. This may potentially trigger seizures for people with photosensitive epilepsy. If this is cause for concern, let the staff know and we can make arrangements.


Today, we'll be integrating our battery management board into our system. We'll go over some safety instructions, discuss the source(s) and sink(s) of power when our system is in various states, and look at two different ways to control the power provided to a high-brightness LED.

This is the day you get your Lithium Polymer Battery. This is the reason we have those awesome lunchboxes—they can suppress fire. Treat your battery with care. Make sure you see the lecture notes from this past week on battery safety.

1) Getting Started

Download today's code distribution FROM HERE. Inside you will find several folders:

  • adp5350: This is a library we will use to communicate with our battery management board. Install it in your Arduino environment by placing it in your */Documents/Arduino/libraries/ folder, just like we did with the IMU library from Lab 02A.
  • battery_voltage_readout.ino: This is a short script that turns on the charger functionality and prints out the sensed voltage from the battery to both the OLED and the Serial monitor. It will serve as a simple way to make sure you have your system hooked up properly.
  • LDO3_control.ino: This is a starter script for the last portion of the lab where we will control a higher-power device (a white LED). As it is provided, it'll cycle through a number of output voltages at one of the outputs of our battery management board. We'll eventually change that to control the LED using Pulse Width Modulation.

2) The ADP5350 Board

We first need to integrate our ADP5350 battery management board in with our current setup. The board can be found up front and looks like the following:

Our Powerboard.

The parts for this board are actually mounted on the underside of the Printed Circuit Board (PCB), including the ADP5350 Battery Management Chip which provides the bulk of the power board's functionality.

Our powerboard and its parts. The key piece is the chip in the middle from Analog Devices, the ADP5350 Battery Management Chip.

Depending on how you laid out your individual components, this may or may not require a bit of rearrangement. Schematically, we want to implement the new connection shown in the Figure below.

Unplug your system from the USB while wiring up this new part! This is for the safety of the parts! Making mistakes here cannot necessarily be undone. (there is no control-Z if you burn a chip).

New connections involving the ADP5350 and the current system.

There are three LDO's in the system. Use the "B" outputs for them when you have to wire up to them. We'll use the "A" output later in the semester.

Your setup may of course look different, but we STRONGLY recommend you move parts so that the 5V pin on the Powerboard sits in the same breadboard row as the 5V pin on your ESP32. This will make it far less likely that you accidentally connect a wire from 5V to any other part on the board, which might prove fatal to the components.

When connecting to the LDO1 and LDO2 outputs, use terminal B, not A.

In addition, we strongly recommend you just use two really long wires to connect your SDA and SCL to the powerboard for I2C.

You can use either (or both) of the GND connections on the powerboard. They were put in place for convenience and to minimize series resistance.

How my setup looks once connected. Note the I2C-communication wires (SDA and SCL are somewhat obscured underneath the ESP32 and power boards. Also note I placed my two 5V pins (one from the power board and one from the ESP32 dev board) in the same row to avoid having to run a wire (forcing the layout to be like this will minimize potentially destructive wiring mistakes)

The ONLY connection to the ESP32's 5.0V pin should be to the power board's 5V pin. NOTHING else. The actual ESP32 microcontroller can be permanently destroyed if put in contact with 5V, so it is of the utmost importance that you pay attention and ask for help if you are at all unsure.

Once you feel confident you have implemented the wiring as shown, ask for the Checkoff below. During your checkoff you will upload the battery_voltage_readout.ino code. It is very simple, using a short library we wrote1 to control our power board. We include that library in our code with the line #include <adp5350.h>, before creating an ADP5350 object which we call adp5350.

In order to control the power board through the adp5350 object, there are limited number of class member functions we can call:

In our setup function we can turn on the battery charging functionality with adp5350.setCharger(1);2. If for some other reason later on, we want to turn off our battery charger this can be done with the call adp5350.setCharger(0);

We can turn on the two linear regulators (called Low-Dropout (LDO) regulators) we'll use to drive our 3.3V rail when in battery-power mode using the following two commands:

adp5350.enableLDO(1, 1); //turn on LDO1
adp5350.enableLDO(2, 1); //turn on LDO2

We can also enable or disable a fuel gauge functionality with the call adp.enableFuelGauge(1); or adp.enableFuelGauge(0);, respectively3. This is necessary to make battery voltage measurements.

If we'd like to read the voltage currently on the battery (check how much it is charged or discharged), we can call adp.batteryVoltage(); which will return the current value of the battery in milliVolts (mV).

Checkoff 1:
Review the wiring of your powerboard integration with a staff member. The staff member will bring a lithium polymer battery and you will (together) plug it in and run an example script. With the staff member, plug in your system, and upload the battery_voltage_readout.ino example script.

Once the battery is added in, your schematic becomes the following:

Add in the lithium polymer battery to the system.

We recommend just keeping your battery on top of your powerboard if possible.

The system with battery.

When put in context of everything we've incorporated so far in 6.08, we get this high level schematic. You may have an extra button in your setup currently. That's totally fine.

2.1) Configurations

The figure directly above contains all connections in the system as it currently stands, but it would be beneficial to remove communication-specific connections in order to emphasize the power-specific connections. To make the use of the battery easy, the ADP5350 at the core of our power board reconfigures its internal circuits depending on what the source of power is at any point in time (this is often known as PowerPath management). Below are the two primary configurations of our system.

When in charging mode, the ESP32 microcontroller, IMU, and OLED are powered directly from a 3.3V linear regulator found on the ESP32 devboard, which drops the 5.0V USB power supply to 3.3V. In addition, the ADP5350 uses that 5.0V USB signal to charge up the Lithium Polymer battery (using a rather complex charging pattern).

In case you're wondering, the 3.3V linear regulator onboard the ESP32 is located here. This component accepts the 5.0V power line from the USB plug on its input side and using some internal feedback circuitry ensures that on the other side (its output), a nice 3.3V signal is present.

When in battery-powered mode, the ESP32 devboard's onboard 3.3V regulator is useless. The ADP5350 recognizes that power must now come from the battery, and reconfigures to form the circuit shown, where two parallel 3.3V linear regulators, LDO1 and LDO2, (ignore the 0.5 Ohm resistors) power the primary circuit.

When in charging mode LDO1 and LDO2 are still present and can theoretically provide current from the USB if our breadboard were wired differently, but they aren't actually doing since the onboard 3.3V regulator of the ESP32 is running. A third LDO, LDO3, discussed below, is also available and can provide power at different voltages in both charging and batter mode.

Study these configurations above. Ask yourself where power is being sourced from and where power is being consumed in each case. The direction of certain currents on the board will change depending on which power state we are in.

Consider the following situation: In operation, the currents through the system devices we have so far are the following:

  • i_{esp} = 190 mA
  • i_{imu} = 10 mA
  • i_{oled} = 40 mA

While being powered over USB, and ignoring the battery charging, what is the efficiency of the system (what percentage of power is actually consumed by the ESP32, IMU, and OLED as opposed to the overall power consumed)?

When being powered over USB (and charging) such that the current flowing into the battery is 100 mA, what is the power consumed by the battery when its voltage is 3.4V (answer in Watts)?

In battery-powered mode, using passive sign convention (as discussed in Week 2's exercise on power) what is the power consumed by the three components (in Watts)?

In battery-powered mode, using passive sign convention what is the power consumed by the combined linear regulators LDO1 and LDO2 (in Watts) when the battery's voltage is currently 3.7V?

In battery-powered mode, using passive sign convention what is the power consumed by the battery (in Watts) when the battery's voltage is currently 3.7V?

In battery-powered mode, when the battery's voltage is currently 3.7V, what is the overall efficiency of the system?

We should be able to see that different parts (particularly the battery) will consume or provide differing amounts of power in different modes, and that this should make sense since we want to charge up the battery when in charging mode and discharge and use the energy stored in the battery during mobile mode.

3) Adding an Additional Load

Currently we have three components all sharing one primary 3.3V power rail. When plugged into your device, that power rail gets its power from your computer, and when disconnected (and the battery is sufficiently charged), that power rail gets its power from the battery. In both cases, special chips ensure that no matter what, 3.3V exists on that power rail.

Let's grab one more component for today, a large, rather bright white LED that we're going to run on a separate isolated power rail. We want to control this LED and vary its brightness. Today the control for it will be based on a button-driven state machine, but in the future you could use this to make a remote room light or something crazy. Go and grab a 10mm White LED from the front.

This LED is pretty bright. Do not look directly into it.

Our goal is to run this LED by varying its brightness. We will use a third controllable linear regulator that the ADP5350 powerboard gives us access to. This is LDO3. We will hook the LED up as shown in the figure below:

An LED will only emit light when placed in the proper orientation. Its anode must be at a higher potential than its cathode.

We'll use the third independently controllable linear regulator called LDO3. Similar to earlier, use the "B" terminal of this regulator output.:

We have a third LDO we can control independently of the others. We can turn it on and off as well as specify its output.

And hook it up as such:

Our third LDO should be connected to the LED, so we can vary the voltage supplied to the LED.

We can control the voltage at the output of the third linear regulator by using the voltageLDO3 member function of the ADP5350 class. This function takes in an integer which corresponds to the following regulator output voltages (pay close attention to them):

  • 13 = 3.30 V.
  • 12 = 3.15 V.
  • 11 = 3.00 V.
  • 10 = 2.85 V.
  • 9 = 2.50 V.
  • 8 = 2.30 V.
  • 7 = 2.10 V.
  • 6 = 1.80 V.
  • 5 = 1.50 V.
  • 4 = 1.40 V.
  • 3 = 1.30 V.
  • 2 = 1.20 V.
  • 1 = 1.10 V.
  • 0 = 1.00 V.

So if you'd like the output regulator to be set to 1.5V you'd make the member function call:

adp.voltageLDO3(5); //set to 1.5V
adp.enableLDO(3,1); //turn on that LDO

Note that adp.voltageLDO3(0); does not set the voltage to be zero, but rather 1V! However, this might not be apparent with our LED since a white LED will usually only emit light when it is supplied with greater than ~2.0V or so.

With everything hooked up, if somewhere in your code you ran the line adp.voltageLDO3(11); it would set 3.0V at the output of that regulator.

If the white LED consumes 20 mA when powered at 3.0V what is the power it consumes (in Watts)?

While we have 3 LDO's (linear regulators), for the protection of our 6.08 parts, only LDO3 has the voltage-control functionality available to you. However you can turn on and off all three LDOs as needed. We recommend you don't, though, since LDO1 and LDO2 are used to run the microcontroller and other electronics. When on battery power, if you turn off LDO1 and LDO2, the device will shut itself off (you basically tell it to unplug itself).

The brightness of an LED (and the power it consumes) is related to the voltage across it. We should therefore be able to see that we can control the brightness of the LED by varying the voltage at the output of LDO3. For example, when in mode 9 (voltage of 2.50V) the LED will be dimmer than if it is set to mode 13 (voltage of 3.30V).

If we are in battery-mode with a battery voltage of 3.6V, and with LDO3 set to be 2.5V what is the efficiency of our LED controller? In other words, when considering only the portion of the circuit in Figure 14, what percent of utilized power actually goes to the LED with respect to the total power used when in mode 9?

If we are in battery-mode with a battery voltage of 3.6V, and now LDO3 is set to be 3.3V what is the efficiency of our LED controller? In other words, what percent of utilized power actually goes to the LED with respect to the total power used when in mode 13?

We can see that in controlling our LED in this manner, our system becomes more inefficient when we set the LED to be dimmer.

The third piece of code included in today's lab downloadable is LDO3_control.ino. Open, compile, and upload this code. Make sure you have a pushbutton switch connected to IO15. When you run this code, by pressing the button, you can change the brightness by cycling through the voltage at the output of LDO3 in a manner identical to what is discussed above.

3.1) PWM-Control

The dimming solution above is one way to get various brightnesses out of our device, but frustratingly, no matter what brightness we want, it seems we always end up wasting power (and just dissipating as heat the power not used by the LED) and it gets worse when we want the LED to be dimmer. This is an awful way to go about life. It is extremely wasteful, and since our battery is tiny, the more we can save, the better.

Interestingly, for a given battery voltage, we should see that the brighter we run the LED, the higher the efficiency of the system will be. What would be neat would be if we could somehow get the efficiency of the LED when running full strength when we want lower brightnesses. If we continue to use our linear regulator like we are, this is impossible.

There exists an alternative. First we need to figure out what we care about. What is the purpose of a light? Usually to illuminate things. And for what purpose do we illuminate things? For people to see them generally. Now the act of a person seeing something generally utilizes their eyes and human eyes, while marvels of engineering, are actually pretty slow-responding in time, at least in comparison to the speeds at which electronics and LEDs can operate. This is in fact why we have movies and why the media below looks like actual moving kittens and not just a series of sequentially drawn kitten pictures.

The kittens aren't actually moving in this video. Our mediocre eyes let us think that they are. Ignorance is bliss.

We can take advantage of this for our LED brightness control. If instead of constantly providing a dim continuous illumination from the LED we can instead provide quick bright bursts interspersed with periods of time when the LED is not on. The result is we can trick the eye into seeing a various degreees of dim illumination—, but we end up achieving this using only high-efficiency states from the LED (high-brightness with a high efficiency and no-brightness/no power at all when off)! In doing so, we will turn it on and off at various duty cycles. Because our eye cannot respond fast enough to the turning-on-and-off events of the LED, it will allow us the freedom to change the perceived brightness of the system. In effect, our eye time-averages for us. Graphically this looks like the following:

Duty Cycle.

We define the term Duty Cycle to be the percentage of "ON" time with respect to the total amount of "ON" and "OFF" time. 50% duty cycle, for example, means the LED would be on for half the time and off for half the time. 25% means it is on for 25% of the time and off for 75%. The frequency at which we do this on-off switching is extremely important. If our frequency is 1Hz, our eyes can very easily see that and the illusion will not hold...we won't get varying dimming, just weird flashing patterns. But if we move up a couple orders of magnitude beyond the response rate (the time constants of the eye's light-detecting ion channels), we can get our achieved effect. If we run through our period in 10 ms, for example, as shown below, a 50% duty cycle signal will look brightish (but not as bright as a 100% duty cycle), where as something much smaller (5 or 10% duty cycle) will look much dimmer.

The effect of varying duty cycles.

Again to really emphasize a key point here: this PWM approach is beneficial from a power perspective since we're only operating the LED in high-efficiency states rather than in ways that burn a lot of power. This is great.

According to the voluminous datasheet for the ADP5350, LDO3 can be turned on in about 80 microseconds. This gives us the freedom to actually just turn on and off the LED, which is exactly what we need.

PWM control of systems can also have the added benefit of more linear control! We can quite readily set our system to be 25% of full brightness by setting the duty cycle to be 25%. This is actually tough to do the other way with an LED since its voltage-current-power relationship is highly non-linear.

Modify the current LDO code so that it utilizes a PWM-brightness control scheme. This should involve you setting your regulator voltage to be as high as possible (to maximize efficiency when on), and then only turning on and off the regulator using the adp.enableLDO(3,1); and adp.enableLDO(3,0); commands.

Feel free to experiment with different loop speeds (Consider a PWM frequency of 10Hz, 50Hz, 100 Hz, 1000Hz), which one works the best? The system should be able to do 0% 25%, 50%, 75%, and 100% duty brightness and do the same thing with the button as before.

Discuss with a staff member how you can implement a variable-duty cycle control for your LED. The system should be able to do 0% 25%, 50%, 75%, and 100% duty brightness.

Show your varying duty-cycle illumination control of your LED. Provide efficiency numbers for 0% brightness, 25% brightness, and 75% brightness.

It is the weekend again already! I love short weeks! Exercises for Week 3 are due Sunday night (11:59 PM). Consider doing a design exercise if you didn't do one last week.


1 Thanks for the development work, Kenneth Collins. Make sure you're LinkedIn friends with him. (click to return to text)

2 Note this doesn't mean it will necessarily charge the battery, just that it will charge it if the battery needs charging. Lithium-polymer batteries are complex things to charge properly and the ADP5350 takes care of a lot of the complexities for us (click to return to text)

3 The fuel gauge functionality is really neat (basically an automated way to estimate the remaining life in the battery, but it will only give reliable performance in a "production" device, that is, when you're not constantly power-cycling and reprogramming everything as we will be in our labs. For now we will mostly ignore this functionality, but it can prove useful in projects where you need to stretch the functionality. (click to return to text)