HAT 18650C

HAT 18650C V1.1 integrates an AW32257 charger and an INA226 power monitor. It can measure battery voltage, current, and power, control battery charging, set charge current, read charge status/fault status, and control the AW32257 Boost/OTG output.

Support the following products:

HAT18650C

Note

With the current hardware direction, charging current is usually negative and discharging current is usually positive. Charge current and voltage settings are written through AW32257 register steps, so the actual value is mapped to a supported gear rather than an arbitrary value.

UiFlow2 Example

Charge Test

Open the sticks3_hat18650c_charge_example.m5f2 project in UiFlow2.

This example reads battery voltage and current, shows charging state, and controls Charge ON/OFF with the button on StickS3.

UiFlow2 Code Block:

charge_example.png

Example output:

None

Output Test

Open the sticks3_hat18650c_output_example.m5f2 project in UiFlow2.

This example reads battery voltage and current, shows OTG output state, and controls OTG Output ON/OFF with the button on StickS3.

UiFlow2 Code Block:

output_example.png

Example output:

None

MicroPython Example

Charge Test

Read battery voltage and current, show charging state, and control Charge ON/OFF with the button on StickS3.

MicroPython Code Block:

  1# SPDX-FileCopyrightText: 2024 M5Stack Technology CO LTD
  2#
  3# SPDX-License-Identifier: MIT
  4
  5import os, sys, io
  6import M5
  7from M5 import *
  8from hat import HAT18650CHat
  9from hardware import Pin
 10from hardware import I2C
 11import time
 12
 13
 14label_title = None
 15label_voltage = None
 16label_current = None
 17label_iset = None
 18label_ctrl = None
 19i2c0 = None
 20hat_18650c_v11_0 = None
 21
 22
 23iset = None
 24last_time = None
 25bat_voltage = None
 26bat_current = None
 27
 28
 29def btna_was_clicked_event(state):
 30    global \
 31        label_title, \
 32        label_voltage, \
 33        label_current, \
 34        label_iset, \
 35        label_ctrl, \
 36        i2c0, \
 37        hat_18650c_v11_0, \
 38        iset, \
 39        last_time, \
 40        bat_voltage, \
 41        bat_current
 42    if hat_18650c_v11_0.get_charge_enable():
 43        hat_18650c_v11_0.set_charge_enable(False)
 44        label_ctrl.setText(str("Chg: OFF"))
 45    else:
 46        hat_18650c_v11_0.set_charge_enable(True)
 47        label_ctrl.setText(str("Chg: ON"))
 48
 49
 50def btnb_was_clicked_event(state):
 51    global \
 52        label_title, \
 53        label_voltage, \
 54        label_current, \
 55        label_iset, \
 56        label_ctrl, \
 57        i2c0, \
 58        hat_18650c_v11_0, \
 59        iset, \
 60        last_time, \
 61        bat_voltage, \
 62        bat_current
 63    iset = iset + 500
 64    if iset > 2500:
 65        iset = 500
 66    hat_18650c_v11_0.set_charge_current(iset)
 67    label_iset.setText(str((str("ISET: ") + str((str(iset) + str(" mA"))))))
 68
 69
 70def setup():
 71    global \
 72        label_title, \
 73        label_voltage, \
 74        label_current, \
 75        label_iset, \
 76        label_ctrl, \
 77        i2c0, \
 78        hat_18650c_v11_0, \
 79        iset, \
 80        last_time, \
 81        bat_voltage, \
 82        bat_current
 83
 84    M5.begin()
 85    Widgets.setRotation(0)
 86    Widgets.fillScreen(0x000000)
 87    label_title = Widgets.Label(
 88        "Charge", 22, 5, 1.0, 0x17EE6A, 0x000000, Widgets.FONTS.Montserrat24
 89    )
 90    label_voltage = Widgets.Label(
 91        "Vol:", 7, 45, 1.0, 0xFFFFFF, 0x000000, Widgets.FONTS.Montserrat18
 92    )
 93    label_current = Widgets.Label(
 94        "Cur:", 3, 70, 1.0, 0xFFFFFF, 0x000000, Widgets.FONTS.Montserrat18
 95    )
 96    label_iset = Widgets.Label(
 97        "ISET: 500mA", 3, 179, 1.0, 0xFFFFFF, 0x000000, Widgets.FONTS.Montserrat18
 98    )
 99    label_ctrl = Widgets.Label(
100        "CHG: ON", 26, 214, 1.0, 0xFFFFFF, 0x000000, Widgets.FONTS.Montserrat18
101    )
102
103    BtnA.setCallback(type=BtnA.CB_TYPE.WAS_CLICKED, cb=btna_was_clicked_event)
104    BtnB.setCallback(type=BtnB.CB_TYPE.WAS_CLICKED, cb=btnb_was_clicked_event)
105
106    i2c0 = I2C(0, scl=Pin(0), sda=Pin(8), freq=100000)
107    hat_18650c_v11_0 = HAT18650CHat(i2c0)
108    hat_18650c_v11_0.set_charge_enable(True)
109    iset = 500
110    hat_18650c_v11_0.set_charge_voltage(4.2)
111
112
113def loop():
114    global \
115        label_title, \
116        label_voltage, \
117        label_current, \
118        label_iset, \
119        label_ctrl, \
120        i2c0, \
121        hat_18650c_v11_0, \
122        iset, \
123        last_time, \
124        bat_voltage, \
125        bat_current
126    M5.update()
127    if (time.ticks_diff((time.ticks_ms()), last_time)) >= 500:
128        last_time = time.ticks_ms()
129        bat_voltage = hat_18650c_v11_0.get_battery_voltage()
130        bat_current = hat_18650c_v11_0.get_battery_current()
131        print(hat_18650c_v11_0.get_battery_power())
132        label_voltage.setText(str((str("Vol: ") + str((str(bat_voltage) + str("V"))))))
133        label_current.setText(str((str("Cur: ") + str((str(bat_current) + str("A"))))))
134        if hat_18650c_v11_0.is_charging():
135            label_voltage.setColor(0x009900, 0x000000)
136            label_current.setColor(0x009900, 0x000000)
137        else:
138            label_voltage.setColor(0xFFFFFF, 0x000000)
139            label_current.setColor(0xFFFFFF, 0x000000)
140
141
142if __name__ == "__main__":
143    try:
144        setup()
145        while True:
146            loop()
147    except (Exception, KeyboardInterrupt) as e:
148        try:
149            from utility import print_error_msg
150
151            print_error_msg(e)
152        except ImportError:
153            print("please update to latest firmware")

