Technical Article

Battery Fast Charging Using Raspberry Pi and Python

January 07, 2024 by Franco Contadini

By implementing fuel gauge functionality in the battery pack, original equipment manufacturers can design smart fast chargers that increase system flexibility, minimize power dissipation, ensure safe charging/discharging, and improve the overall user experience. This article explores the implementation details of a fast-charging system with parallel batteries using evaluation kits, a Raspberry Pi board, and Python.

This article is published by EEPower as part of an exclusive digital content partnership with Bodo’s Power Systems.


Evaluating a simple charging system and testing its functionality can typically be done with an evaluation kit. These kits include all the necessary hardware and software applications, as well as graphical user interface (GUI)-based tools and APIs, to configure charging systems.


Image used courtesy of Adobe Stock


Evaluating 1S2P Architectures

However, complex systems that require multiple cells are correspondingly more complex to evaluate. Complex systems may have several devices that need to be characterized. Developers will need to write some software code to read the signals generated from different system parts, analyze them, and take action. Consider a two Li+ cell in a parallel battery fast charging system using the MAX17330. As described in the datasheet, the MAX17330 can be used to charge and control two Li+ cells simultaneously. This system requires two MAX17330 ICs each managing one Li+ cell, and a buck converter (such as the MAX20743) with the capability to change its output voltage on-the-fly.

A microcontroller is required to configure and manage battery charging as well as to handle communication between the two ICs. Because it is a commonly used platform for system testing, we chose a Raspberry Pi board using Python as the programming language. The Raspberry Pi manages communications over I2C and logs important system parameters useful for evaluation and debugging, including charge current, battery voltage, and battery state of charge (SOC). These values are stored in an Excel file to enable offline analysis.


Figure 1. A 1S2P charging system evaluation architecture using Raspberry Pi. Image used courtesy of Bodo’s Power Systems [PDF]


Testing the 1S2P Architecture

This section shows how the charger and fuel gauge (MAX17330) are tested. It also describes the real performance that can be expected from parallel charging. For the most flexibility and control, the device is programmed by a microcontroller using I2C.

Figure 1 shows the 1S2P system architecture and the connections that are needed to evaluate the charging of two cells in parallel. The Raspberry Pi controls the three EVKITs: one MAX20743EVKIT (buck converter) and two MAX17330EVKITs (charger + fuel gauge). Data is logged in an Excel file.

The GUI-based, MAX17330 EV Kit Software is available and can be downloaded from the MAX17330 product page under the Tools and Simulations tab. It can be used to generate initialization files (.INI) for the MAX17330 using the Configuration Wizard (select from the Device tab). The INI file contains the register initialization information for the device in a register address/register value format. This is the file used by the microcontroller to configure the MAX17330 register by register.

The MAX17330EVKIT data sheet details the different steps required to generate the initialization file. The configuration, shown in Figure 2, is used to begin parallel charging. Next, step charging is enabled (see Figure 3). Figure 4 shows the expected step charging profile based on the step charging configuration found in Figure 3.


Figure 2. Configuring the MAX17330 for parallel charging. Image used courtesy of Bodo’s Power Systems [PDF]


Figure 3. Enable step charging. Image used courtesy of Bodo’s Power Systems [PDF]


The MAX20734 buck converter is used to increase the voltage applied to the two MAX17330EVKITs when needed. The MAX20734 buck converter changes the output voltage according to the value of the internal register at address 0x21. The buck converter can be controlled via I2C; a class in Python has been written to do so.


Table 1. Conversion Output Voltage Based on Register 0x21 for the MAX20743.

0x21 Register Value



3 V


3.05 V


3.1 V


3.15 V


3.2 V


3.25 V


3.3 V


3.35 V


3.4 V


3.45 V


3.5 V


3.55 V


3.6 V


3.65 V


3.7 V


3.75 V


3.8 V


3.85 V


3.9 V


3.95 V




4.05 V


4.1 V


4.15 V


4.2 V


4.25 V


4.3 V


4.35 V


4.4 V


4.45 V


4.5 V


4.55 V


4.6 V


Figure 4. An expected step-charging profile is based on the step-charging configuration in Figure 3. Image used courtesy of Bodo’s Power Systems [PDF]


Figure 5. The output voltage divider has been modified for an output range of 3 V to 4.6 V (with R6 = 4 K7 and R9 = 1 K3). Image used courtesy of Bodo’s Power Systems [PDF]


