XIAO_MG24 battery voltage measurement function is not available

The XIAO_MG24 has the ability to measure battery voltage by dividing it by 1/2.
Assuming the maximum battery voltage is 4.2V, the full scale of AD conversion requires at least 2.1V. The reference voltage Vref can be selected from the internal reference voltage of 1.2V or VDD (3.3V). When Vref=1.2V is selected, battery voltages above 2.4V cannot be measured. When Vref=VDD(3.3V) is selected, battery voltage below 3.3V cannot be measured because VDD drops below 3.3V.
On the other hand, the MG24 chip has a function that allows the AD converter input gain to be set, and if GAIN = 0.5, the battery voltage can be AD converted with a margin with Vref = 1.2V.
Unfortunately, BoardSupportPackage 2.2.0 does not have a function to set gain.

Is there any good solution?

2 Likes

Hi there,

So I wasn’t able to get it to work, and have reached out to @Chunchun for advisement.
HTH
GL :slight_smile: PJ :v:

2 Likes

I know it is not a good thing to change the BSP without permission, but I have tentatively confirmed that the battery voltage can be measured from 4.2V to 2.5V using the following patch.

\Arduino15\packages\SiliconLabs\hardware\silabs\2.2.0\variants\xiao_mg24\ noradio \include\em_iadc.h (from Line 845 to Line901)

The four places where gain = 1 is set by default have been changed to gain = 0.5.
Below is an example of compiling with protocol stack = None

iadcCfgAnalogGain1x, ----> iadcCfgAnalogGain0P5x,

#if defined(_IADC_CFG_DIGAVG_MASK)
#if defined(_IADC_CFG_ADCMODE_HIGHACCURACY)
/** Default IADC config structure. */
#define IADC_CONFIG_DEFAULT                                               \
  {                                                                       \
    iadcCfgModeNormal,            /* Normal mode for IADC. */             \
    iadcCfgOsrHighSpeed2x,        /* 2x high speed over sampling. */      \
    iadcCfgOsrHighAccuracy92x,    /* 92x high accuracy over sampling. */  \
    iadcCfgAnalogGain0P5x,          /* 1x analog gain. */                   \
    iadcCfgReferenceInt1V2,       /* Internal 1.2V band gap reference. */ \
    iadcCfgTwosCompAuto,          /* Automatic Two's Complement. */       \
    0,                            /* Max IADC analog clock rate. */       \
    1210,                         /* Vref expressed in millivolts. */     \
    iadcDigitalAverage1           /* No averaging. */                     \
  }
#else
/** Default IADC config structure. */
#define IADC_CONFIG_DEFAULT                                               \
  {                                                                       \
    iadcCfgModeNormal,            /* Normal mode for IADC. */             \
    iadcCfgOsrHighSpeed2x,        /* 2x high speed over sampling. */      \
    iadcCfgAnalogGain0P5x,          /* 1x analog gain. */                   \
    iadcCfgReferenceInt1V2,       /* Internal 1.2V band gap reference. */ \
    iadcCfgTwosCompAuto,          /* Automatic Two's Complement. */       \
    0,                            /* Max IADC analog clock rate. */       \
    1210,                         /* Vref expressed in millivolts. */     \
    iadcDigitalAverage1           /* No averaging. */                     \
  }
#endif
#else
#if defined(_IADC_CFG_ADCMODE_HIGHACCURACY)
/** Default IADC config structure. */
#define IADC_CONFIG_DEFAULT                                               \
  {                                                                       \
    iadcCfgModeNormal,            /* Normal mode for IADC. */             \
    iadcCfgOsrHighSpeed2x,        /* 2x high speed over sampling. */      \
    iadcCfgOsrHighAccuracy92x,    /* 92x high speed over sampling. */     \
    iadcCfgAnalogGain0P5x,          /* 1x analog gain. */                   \
    iadcCfgReferenceInt1V2,       /* Internal 1.2V band gap reference. */ \
    iadcCfgTwosCompAuto,          /* Automatic Two's Complement. */       \
    0,                            /* Max IADC analog clock rate. */       \
    1210                          /* Vref expressed in millivolts. */     \
  }