Example output:

None

Output Test

Read battery voltage and current, show OTG output state, and control OTG Output ON/OFF with the button on StickS3.

MicroPython Code Block:

  1# SPDX-FileCopyrightText: 2024 M5Stack Technology CO LTD
  2#
  3# SPDX-License-Identifier: MIT
  4
  5import os, sys, io
  6import M5
  7from M5 import *
  8from hardware import Pin
  9from hardware import I2C
 10from hat import HAT18650CHat
 11import time
 12
 13
 14label_title = None
 15label_voltage = None
 16label_current = None
 17label_ctrl = None
 18i2c0 = None
 19hat_18650c_v11_0 = None
 20
 21
 22output = None
 23last_time = None
 24bat_voltage = None
 25bat_current = None
 26
 27
 28def btna_was_clicked_event(state):
 29    global \
 30        label_title, \
 31        label_voltage, \
 32        label_current, \
 33        label_ctrl, \
 34        i2c0, \
 35        hat_18650c_v11_0, \
 36        output, \
 37        last_time, \
 38        bat_voltage, \
 39        bat_current
 40    output = not output
 41    if output:
 42        hat_18650c_v11_0.set_boost_enable(True)
 43        label_ctrl.setText(str("OUT: ON"))
 44        label_voltage.setColor(0xCC0000, 0x000000)
 45        label_current.setColor(0xCC0000, 0x000000)
 46    else:
 47        hat_18650c_v11_0.set_boost_enable(False)
 48        label_ctrl.setText(str("OUT: OFF"))
 49        label_voltage.setColor(0xFFFFFF, 0x000000)
 50        label_current.setColor(0xFFFFFF, 0x000000)
 51
 52
 53def setup():
 54    global \
 55        label_title, \
 56        label_voltage, \
 57        label_current, \
 58        label_ctrl, \
 59        i2c0, \
 60        hat_18650c_v11_0, \
 61        output, \
 62        last_time, \
 63        bat_voltage, \
 64        bat_current
 65
 66    M5.begin()
 67    Widgets.setRotation(0)
 68    Widgets.fillScreen(0x000000)
 69    label_title = Widgets.Label(
 70        "OUTPUT", 28, 5, 1.0, 0x17EE6A, 0x000000, Widgets.FONTS.Montserrat18
 71    )
 72    label_voltage = Widgets.Label(
 73        "Vol:", 7, 45, 1.0, 0xFFFFFF, 0x000000, Widgets.FONTS.Montserrat18
 74    )
 75    label_current = Widgets.Label(
 76        "Cur:", 3, 70, 1.0, 0xFFFFFF, 0x000000, Widgets.FONTS.Montserrat18
 77    )
 78    label_ctrl = Widgets.Label(
 79        "OUT: OFF", 23, 205, 1.0, 0xFFFFFF, 0x000000, Widgets.FONTS.Montserrat18
 80    )
 81
 82    BtnA.setCallback(type=BtnA.CB_TYPE.WAS_CLICKED, cb=btna_was_clicked_event)
 83
 84    i2c0 = I2C(0, scl=Pin(0), sda=Pin(8), freq=100000)
 85    hat_18650c_v11_0 = HAT18650CHat(i2c0)
 86    output = 0
 87    output = False
 88    hat_18650c_v11_0.set_boost_enable(False)
 89
 90
 91def loop():
 92    global \
 93        label_title, \
 94        label_voltage, \
 95        label_current, \
 96        label_ctrl, \
 97        i2c0, \
 98        hat_18650c_v11_0, \
 99        output, \
