XIAO_BLE_Sense(mbed 2.7.2) battery charge and voltage monitor, analogRead(P0_31) does not work

XIAO_BLE_Sense has battery charging and battery voltage monitoring functions. I am trying to check these functions with “mbed 2.7.2”.
The charging function worked as expected, but “analogRead(P0_31)” to read the battery voltage did not work. To check, I tried other analog pins from A0 to A5, and “analogRead()” worked without any problem.

After much analysis, it seems that there is a problem in the macro “analogPinToPinName(P)” used in the “analogRead()” function. In the definition, “g_APinDescription” (digital pin description) is used instead of “g_AAnalogPinDescription” (analog pin description).

/Arduino15/packages/Seeeduino/hardware/mbed/2.7.2/cores/arduino/wiring_analog.cpp : 89

int analogRead(PinName pin)
{	
  for (pin_size_t i = 0; i < NUM_ANALOG_INPUTS; i++) {
    if (analogPinToPinName(i) == pin) {
      return analogRead(i + A0);
    }
  } 
  return -1;
}

/Arduino15/packages/Seeeduino/hardware/mbed/2.7.2/cores/arduino/pinDefinitions.h : 22

#define analogPinToPinName(P)       (P >= PINS_COUNT ? NC : P < A0 ? g_APinDescription[P+A0].name : g_APinDescription[P].name)

I changed “g_APinDescription” to “g_AAnalogPinDescription” and now “analogRead(P0_31)” also works as expected.

//#define analogPinToPinName(P)       (P >= PINS_COUNT ? NC : P < A0 ? g_APinDescription[P+A0].name : g_APinDescription[P].name)
#define analogPinToPinName(P)       (P >= PINS_COUNT ? NC : P < A0 ? g_AAnalogPinDescription[P+A0].name : g_AAnalogPinDescription[P].name)

my sample sketch

void setup() 
{
  Serial.begin(115200);
//  while(!Serial);

  pinMode(P0_31, INPUT);    //Battery Voltage monitoring pin

  pinMode(P0_13, OUTPUT);   //Charge Current setting pin
  pinMode(P0_14, OUTPUT);   //Enable Battery Voltage monitoring pin
  digitalWrite(P0_13, LOW); //Charge Current 100mA   
  digitalWrite(P0_14, LOW); //Enable

  analogReference(AR_INTERNAL2V4);  //Vref=2.4V
  analogReadResolution(12);         //12bits
}

void loop() 
{
  digitalWrite(LED_GREEN, LOW);
  delay(500);
  
  int Vadc = analogRead(P0_31);

  float Vbatt = ((510e3 + 1000e3) / 510e3) * 2.4 * Vadc / 4096;
  Serial.print("0x");Serial.print(Vadc, HEX);
  Serial.print(", "); 
  Serial.println(Vbatt, 3); 
  
  digitalWrite(LED_GREEN, HIGH);
  delay(500);
}
4 Likes

@msfujino Perfect!! I followed your instruction and it reads the battery voltage correctly. Thank you for sharing your findings.
Cheers!

+1 to that! Thank you msfujino :ok_hand:

Great Start on this… I tried this with the development board and it only displays battery voltage as long as the usb is connected. When I disconnect it drops to ZERO.
What am I doing wrong here, I made the changes to the pins file,BTW same problem.

Thanks for any incite to this problem, probably between the Keyboard and the Floor :slight_smile:
GL :slight_smile:





here is the code I’m running.

#include <Arduino.h>
#include <Wire.h>
#include <U8x8lib.h>