Finally, as shown in Figure 5, the MAX20743EVKIT output voltage divider is modified for an output range from 3 V to 4.6 V (using the values R6 = 4K7 and R9 = 1K3).

From Table 1, we can extract the curve:


where x is the voltage we want to apply at the output. While this approach will have a slight error, it is a good way to estimate the desired value of the register from the voltage.


Powering Up and Initialization

When the MAX17330 is first connected to a battery, default register value settings force the IC into a shutdown state. To wake the device, press the PKWK button. This will shorten the temporary protection of MOSFETs and wake up both MAX17330EVKITs in this way.

Next, the Raspberry Pi needs to communicate via I2C with all three devices. Carefully initialize the I2C hardware to avoid device address conflicts. By default, the two MAX17330EVKITs use the same I2C address. The first step is to change the address of one of the two fuel gauges.

The MAX17330 has both volatile and nonvolatile registers, with nonvolatile registers identified with the “n” prefix. This also results in a pair of node addresses, 6Ch (volatile registers) and 16h (NV registers).

There are two ways to change device node addresses on the MAX17330:

  • Set the nPackCfg NV register using the I2CSid field. This change can be set using the Configuration Wizard. See Table 3.
  • The I2CCmd register allows dynamic changes to the I2C bus. See Table 4.

For ease of use, we use the second way to change the address so that the same INI file can be used to initialize both devices. Generating settings that can be shared by the two devices simplifies the configuration of the devices and eliminates the potential for user error when the address must be entered manually.


Table 2. MAX17330 Registers
Register Page Lock Description 2-Wire Node Address 2-Wire Protocol 2-Wire External Address Range
00 h          
01 h – 04 h Lock 2 Modelgauge M5 EZ data block 6 channels I2C 00 h – 4 Fh
05 h – 0Ah   Reserved      
0 Bh Lock 2 Modelgauge M5 EZ data block (continued) 6 channels I2C B0 h – BFh
0 Ch SHA SHA memory 6 channels I2C C0h – CFh
0 Dh Lock 2 Modelgauge M5 EZ data block (continued) 6 channels I2C D0h – DFh
0 Eh – 0 Fh   Reserved      
10 h – 17 h   SBS data block 16 channels SBS 00 h – 7 Fh
18 h – 19 h Lock 3 Modelgauge M5 EZ nonvolatile memory block      
1 Ah – 1 Bh Lock 1 Lifelogging and configuration of nonvolatile memory block 16 channels I2C 80 h – EFh
1 Ch Lock 4 Configuration nonvolatile memory block


Table 3. nPackCfg (1B5h) Register Format
D15 D14 D13 D12 D11 D10 D9 D8 D7 D6 D5 D4 D3 D2 D1 D0
0 S_Hib THCfg THType 000 0 ParEn I2CSid 0001


Table 4. I2CCmd (12Bh) Register Format
D15 D14 D13 D12 D11 D10 D9 D8 D7 D6 D5 D4 D3 D2 D1 D0
0 GoToSID 0001 IncSID


Table 5. I2C ALRT Settings
GoToSID Alert High Alert Low
  Primary/Secondary Address Primary/Secondary Address
0b00 ECh/96h 6Ch/16h
0b01 64h/1Eh ECh/96h
0b10 E4h/9Eh 64h/1Eh
0b11 6Ch/16h E4h/9Eh


Since the two MAX17330 devices share the same I2C bus, this procedure requires that the ALRT signal of one device be set low while the other one is set high.

Table 4, from the MAX17330 datasheet, shows how the I2CCmd register can dynamically change the address of the device based on the ALERT GPIO pin value. In this case, the GoToSID and INcSID fields are used to change the I2C address:

▸Set ALRT_A logic low

▸Set ALRT_B logic high

▸Write I2CCmd = 0 × 0001

          ➔MAX17330_A address remains at 6Ch/16h

          ➔MAX17330_B address set to ECh/96h

Once each device has its unique address, the entire system can be controlled by a single microcontroller.

Here is the script for the microcontroller to complete the I2C configuration. This will be part of the system initialization.

▸Load .INI file

▸Assert ALRT_A and ALRT_B to keep the path between SYSP and BATTP open



▸Set VOUT = VMAX + 50 mV

▸Release ALRT_A and ALRT_B

▸Set nProtCfg.OvrdEn = 0 to use ALRT as Output

See Table 6.

Some registers in the nonvolatile space require the firmware to be restarted for the change to take effect. Thus, the following step is required:

▸Assert Config2.POR_CMD to restart firmware