100        last_time, \
101        bat_voltage, \
102        bat_current
103    M5.update()
104    if (time.ticks_diff((time.ticks_ms()), last_time)) >= 500:
105        last_time = time.ticks_ms()
106        bat_voltage = hat_18650c_v11_0.get_battery_voltage()
107        bat_current = hat_18650c_v11_0.get_battery_current()
108        label_voltage.setText(str((str("Vol: ") + str(bat_voltage))))
109        label_current.setText(str((str("Cur: ") + str(bat_current))))
110
111
112if __name__ == "__main__":
113    try:
114        setup()
115        while True:
116            loop()
117    except (Exception, KeyboardInterrupt) as e:
118        try:
119            from utility import print_error_msg
120
121            print_error_msg(e)
122        except ImportError:
123            print("please update to latest firmware")

Example output:

None

API

HAT18650CHat

class hat.hat18650c.HAT18650CHat(i2c, charger_address=micropython.const, monitor_address=micropython.const, shunt_resistor=0.01, max_expected_current=10)

Bases: object

Create a HAT18650CHat object.

The AW32257 controls battery charging and Boost/OTG output. The INA226 measures battery bus voltage, current, and power.

Parameters:
  • i2c (I2C) – I2C bus.

  • charger_address (int) – AW32257 I2C address. Default is 0x6A.

  • monitor_address (int) – INA226 I2C address. Default is 0x41.

  • shunt_resistor (float) – INA226 shunt resistor value in ohms. Default is 0.01.

  • max_expected_current (float) – Maximum expected current for INA226 calibration in amps. Default is 10.

UiFlow2 Code Block:

init.png

MicroPython Code Block:

from hardware import I2C, Pin
from hat import HAT18650CHat

i2c0 = I2C(0, scl=Pin(0), sda=Pin(8), freq=100000)
hat18650c = HAT18650CHat(i2c0)
set_charge_enable(enable)

Enable or disable battery charging.

Parameters:

enable (bool) – True to enable charging, False to disable charging.

Return type:

None

UiFlow2 Code Block:

set_charge_enable.png

MicroPython Code Block:

hat18650c.set_charge_enable(True)
hat18650c.set_charge_enable(False)
get_charge_enable()