//Create a instance of class
U8X8_SSD1306_128X64_NONAME_HW_I2C u8x8(/* clock=*/ PIN_WIRE_SCL, /* data=*/ PIN_WIRE_SDA, /* reset=*/ U8X8_PIN_NONE);
// OLEDs without Reset of the Display
const int ledPin = LED_BUILTIN;
int BuzzerPin = A3;                 //A3 , P0.29 PIN 4
int buzzer = BuzzerPin;
int Vadc = analogRead(P0_31);
long mac = 00000000000000000;
long lowA;
long hiA;
void setup()
{
 Serial.begin( 9600 );
 pinMode(LEDR, OUTPUT);
 pinMode(LEDG, OUTPUT);
 pinMode(LEDB, OUTPUT);
 pinMode(LED_BUILTIN, OUTPUT);      // initialize the LED pin as an output:
 Serial.println("Processor came out of reset.\n");
 startsound(); 
 pinMode(P0_31, INPUT);    //Battery Voltage monitoring pin
 pinMode(P0_13, OUTPUT);   //Charge Current setting pin
 pinMode(P0_14, OUTPUT);   //Enable Battery Voltage monitoring pin
 digitalWrite(P0_13, LOW); //Charge Current 100mA   
 digitalWrite(P0_14, LOW); //Enable
 analogReference(AR_INTERNAL2V4);  //Vref=2.4V
 analogReadResolution(12);
 initdisplay();
 setupblink();  

}

void loop()
{
 // Serial.print( "Device ID 0: " );
 // Serial.println( NRF_FICR->DEVICEID[0], HEX );
 //Serial.print( "Device ID 1: " );
 // Serial.println( NRF_FICR->DEVICEID[1], HEX );
 //
  Serial.print( "Device Address 0: " );
  Serial.println( NRF_FICR->DEVICEADDR[0], HEX );
  Serial.print( "Device Address 1: " );
  Serial.println( NRF_FICR->DEVICEADDR[1], HEX );
  //mac = (DEVICEADDR[1],DEVICEADDR[0]);
 Serial.print( "MAC Address:" );
  //Serial.println( DEVICEADDR[1], HEX );
  lowA = NRF_FICR->DEVICEADDR[0], HEX ; //copy lower 8 hex bytes to varible
  hiA = NRF_FICR->DEVICEADDR[1], HEX ; //copy upper 8 hex bytes to varible
  Serial.print( hiA , HEX );//B1F8B34E
  Serial.print ( lowA , HEX );  //F529BC40
  delay ( 5000 );
  digitalWrite(LED_GREEN, LOW);
  delay(500);

  int Vadc = analogRead(P0_31);
  float Vbatt = ((510e3 + 1000e3) / 510e3) * 2.4 * Vadc / 4096;
  Serial.println();
  Serial.print("0x");Serial.print(Vadc, HEX);
  Serial.print(", "); 
  Serial.println(Vbatt, 3); 
  digitalWrite(LED_GREEN, HIGH);
  u8x8.clearDisplay();
  u8x8.setCursor(0,2);
  u8x8.print("Battery Monitor");
  u8x8.setCursor(6,6);
  u8x8.print(Vbatt, 3);
  //Serial.print(uint8_t mac_address[0]);
 delay(500);
}

void setupblink(){
  setLedRGB(false, false, true);  // set Blue LED 
    delay(1000);
    setLedRGB(false, true, false);  // Red
    delay(1000);
    setLedRGB(true, false, false);  // Green
    delay(1000);
    setLedRGB(false, false, false);  // OFF
}   

void initdisplay() {
  u8x8.begin();
    u8x8.setFlipMode(1);   // set number from 1 to 3, the screen word will rotary 180
    u8x8.setFont(u8x8_font_8x13B_1x2_r);
    u8x8.clearDisplay();
    u8x8.setCursor(0, 0);
    u8x8.print("Power ON ");
}

void startsound() {
  tone (buzzer, 890);
    delay (220);
    noTone(buzzer);
    delay (20);
    tone (buzzer, 800);
    delay (220);
    noTone(buzzer);
    delay (20);
    tone (buzzer, 800);
    delay (220);
    noTone(buzzer);
    delay (20);
    tone (buzzer, 990);
    delay (420);
    noTone(buzzer);
    delay (20);
}