#else
/** Default IADC config structure. */
#define IADC_CONFIG_DEFAULT                                               \
  {                                                                       \
    iadcCfgModeNormal,            /* Normal mode for IADC. */             \
    iadcCfgOsrHighSpeed2x,        /* 2x high speed over sampling. */      \
    iadcCfgAnalogGain0P5x,          /* 1x analog gain. */                   \
    iadcCfgReferenceInt1V2,       /* Internal 1.2V band gap reference. */ \
    iadcCfgTwosCompAuto,          /* Automatic Two's Complement. */       \
    0,                            /* Max IADC analog clock rate. */       \
    1210                          /* Vref expressed in millivolts. */     \
  }
#endif
#endif

1 Like

BSP 2.3.0 was released yesterday, but this issue was not resolved.

This is a real shame, as it is an essential feature for running the MG24 on battery power.

Hi there,

As I maintain they have NO interest in fixing it either. Their local Shill however will tell you they are the best thing since sliced bread… LOL :lying_face:
They were a graphics card co., and have really NO business in the MCU game at All!
Great for blinking LED’s Though! :+1:

GL :slight_smile: PJ :v:

Here is an easy way to measure the battery

pinMode(PD3, OUTPUT);
digitalWrite(PD3, 1); //enable VBAT to ADC switch

int mv = (analogRead(PD4) * 1000) / 610;
Serial.print("Battery mV = ");
Serial.println(mv);

Hi there,

Yes, one post on this is Sufficient. You don’t say much about how and what you use to do it or provide any Serial output. This may be more informative if you provide more info.

HTH
GL :slight_smile: PJ :v:

Hi, I just checked the schematic and did a few test measurements at different voltages to get this calibrated, so far it seems good and I’m currently discharging the battery to check further. It started at about 4200 and currently sitting at 3850 and still measuring as expected.

Hi there,

Ah’ good. So which BSP are you using?
What is the dev , environment if you don’t mind?
GL :slight_smile: PJ :v:

Hi RikusW,
Make sure your method can measure correctly well below 3.3V battery voltage.

2 Likes

I’m using arduino-ide_nightly-20241212_Linux_64bit and no radio at the moment with the latest 2.3.0 bsp GitHub - SiliconLabs/arduino: Arduino Core for Silicon Labs devices

I’m in the process of checking the following patch, which is much simpler.
I will post again when I have the results of the measurements.

// \Arduino15\packages\SiliconLabs\hardware\silabs\2.3.0\cores\silabs\adc.cpp
// LINE 93   all_configs.configs[0].analogGain = iadcCfgAnalogGain0P5x;
1 Like

Hi there,

I suspect it will FAIL… Hope I’m wrong. :face_with_hand_over_mouth:
But “A” for effort. :v:

GL :slight_smile: PJ :v:

I’m shutting down the device at 3.5V since then the battery is almost drained so hopefully it works for me. I see the issue with using VDD ref now…

Hi there,

That doesn’t seem quite right. Given the battery life calculator on Digikey and others, for a single-cell LiPo battery, the “3.85V” rating is typically the nominal voltage. In practice, a LiPo battery usually measures around:

  • Fully charged: about 4.2V
  • Nominal voltage: roughly 3.7V to 3.85V
  • Discharged (cutoff): around 3.0V

So, during normal operation, you might see a voltage range from about 4.2V down to around 3.0V many nRF52840-based boards include a voltage regulator that can take the full battery range (4.2V to ~3.0V) and provide a steady operating voltage for the chip.

this just adds to the miss of the Mark iIMO…
HTH
GL :slight_smile: PJ :v:

I tried the new patch in post #13.
I am able to measure voltages below 3.3V without any problems.

1 Like

Hi there,

Wow, Nice work @msfujino Pretty straight forward as well.
I just don’t understand why these vendors don’t fix this stuff they owe you a big GIFT basket for saving there face IMO. :bow:

GL :slight_smile: PJ :v:

I guess we can expect a New BSP from SIL 2.3.1 but I’m not Holding my Breath :sweat_smile: :+1:

1 Like

This will apply to all variants, other boards might have different divider ratios.

This patch is only provisional and should only be used to measure the battery voltage of the XIAO_MG24.
It is my strong hope that a BSP will be released that will correctly measure the battery voltage of the XIAO_MG24 without causing problems for all boards.

1 Like

The graph shows that the battery voltage cannot be measured correctly with Vref=3.3V(VDD) set. Please refer to it if you are interested.

1 Like