Get battery charging enable state.

Returns:

True if charging is enabled, False otherwise.

Return type:

bool

UiFlow2 Code Block:

get_charge_enable.png

MicroPython Code Block:

charge_enable = hat18650c.get_charge_enable()
set_charge_current(current_ma)

Set fast-charge current.

The target current is clamped to the HAT 18650C supported table. The closest supported table value not greater than the target is used internally, so the written value may be lower than the requested value.

Parameters:

current_ma (int) – Target charge current in mA.

Return type:

None

UiFlow2 Code Block:

set_charge_current.png

MicroPython Code Block:

hat18650c.set_charge_current(1000)
get_charge_current()

Get fast-charge current setting.

Returns the actual selected current-table value.

Returns:

Charge current setting in mA.

Return type:

int

UiFlow2 Code Block:

get_charge_current.png

MicroPython Code Block:

current_ma = hat18650c.get_charge_current()
set_charge_voltage(voltage)

Set charge regulation voltage.

The target voltage is clamped to the valid AW32257 range and rounded to the nearest register step, so the written value may be only close to the requested value.

Parameters:

voltage (float) – Target charge voltage in volts. Valid range is 3.50V to 4.50V.

Return type:

None

UiFlow2 Code Block:

set_charge_voltage.png

MicroPython Code Block:

hat18650c.set_charge_voltage(4.2)
get_charge_voltage()

Get charge regulation voltage.

Returns the actual selected voltage step.

Returns:

Charge regulation voltage in volts.

Return type:

float

UiFlow2 Code Block:

get_charge_voltage.png

MicroPython Code Block:

voltage = hat18650c.get_charge_voltage()
set_termination_current(current_ma)

Set charge termination current.

The target current is rounded to the nearest termination-current table value supported by AW32257.

Parameters:

current_ma (int) – Target termination current in mA. Options are 62 to 496 mA.

Return type:

None

UiFlow2 Code Block:

set_termination_current.png

MicroPython Code Block:

hat18650c.set_termination_current(124)
get_termination_current()

Get charge termination current setting.

Returns the actual selected termination-current table value.

Returns:

Termination current setting in mA.

Return type:

int

UiFlow2 Code Block:

get_termination_current.png

MicroPython Code Block:

current_ma = hat18650c.get_termination_current()
set_safety_charge_current(current_ma)

Set maximum allowed charge current.

The target current is rounded to the nearest charge-current table value supported by AW32257.

Parameters:

current_ma (int) – Target safety current in mA. Valid range is 496 to 2480 mA.

Return type:

None

UiFlow2 Code Block:

set_safety_charge_current.png

MicroPython Code Block:

hat18650c.set_safety_charge_current(1000)
get_safety_charge_current()

Get maximum allowed charge current.

Returns the actual selected safety-current table value.

Returns:

Safety current limit in mA.

Return type:

int

UiFlow2 Code Block:

get_safety_charge_current.png

MicroPython Code Block:

current_ma = hat18650c.get_safety_charge_current()
set_safety_charge_voltage(voltage)

Set maximum allowed charge regulation voltage.

The target voltage is rounded to the nearest safety-voltage table value supported by AW32257.

Parameters:

voltage (float) – Target safety voltage in volts. Valid range is 4.20V to 4.50V.

Return type:

None

UiFlow2 Code Block:

set_safety_charge_voltage.png

MicroPython Code Block:

hat18650c.set_safety_charge_voltage(4.2)
get_safety_charge_voltage()

Get maximum allowed charge regulation voltage.

Returns the actual selected safety-voltage table value.

Returns:

Safety voltage limit in volts.

Return type:

float

UiFlow2 Code Block:

get_safety_charge_voltage.png

MicroPython Code Block:

voltage = hat18650c.get_safety_charge_voltage()
set_recharge_threshold(threshold_mv)

Set automatic recharge threshold below VOREG.

Parameters:

threshold_mv (int) – Target recharge threshold in mV. Options are 50, 100, 150, and 200.

Return type:

None

UiFlow2 Code Block:

set_recharge_threshold.png

MicroPython Code Block:

hat18650c.set_recharge_threshold(100)
get_recharge_threshold()

Get automatic recharge threshold below VOREG.

Return type:

int

UiFlow2 Code Block:

get_recharge_threshold.png

MicroPython Code Block:

threshold_mv = hat18650c.get_recharge_threshold()
get_charge_status()

Get charger status text.

Returns:

Charge status text: ready, charging, done, or fault.

Return type:

str

UiFlow2 Code Block:

get_charge_status.png

MicroPython Code Block:

status = hat18650c.get_charge_status()
get_charge_status_code()

Get charger status code.

Returns:

One of STAT_READY, STAT_CHARGING, STAT_DONE, or STAT_FAULT.

Return type:

int

UiFlow2 Code Block:

get_charge_status_code.png

MicroPython Code Block:

status = hat18650c.get_charge_status_code()
is_charging()

Check whether charging is in progress.

Returns:

True if charging is in progress, False otherwise.

Return type:

bool

UiFlow2 Code Block:

is_charging.png

MicroPython Code Block:

charging = hat18650c.is_charging()
is_charge_done()

Check whether charging is complete.

Returns:

True if charging is complete, False otherwise.

Return type:

bool

UiFlow2 Code Block:

is_charge_done.png

MicroPython Code Block:

done = hat18650c.is_charge_done()
get_charge_fault()

Get charger fault text.

Returns:

Charge fault text.

Return type:

str

UiFlow2 Code Block:

get_charge_fault.png

MicroPython Code Block:

fault = hat18650c.get_charge_fault()
get_charge_fault_code()

Get charger fault code.

Returns:

Charge fault code. Use CHARGE_FAULT_* constants for comparison.

Return type:

int

UiFlow2 Code Block:

get_charge_fault_code.png charge_fault_code_option.png

MicroPython Code Block:

fault = hat18650c.get_charge_fault_code()
if fault == HAT18650CHat.CHARGE_FAULT_NO_BATTERY:
    print("No battery")
set_boost_enable(enable)

Enable or disable AW32257 Boost/OTG mode.

Parameters:

enable (bool) – True to enable Boost/OTG mode, False to disable it.

Return type:

None

UiFlow2 Code Block:

set_boost_enable.png

MicroPython Code Block:

hat18650c.set_boost_enable(True)
hat18650c.set_boost_enable(False)
get_boost_enable()

Get AW32257 Boost/OTG enable state.

Returns:

True if Boost/OTG mode is enabled, False otherwise.

Return type:

bool

UiFlow2 Code Block:

get_boost_enable.png

MicroPython Code Block:

boost_enable = hat18650c.get_boost_enable()
get_boost_fault()

Get Boost/OTG fault text.

Returns:

Boost/OTG fault text.

Return type:

str

UiFlow2 Code Block:

get_boost_fault.png

MicroPython Code Block:

fault = hat18650c.get_boost_fault()
get_boost_fault_code()

Get Boost/OTG fault code.

Returns:

Boost/OTG fault code. Use BOOST_FAULT_* constants for comparison.

Return type:

int

UiFlow2 Code Block:

get_boost_fault_code.png boost_fault_code_option.png

MicroPython Code Block:

fault = hat18650c.get_boost_fault_code()
if fault == HAT18650CHat.BOOST_FAULT_BATTERY_LOW:
    print("Battery low")
get_battery_voltage()

Get battery bus voltage from INA226.

Returns:

Battery voltage in volts.

Return type:

float

UiFlow2 Code Block:

get_battery_voltage.png

MicroPython Code Block:

voltage = hat18650c.get_battery_voltage()
get_battery_current()

Get battery current from INA226.

With the current hardware direction, charging current is usually negative and discharging current is usually positive.

Returns:

Battery current in amps.

Return type:

float

UiFlow2 Code Block:

get_battery_current.png

MicroPython Code Block:

current = hat18650c.get_battery_current()
get_battery_power()

Get battery power from INA226.

Returns:

Battery power in watts.

Return type:

float

UiFlow2 Code Block:

get_battery_power.png

MicroPython Code Block:

power = hat18650c.get_battery_power()