void setLedRGB(bool red, bool green, bool blue) {
   if (!red) { digitalWrite(LEDR, HIGH); } else { digitalWrite(LEDR, LOW); }
   if (!green) { digitalWrite(LEDG, HIGH); } else { digitalWrite(LEDG, LOW); }
   if (!blue) { digitalWrite(LEDB, HIGH); } else { digitalWrite(LEDB, LOW); }
}

analogRead(P0_31) reads the battery voltage soldered to the pad on the back side of the board.Unfortunately, it cannot read the battery voltage connected to the JST connector on the expansion board.

I suspected that, but thanks for extra look.
GL :slight_smile:
I went back and soldered the battery to the tester and loaded the BLE code fromb4 and Battery_Service is reporting same level as usb when plugged in Works perfectly in case anyone wants to see. and btw the battery is at 39% LOL :-p



does this work with the xiao expansion board onboard charging chip or only with the sense module

Short answer NO. but that’s initially what I thought too, They set me straight and I tried it , It works on the BATT pads forsure. See pictures.
HTH
GL :slight_smile:

This problem was fixed in mbed 2.8.1.
[edit]
This problem was NOT fixed in mbed 2.8.1.

Today, mbed 2.9.0 was released, but for some reason this problem has not been resolved. Unfortunately, in order to read the battery voltage, you need to fix /Arduino15/packages/seeduino/hardware/mbed/2.9.0/cores/arduino/pinDefinitions.h : 22.

//#define analogPinToPinName(P)       (P >= PINS_COUNT ? NC : P < A0 ? g_APinDescription[P+A0].name : g_APinDescription[P].name)
#define analogPinToPinName(P)       (P >= PINS_COUNT ? NC : P < A0 ? g_AAnalogPinDescription[P+A0].name : g_AAnalogPinDescription[P].name)

HI, msfujino, thank you for your feedback, we will fix this issue as soon as possible, thank you again!

1 Like

nengyu thanks,
We are waiting for your resolution.

1 Like

Thank you - been banging my head all day - this patch fixes the problem!

Nengyu please do resolve this.

Everytime the library is updated we go back to the beginning with this issue. So much so I’ve added a self-reminder to the header of my Xiao sketches!

1 Like

Thank you for your attention to this. Mr nengyu,
pj

Just recieved 3 more Sense devices… (15)
I look forward to a Competent fix for this ongoing issue. Mr. Nengyu​:wink::ok_hand:


TiA.

2 Likes

Does anyone have an Arduino sketch that can read the battery voltage? When I tried the above (with arduino and serial includes and using the raw pin numbers, not “PO_” becuase Arduino doesn’t see those as proper pins) it tells me that pins 14 and 31 don’t exist. I did add them to the pins_arduino.h file as “D14” and “A31”, but that doesn’t work either, giving me a complaint from the gpio hal:

entry 0x403ce000
[    94][E][esp32-hal-gpio.c:102] __pinMode(): Invalid pin selected
ESP-ROM:esp32c3-api1-20210207
Build:Feb  7 2021
rst:0x8 (TG1WDT_SYS_RST),boot:0x8 (SPI_FAST_FLASH_BOOT)

This is using the XIAO_ESP32C3 board in Arduino directly. I don’t know what is MBED actually, which I think MFUJINO is reporting the error in. But, it’s possible the same error is propagated to the Arduino variants. Thanks!

Hi braddo,
The problem in this post only occurs with the combination of the board “Seeed XIAO_nRF52840” and the board library “Seeed nRF52 mbed-enabled Borads 2.7.2/2.8.1/2.9.0”.
For more information about your board “XIAO_ESP32C3”, please see the following link.

To all those who care about this:
Sorry for the long wait! We finally have the R&D resources to do the testing in question, and we’ll have it done within the week.

That’s GREAT News ! Well We are ALL here waiting to help , If I may say So.
You have such a Great product in the Xiao Line.
Lots of FAN Folks TOO, so let’s make some good end user products with your help.
Thank You.
GL :wink:

Hi Seed-Liu,
Will the following issues also be considered in this upgrade?