This is a simple project to discharge Adafruit LiPo packs to 3.8 volts for storage. First you use a computer to set up the ESP32-S3 TFT Feather, then you disconnect the computer and plug in the LiPo. The battery voltage shows on the display until it reaches 3.8 volts. Once the battery discharges to the storage voltage threshold, the Feather goes into deep sleep. When you see the display turn off, you can unplug and store the battery.
Updating CircuitPython
As I write this (January 22, 2026), CircuitPython 10.0.3 is the most recent build for Fruit Jam. To keep your board up to date, you can use the "DOWNLOAD .BIN NOW" button on the download page of circuitpython.org:
- Feather ESP32-S3 TFT PSRAM download page
To install the BIN File:
- Review the instructions in the Web Serial ESPTool section of the "CircuitPython on ESP32 Quick Start" learn guide.
- Put your board in bootloader mode: plug in a USB data cable (must be a sync cable, power-only won't work!), hold down the BOOT button, press and release the RESET button, then release the BOOT button.
- Load the Adafruit WebSerial ESPTool page in Chrome (other browsers may not work).
- Connect to your board.
- Erase the flash.
- Program the .BIN file.
- Reset the board.
Project Code & Libraries
You can view the code at the samblenny/lipo-conditioner GitHub repository. To download a zip archive project bundle with the code and all the necessary libraries, use the "Download Project Bundle" button:
Install Project Bundle
To copy the project bundle files to your CIRCUITPY drive:
- Download the project bundle .zip file using the "Download Project Bundle" button above.
- Expand the zip file by opening it, or use unzip in a Terminal. The zip archive should expand to a folder. When you open the folder, it should contain a README.txt file and a CircuitPython 10.x folder.
- Open the CircuitPython 10.x folder and copy all of its contents to your CIRCUITPY drive.
To learn more about copying libraries to your CIRCUITPY drive, check out the CircuitPython Libraries section of the Welcome to CircuitPython! learn guide.
# SPDX-License-Identifier: MIT
# SPDX-FileCopyrightText: Copyright 2026 Sam Blenny
#
# See NOTES.md for documentation links
#
import alarm
import bitmaptools
import board
from displayio import Bitmap, Group, Palette, TileGrid
from digitalio import DigitalInOut
import displayio
from micropython import const
import terminalio
import time
from adafruit_display_text import bitmap_label
from adafruit_max1704x import MAX17048
STORAGE_VOLTS = const(3.8)
# Init I2C battery fuel gauge
time.sleep(0.5)
i2c = board.I2C()
max17 = MAX17048(i2c)
time.sleep(1) # let max17 finish initializing
# Init display with text label for voltage
display = board.DISPLAY
display.rotation = 180
grp = Group(scale=1)
display.root_group = grp
volts = bitmap_label.Label(terminalio.FONT, text="", color=0xFFFF00, scale=5)
volts.line_spacing = 1.0
volts.anchor_point = (0, 0)
volts.anchored_position = (32, 32)
grp.append(volts)
# Wait for battery volts to reach storage voltage
while True:
v = max17.cell_voltage
volts.text = f"{v:.2f} V"
time.sleep(3)
if v <= STORAGE_VOLTS:
break
# Put fuel gauge in low power mode
max17.hibernate()
time.sleep(0.5)
# Make sure Neopixel, I2C, TFT, and TFT backlight are off
displayio.release_displays()
npp = DigitalInOut(board.NEOPIXEL_POWER)
npp.switch_to_output(value=False)
tip = DigitalInOut(board.TFT_I2C_POWER)
tip.switch_to_output(value=False)
tb = DigitalInOut(board.TFT_BACKLIGHT)
tb.switch_to_output(value=False)
# Deep sleep for an hour
alarm.exit_and_deep_sleep_until_alarms(
alarm.time.TimeAlarm(monotonic_time=time.monotonic() + 3600))
This page (LiPo Storage Voltage Conditioner) was last updated on January 22, 2026.
Text editor powered by tinymce.