Read this section carefully to avoid damaging the kode dot.

Features

The kode dot integrates a complex and sophisticated power system, but at the same time robust, modular and easy to use. It can be powered in three ways: from the 500mAh battery, from the USB-C or through the external connectors. The system is formed by these components:
  • Power Management Integrated Circuit (PMIC)
  • Fuel Gauge
  • 3V3 regulator for internal components
  • 3V3 regulator for peripherals
  • 3V3 regulator for the internal RTC of the ESP32-S3

Power Management Integrated Circuit (PMIC)

The central part of the power system is a PMIC that is responsible for managing where the energy comes from, whether from the battery, the USB-C or the external connectors. In addition, the PMIC is responsible for the security and protection of the components, ensuring protection against overcurrents, short circuits or overcurrents. In addition, it allows to obtain data from the battery and the power supply. It also allows to generate a 5V bus and up to 2A of current that can be used to power external peripherals through the external connectors.

Fuel Gauge

The fuel gauge is a component that is responsible for measuring several battery data and giving us an analysis of its state. So we can know the following data from the battery:
  • Remaining capacity
  • Charge state
  • Remaining usage time
  • Battery voltage
  • Battery temperature
  • Health
  • Output or input current
In addition, it warns us about possible problems such as overcurrents, short circuits, overcurrents, etc.

3V3 regulator for internal components

This is the main voltage regulator of the kode dot and supports up to 1A of current. It is responsible for stabilizing the voltage to 3V3 and powering these components:
  • ESP32-S3
  • IO expander
  • RTC
  • Audio amplifier
  • Microphone
  • 6-axis IMU
  • 3-axis magnetometer
So, when the kode dot enters suspend mode, this regulator is responsible for maintaining the voltage on the ESP32-S3 and the internal components.

3V3 regulator for peripherals

This regulator, which supports up to 2A of current, can be activated or deactivated to power the following peripherals of the kode dot:
  • Screen
  • microSD
  • 3V3 bus of the upper connector
When the kode dot is in suspend mode, this regulator is deactivated and disconnects the power to the peripherals.

3V3 regulator for the internal RTC of the ESP32-S3

This regulator is responsible for powering the internal RTC of the ESP32-S3.

Connection diagram

Power Management Integrated Circuit (PMIC)

The PMIC is connected to the I2C bus using these connections:
PMICESP32-S3
SDAGPIO48
SCLGPIO47
INTEXP10
The PMIC has the address 0x6B on the I2C bus.
The interrupt pin is connected to the IO expander.
The 5V and 2A bus that the PMIC generates is connected to the upper connector and the back of the kode dot. If the USB-C is connected, the power of the 5V bus comes from this. If not, the power of the 5V bus comes from the battery. In addition, a external 5V power supply can be connected through one of the external connectors to charge the kode dot.
Do not connect an external 5V power supply while the USB-C is connected.

Fuel Gauge

The fuel gauge is connected to the I2C bus using these connections:
Fuel GaugeESP32-S3
SDAGPIO48
SCLGPIO47
GPOUTEXP5
The fuel gauge has the address 0x55 on the I2C bus.
The GPOUT pin is connected to the IO expander.

3V3 regulator for peripherals

This regulator can be activated or deactivated to power the peripherals of the kode dot. By default it is activated, to deactivate it set the following pin to LOW:
3V3 regulatorESP32-S3
ENEXP4
The EN pin is connected to the IO expander.

Arduino

Power Management Integrated Circuit (PMIC)

Fuel Gauge

ESP-IDF

Power Management Integrated Circuit (PMIC)

Fuel Gauge

Example code

Power Management Integrated Circuit (PMIC)

With this code you can see the parameters that the PMIC returns from the battery and the power supply.
pmic_test.ino
/**
 * Example usage of the PMIC BQ25896 on ESP32-S3 via I²C.
 * Initializes the battery charger/power manager, displays system parameters,
 * and updates readings and status every second.
 */
/* ───────── KODE | docs.kode.diy ───────── */

#include "PMIC_BQ25896.h"
#include <Wire.h>

/* I²C bus configuration: SDA, SCL pins */
#define I2C_SDA 48           /* SDA pin */
#define I2C_SCL 47           /* SCL pin */

/* BQ25896 driver instance */
PMIC_BQ25896 bq25896;

void setup() {
  /* Initialize serial port for debugging */
  Serial.begin(115200);
  while (!Serial) {
    /* Wait for serial connection */
  }

  /* Initialize I²C bus with specified pins */
  Wire.begin(I2C_SDA, I2C_SCL);

  Serial.println("BQ25896 Power Management and Battery Charger Example");

  /* Initialize the BQ25896 over I²C */
  bq25896.begin();
  delay(500);  /* Allow device to power up */

  /* Check device connectivity */
  if (!bq25896.isConnected()) {
    Serial.println("BQ25896 not found! Check connection and power");
    while (1) {
      /* Halt execution if device is not found */
    }
  } else {
    Serial.println("BQ25896 found successfully.");
  }
}