See Table 7.

Next, we need to enable interrupts from the chargers:

▸Set (Config.Aen and Config.Caen) = 1

See Table 8.

Now the devices are initialized.


Logging Data and Interrupts

We need to be able to read registers to log data and check if an interrupt has been generated on the ALERT GPIO lines. We can use this script:

▸Set 500 ms Timer


▸Vsys_min = nVEmpty[15:7]

▸CrossCharge = False


Table 6. nProtCfg (1D7h) Register Format
D15 D14 D13 D12 D11 D10 D9 D8
ChgWDTEn nChgAutoCtrl FullEn SCTest SCTest CmOvrdEn ChgTestEn PrequalEn
D7 D6 D5 D4 D3 D2 D1 D0
Reserved PFEn DeepShpEn OvrdEn UVRdy FetPFEn BlockDiscCen DeepShp2En


Table 7. Config2 (OABh) Register Format
D15 D14 D13 D12 D11 D10 D9 D8 D7 D6 D5 D4 D3 D2 D1 D0
POR_CMD 0 AtRtEn 0 0 0 0 0 dSOCen TAlrtEn 0 1 DRCfg CPMode BlockDis


Table 8. Config (O0Bh) Register Format
D15 D14 D13 D12 D11 D10 D9 D8 D7 D6 D5 D4 D3 D2 D1 D0
0 SS TS VS 0 PBen DisBlockRead ChgAutoCtrl SHIP COMMSH FastADCen ETHRM FTHRM Aen CAen PAen


FProtStat Register

Table 9. FProtStat (0DAh) Register Format
D15 D14 D13 D12 D11 D10 D9 D8 D7 D6 D5 D4 D3 D2 D1 D0
X IsDis X Hot Cold Warm


Table 10. Status (000h) Register Format
D15 D14 D13 D12 D11 D10 D9 D8 D7 D6 D5 D4 D3 D2 D1 D0
PA Smx Tmx Vmx CA Smn Tmn Vmn dSOCi Imx AllowChgB X Bst Imn POR X


Table 11. Config2 (0ABh) Register Format
D15 D14 D13 D12 D11 D10 D9 D8 D7 D6 D5 D4 D3 D2 D1 D0
POR_CMD 0 AtRtEn 0 0 0 0 0 dSOCen TAlrtEn 0 1 DRCfg   CPMode BlockDis


Table 12. Status Register (000h) Format
D15 D14 D13 D12 D11 D10 D9 D8 D7 D6 D5 D4 D3 D2 D1 D0
PA Smx Tmx Vmx CA Smn Tmn Vmn dSOCi lmx AllowChgB X Bst Imn POR X


Table 13. ChgStat (0A3h) Register Format
D15 D14 D13 D12 D11 D10 D9 D8 D7 D6 D5 D4 D3 D2 D1 D0
Dropout X X X X X X X X   X X CP CT CC CV


Optionally, once the device moves from the constant current (CC) phase to the constant voltage (CV) phase, the voltage generated from the step-down converter can be reduced as follows:

▸If VBATT = ChargingVoltage

Read ChgStat Register

If ChgStat.CV = ➔ decrease VOUT until VPCK

= ChargingVoltage + 25 mV


Figure 6. A parallel charging plot. Image used courtesy of Bodo’s Power Systems [PDF]


These are all the steps needed to manage a 1S2P charging configuration. Included in is the Python code for configuring the buck converter (MAX20743) as well as the charger and fuel gauge (MAX17330). It also includes the Excel data log to capture important charging parameters and evaluate the step charging profile. By managing alert signals generated from the MAX17330, a microcontroller keeps the linear charger of the MAX17330 close to dropout, minimizing power dissipation and therefore allowing a high charging current. A battery pack using the MAX17330 stores the parameters for the installed battery that the host microcontroller needs to implement efficient fast charging. This allows OEMs to replace a standard charger IC device with a simpler and less expensive buck converter without compromising performance or reliability.


Battery Fast Charging Takeaways

Device charging time is one of the most important user experience considerations. Using a buck converter like the MAX17330 makes it possible to efficiently manage a very high current to decrease charging time in a small IC package. The ability to support parallel charging with a very high current, such as with two MAX17330, enables developers to charge multiple batteries in a safe, reliable manner that keeps charging time to a minimum.


This article is co-authored by Franco Contadini, staff engineer and Alessandro Leonardi, account manager of Field Sales for Analog Devices. The article originally appeared in Bodo’s Power Systems [PDF] magazine.