void loop() {
  Serial.println("BQ25896 System Parameters");

  /* Input current limit pin status */
  Serial.print("ILIM PIN : ");
  Serial.println(String(bq25896.getILIM_reg().en_ilim));

  /* System and charging parameters */
  Serial.print("IINLIM       : "); Serial.println(String(bq25896.getIINLIM()) + " mA");
  Serial.print("VINDPM_OS    : "); Serial.println(String(bq25896.getVINDPM_OS()) + " mV");
  Serial.print("SYS_MIN      : "); Serial.println(String(bq25896.getSYS_MIN()) + " mV");
  Serial.print("ICHG         : "); Serial.println(String(bq25896.getICHG()) + " mA");
  Serial.print("IPRE         : "); Serial.println(String(bq25896.getIPRECHG()) + " mA");
  Serial.print("ITERM        : "); Serial.println(String(bq25896.getITERM()) + " mA");
  Serial.print("VREG         : "); Serial.println(String(bq25896.getVREG()) + " mV");
  Serial.print("BAT_COMP     : "); Serial.println(String(bq25896.getBAT_COMP()) + " mΩ");
  Serial.print("VCLAMP       : "); Serial.println(String(bq25896.getVCLAMP()) + " mV");
  Serial.print("BOOSTV       : "); Serial.println(String(bq25896.getBOOSTV()) + " mV");
  Serial.print("BOOST_LIM    : "); Serial.println(String(bq25896.getBOOST_LIM()) + " mA");
  Serial.print("VINDPM       : "); Serial.println(String(bq25896.getVINDPM()) + " mV");
  Serial.print("BATV         : "); Serial.println(String(bq25896.getBATV()) + " mV");
  Serial.print("SYSV         : "); Serial.println(String(bq25896.getSYSV()) + " mV");
  Serial.print("TSPCT        : "); Serial.println(String(bq25896.getTSPCT()) + "%");
  Serial.print("VBUSV        : "); Serial.println(String(bq25896.getVBUSV()) + " mV");
  Serial.print("ICHGR        : "); Serial.println(String(bq25896.getICHGR()) + " mA");

  /* Fault status */
  Serial.print("Fault -> "); 
  Serial.print("NTC:" + String(bq25896.getFAULT_reg().ntc_fault));
  Serial.print(" ,BAT:" + String(bq25896.getFAULT_reg().bat_fault));
  Serial.print(" ,CHGR:" + String(bq25896.getFAULT_reg().chrg_fault));
  Serial.print(" ,BOOST:" + String(bq25896.getFAULT_reg().boost_fault));
  Serial.println(" ,WATCHDOG:" + String(bq25896.getFAULT_reg().watchdog_fault));

  /* Charging status */
  Serial.print("Charging Status -> "); 
  Serial.print("CHG_EN:" + String(bq25896.getSYS_CTRL_reg().chg_config));
  Serial.print(" ,BATFET DIS:" + String(bq25896.getCTRL1_reg().batfet_dis));
  Serial.print(" ,BATLOAD_EN:" + String(bq25896.getSYS_CTRL_reg().bat_loaden));
  Serial.print(" ,PG STAT:" + String(bq25896.get_VBUS_STAT_reg().pg_stat));
  Serial.print(" ,VBUS STAT:" + String(bq25896.get_VBUS_STAT_reg().vbus_stat));
  Serial.print(" ,CHRG STAT:" + String(bq25896.get_VBUS_STAT_reg().chrg_stat));
  Serial.println(",VSYS STAT:" + String(bq25896.get_VBUS_STAT_reg().vsys_stat));

  /* Trigger a new ADC conversion */
  bq25896.setCONV_START(true);

  delay(1000); /* Update every second */
}

Fuel Gauge

With this code you can see the parameters that the fuel gauge returns from the battery.
bq27220_test.ino
/**
 * Example usage of the Texas Instruments BQ27220 battery fuel gauge.
 * Reads state of charge, voltage, current, and temperature over I²C.
 * Displays charging status and estimated time to full when charging.
 */
/* ───────── KODE | docs.kode.diy ───────── */

#include <Wire.h>
#include <BQ27220.h>

/* I²C pin configuration for ESP32-S3 */
#define SDA_PIN 48   /* SDA line */
#define SCL_PIN 47   /* SCL line */

/* Battery fuel gauge driver instance */
BQ27220 gauge;

void setup() {
  /* Initialize serial port for debug output */
  Serial.begin(115200);

  /* Start I²C bus with custom SDA/SCL pins */
  Wire.begin(SDA_PIN, SCL_PIN);

  /* Initialize the BQ27220 fuel gauge */
  if (!gauge.begin()) {
    Serial.println("BQ27220 not found!");
    while (1) delay(1000); /* Halt execution if not found */
  }

  Serial.println("BQ27220 ready.");
}

void loop() {
  /* Read battery parameters */
  int soc = gauge.readStateOfChargePercent();  // State of charge (%)
  int mv  = gauge.readVoltageMillivolts();     // Voltage (mV)
  int ma  = gauge.readCurrentMilliamps();      // Current (mA), positive = charging
  float tC = gauge.readTemperatureCelsius();  // Temperature (°C)

  /* Print basic battery information */
  Serial.print("SOC= "); Serial.print(soc); Serial.print("%  ");
  Serial.print("V= "); Serial.print(mv); Serial.print(" mV  ");
  Serial.print("I= "); Serial.print(ma); Serial.print(" mA  ");
  Serial.print("T= "); Serial.print(tC, 1); Serial.print(" °C");

  /* If charging, show estimated time to full */
  if (ma > 0) {
    int ttf = gauge.readTimeToFullMinutes();
    Serial.print("  TTF= "); Serial.print(ttf); Serial.print(" min");
  }

  Serial.println();

  delay(1000); /* Update once per second */
}

Download examples

You can test the example codes through the Arduino IDE or the ESP-IDF IDE or download the codes in our drive: Power codes