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

I’m very sorry about this, the engineer told me he tested it before the update. We will test again immediately. :smiling_face_with_tear:

msfujino’s patch is great, but it modifies the code in the /core/arduino directory instead of /variant, and trust me, if your code is not aligned with ArduinoCore-mbed, compatibility will be an issue. :slightly_smiling_face:
In 2.9.1, PIN_VBAT works, while P0_31 still does not. This was a serious mistake, for which I am sorry.
We will fix it soon (chatgpt go for it!

Hi, you are right, analogRead(P0_31) is still not available in v2.9.1, but analogRead(PIN_VBAT) should work. Can I have a look at your code?

In v2.9.1,analogRead(PIN_VBAT) should work, Refer to the code below

const int analogInPin = PIN_VBAT;
int raw_bat = 0;        // value read from the pot
int v_bat = 0;
uint8_t state = 0;

void setup() {
  Serial.begin(9600);
  pinMode(LED_BUILTIN, OUTPUT);
  pinMode(PIN_VBAT_ENABLE, OUTPUT); 
  digitalWrite(PIN_VBAT_ENABLE, LOW);
}

void loop() {
  
  state = 1 - state;
  digitalWrite(LED_BUILTIN, state);
  
  // read the analog in value:
  raw_bat = analogRead(analogInPin);
  v_bat = (raw_bat * 3 * 3300) / 1024;

  Serial.print("raw = ");
  Serial.print(raw_bat);
  Serial.print(", V = ");
  Serial.print(v_bat);
  Serial.println("mV");
  
  delay(500);
}

I confirmed that analogRead(PIN_VBAT) works, but the IDE hangs if there is a digitalWrite(LEDG, LOW); or digitalWrite(P0_30, LOW);.

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

//  pinMode(P0_31, INPUT);    //Battery Voltage monitoring pin
  pinMode(PIN_VBAT, 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(LEDG, LOW);
  delay(500);
  
//  int Vadc = analogRead(P0_31);
  int Vadc = analogRead(PIN_VBAT);

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

Hi Seeed-Jx,

I checked the LED and LED pin name and analogRead(PIN_VBAT) combination, but the 2/3 combination did not work correctly. In the worst case, the COM port was lost!
Below is the sketch I used to check.

#define LED LED_BUILTIN      // default
//#define LED LEDR                // OK : can read voltage and flush red LED
//#define LED LEDG                // NG : COM port disappears and off green LED
//#define LED LEDB                // OK : can read voltage and flush blue LED
//#define LED P0_26               // NG : can read voltage but always off red LED
//#define LED P0_30               // NG : COM port disappears and on green LED
//#define LED P0_6                // NG : can read voltage but on blue LED

const int analogInPin = PIN_VBAT;
int raw_bat = 0;        // value read from the pot
int v_bat = 0;
uint8_t state = 0;

void setup() {
  Serial.begin(9600);
  pinMode(LED, OUTPUT); 
  pinMode(PIN_VBAT_ENABLE, OUTPUT); 
  digitalWrite(PIN_VBAT_ENABLE, LOW);
}

void loop() { 
  state = 1 - state;
  digitalWrite(LED, state); 
  // read the analog in value:
  raw_bat = analogRead(analogInPin);
  v_bat = (raw_bat * 3 * 3300) / 1024;
  Serial.print("raw = ");
  Serial.print(raw_bat);
  Serial.print(", V = ");
  Serial.print(v_bat);
  Serial.println("mV");  
  delay(500); 
}

Not to mention EVERY update to the IDE, will break the end result without the PINS fix . So YEA! LoL ChatGpt…
and when your trying to produce a prototype with code that will LIVE up to NOT just my HIGH personal standards but truth in advertising matter’s as much as PERFORMANCE IMO :pray: Apparently someone at Seeed marketing thought enough to say so on the second bullet point. (and you do realize if you can’t read the battery properly and reliably then battery powered is in two words is NOT REAL.

AND while I’m up here… :star_struck: YOU notice the two biggest issues folks have on here with this chip is “Deep Sleep” and Battery power items along with mbed conflicts and incompatibilities… So it’s a GREAT product alright but ON-Going and Timely technical support and continuing Engineering is warranted at $16
----soap box off__

" * Wireless Capabilities: Implement Bluetooth 5.0, BLE functions with onboard antenna, also provide NFC connectivity

  • Elaborate Power Design: Provide ultra-low power consumption as 5 μA in deep sleep mode while supporting lithium battery charge management
  • Advanced onboard Functionality: Assemble additional digital microphone and 6-axis IMU in the tiny board for embedded Machine Learning applications
  • Thumb-sized Design: 21 x 17.5mm, Seeed Studio XIAO series classic form-factor, suitable for wearable devices

Seeed Studio XIAO nRF52840 Sense has an ultra-low power consumption of only 5 μA in the deep sleep mode, the embedded BQ25101 chip supports battery charge management which prolongs its use time. (we hope)

I look forward to a fix. I’ll try it.

Thanks for you quick response’s.
:+1:
GL
:slight_smile:

For some reason, analogRead(PIN_VBAT) and LEDs have a close relationship, and some combinations can cause hang-up.Below is a summary of the relationship between red LED or green LED and analogRead().

				      v2.9.0   v2.9.0+patch	  v2.9.1	v2.9.1+variant
with LEDG
analogRead(PIN_VBAT)	XXX			O			XXX			O
analogRead(P0_31)		X			O			X			O

with LED_BUILTIN
analogRead(PIN_VBAT)	XXX			O			O			O
analogRead(P0_31)		X			O			X			O

X:	can't read
XXX:hang up
O:	work

Both v2.9.0 and v2.9.1 do not work properly with the green LED. Applying the patch proposed in #1/30 to v2.9.0 makes it work as expected, but Seeed-Jx pointed out a compatibility problem.I modified two files in the variant folder to work around the compatibility problem. I replaced variant.cpp and pins_arduino.h with the attached files and checked the sketch and it works fine.
I would be happy if someone could confirm this.

analogReadTEST.zip (5.4 KB)

The following is the confirmation procedure.

  1. Unzip the file “analogReadTEST.zip”.
  2. Delete “pin_arduino.h” and “variant.cpp” in directry “\Arduino15\packages\Seeeduino\hardware\mbed\2.9.1\variants\SEEED_XIAO_NRF5284” and “\Arduino15\packages\Seeeduino\hardware\mbed\2.9.1\variants\SEEED_XIAO_NRF5284_SENSE”,
    then copy “pin_arduino.h” and “variant.cpp” from the unzip folder.
  3. Copy “analogRead_LED” to an appropriate location.
  4. Compile and execute “analogRead_LED” from ArduinoIDE.

The pinDefinitions.h patch is not necessary since the variants file will be replaced in v2.9.1.

I tried replacing those files in the variants folder but no go. My 2.9.1 has the moded #1/30 pins.h as b4.
The only one that still works and is about .03 vdc difference which is ok for my app at present but I stand on SEEED making this work like an Adafruit or Nordic reference design to be sure it’s there brew.




code below. running on dev board.

//TESTED AOK.12/15/22
// Displays Xiao Unit ID
// Xiao MAC:
// Battery Monitor.

#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;
volatile int Vadc = analogRead(P0_31);       // Xiao ADC for BATT mon.
uint8_t mac_address[6];             // MAC_address ARRAY


void setup(){
 Serial.begin(9600);
 delay(2000);                       //relax...Get Ready for serial port
 Serial.println("Processor came out of reset.\n");
 startsound();
 setBatt();
 initdisplay();
 setupblink();  

}
void loop(){
char buff[6];
get_id_address(mac_address);
sprintf(buff, "\nXiao Unit: %02lX%02lX\n",
          mac_address[0],mac_address[1]);
  Serial.print(buff);
  u8x8.clearDisplay();
  u8x8.setCursor(0,-1);
  u8x8.print(buff);
  u8x8.setCursor(6,6);
delay(2000);

char buffer[80];
char bufferu8[80];
get_mac_address(mac_address);
sprintf(buffer, "Xiao MAC: %02lX:%02lX:%02lX:%02lX:%02lX:%02lX\n",
          mac_address[0],mac_address[1],mac_address[2],mac_address[3],mac_address[4],mac_address[5] ,mac_address[6]);
  Serial.print(buffer);
  sprintf(bufferu8, "Xiao MAC: \n%02lX%02lX%02lX%02lX%02lX%02lX\n",
          mac_address[0],mac_address[1],mac_address[2],mac_address[3],mac_address[4],mac_address[5] ,mac_address[6]);
  u8x8.setCursor(0,3);
  u8x8.print(bufferu8);
delay (2000);
getBattery();
delay (2000);


}

// 
//************************functions **********************
//

void get_unit_id(){
char buff[2];
get_id_address(mac_address);
sprintf(buff, "\nXiao Unit: %02lX%02lX\n", mac_address[0],mac_address[1]);
  Serial.print(buff);
  u8x8.clearDisplay();
  u8x8.setCursor(0,-1);
  u8x8.print(buff);
  u8x8.setCursor(6,6);
delay(100);
}

void do_mac(){
  char buffer[80];
  char bufferu8[80];
  Serial.println("");
  get_mac_address(mac_address);
  sprintf(buffer, "Xiao MAC: %02lX:%02lX:%02lX:%02lX:%02lX:%02lX\n",
          mac_address[0],mac_address[1],mac_address[2],mac_address[3],mac_address[4],mac_address[5] ,mac_address[6]);
  Serial.print(buffer);
  sprintf(bufferu8, "Xiao MAC: \n%02lX%02lX%02lX%02lX%02lX%02lX\n",
          mac_address[0],mac_address[1],mac_address[2],mac_address[3],mac_address[4],mac_address[5] ,mac_address[6]);
  u8x8.setCursor(0,3);
  u8x8.print(bufferu8);
}

void get_id_address(uint8_t mac_address[6]) {
	unsigned int device_addr_0 = NRF_FICR->DEVICEADDR[0];
	unsigned int device_addr_1 = NRF_FICR->DEVICEADDR[1];
	const uint8_t* part_0 = reinterpret_cast<const uint8_t*>(&device_addr_0);
	const uint8_t* part_1 = reinterpret_cast<const uint8_t*>(&device_addr_1);
	mac_address[0] = part_1[3];   //changed from get_mac_address elements 0,1
	mac_address[1] = part_1[2];   //
}

void setBatt(){
  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);
}

void getBattery(){
  int Vadc = analogRead(P0_31);
  float Vbatt = ((510e3 + 1000e3) / 510e3) * 2.466 * Vadc / 4096;
  Serial.print("Battery Level "); 
  Serial.println( Vbatt, 2); 
  digitalWrite(LED_GREEN, HIGH);
  u8x8.clearDisplay();
  u8x8.setCursor(0,2);
  u8x8.print("Battery Monitor");
  u8x8.setCursor(6,6);
  u8x8.print(Vbatt, 2);
}

void get_mac_address(uint8_t mac_address[6]) {
	unsigned int device_addr_0 = NRF_FICR->DEVICEADDR[0];
	unsigned int device_addr_1 = NRF_FICR->DEVICEADDR[1];
	const uint8_t* part_0 = reinterpret_cast<const uint8_t*>(&device_addr_0);
	const uint8_t* part_1 = reinterpret_cast<const uint8_t*>(&device_addr_1);
	mac_address[0] = part_1[1];
	mac_address[1] = part_1[0];
	mac_address[2] = part_0[3];
	mac_address[3] = part_0[2];
	mac_address[4] = part_0[1];
	mac_address[5] = part_0[0];
}

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() {
 pinMode(LEDR, OUTPUT);         // initialize the LED pin as an output:
 pinMode(LEDG, OUTPUT);         // initialize the LED pin as an output:
 pinMode(LEDB, OUTPUT);
 pinMode(LED_BUILTIN, OUTPUT);      // initialize the LED pin as an output:
  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); }
}

print output,

Processor came out of reset.


Xiao Unit: 53BB
Xiao MAC: 21:0E:63:78:CF:67
Battery Level 3.50

Xiao Unit: 53BB
Xiao MAC: 21:0E:63:78:CF:67
Battery Level 3.51

Xiao Unit: 53BB
Xiao MAC: 21:0E:63:78:CF:67
Battery Level 3.50

HTH
GL :slight_smile:

Hi PJ,
Thanks for trying. English is not my first language, so I am not sure what you mean. I have a few questions.

My 2.9.1 has the moded #1/30 pins.h as b4.

1.Do you mean that you have “pins.h” in your “variants” directory?
2.What is “b4”?
3.Is the structure of “variants” directory “\Arduino15\packages\Seeduino\hardware\mbed\2.9.1\variants\SEEED_XIAO_NRF5284” different from yours?

4.Why do you use 2.466 instead of 2.4 in getBattery()?

Hay, Yea it’s the moded pinsDefinitions.h in your orginal post.
at c:~“\Arduino15\packages\Seeduino\hardware\mbed\2.9.1\cores\arduino
Same structure as yours on the variants folder path but the sense version. ie.
“\Arduino15\packages\Seeduino\hardware\mbed\2.9.1\variants\SEEED_XIAO_NRF5284_SENSE”
When I pasted them in from the zip ,compiler complained about renaming originals to “OLDvariant” & “OLDpins_arduino” and ADDING them from analogRead_LED.zip
Just messing with the ref to tweak the deviation +/- .03 deviation between the dvm and the serial print and OLED :wink: :wink:
HTH
GL :-p

PJ,
Thanks for the report.
I have written the detailed procedure. If you don’t mind, could you try again?

The following is the confirmation procedure.

  1. Unzip the file “analogReadTEST.zip”.
  2. Delete “pin_arduino.h” and “variant.cpp” in directry “\2.9.1\variants\SEEED_XIAO_NRF5284” and “\2.9.1\variants\SEEED_XIAO_NRF5284_SENSE”,
    then copy “pin_arduino.h” and “variant.cpp” from the unzip folder.
  3. Copy “analogRead_LED” to an appropriate location.
  4. Compile and execute “analogRead_LED” from ArduinoIDE.

GM,
OK I did it by your instructions.
Appears to work but the numbers are different?
HTH
GL :slight_smile:


code + Chop

//----------------------------------------------------------------------------------------------
//CHOP CHOP
//Board Library : Seeed nRF52 mbed-enable Borads 2.9.1
//Board Select  : Seeed nRF52 mbed-enable Borads / Seeed XIAO BLE - (nRF52840)
//2023/02/12
//Arduino15\packages\Seeeduino\hardware\mbed\2.9.1\variants\SEEED_XIAO_NRF52840/
//  replase pins_arduino.h and variant.cpp
//----------------------------------------------------------------------------------------------
#include <Arduino.h>
#include <U8x8lib.h>
//#define LED LED_BUILTIN         // default
//#define LED LEDR
#define LED LEDG
//#define LED LEDB
//#define LED P0_26   // RED
//#define LED P0_30   // GREEN
//#define LED P0_6    // BLUE
//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 analogInPin = PIN_VBAT;
bool state = false;


void setup() {
  Serial.begin(9600);
  while (!Serial);
  delay(3000);//relax...Get Ready for serial port
  Serial.println();
  Serial.println("Power ON \n ");  // Let's BEGIN!!
  Serial.println("Test program compiled on " __DATE__ " at " __TIME__);
  Serial.println();
  Serial.println("Processor came out of reset.");
  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 ");
  delay(3000); 

  pinMode(PIN_VBAT_ENABLE, OUTPUT);   // P0_14
  digitalWrite(PIN_VBAT_ENABLE, LOW);
  pinMode(PIN_CHARGE_HIGH, OUTPUT);   // P0_13
  digitalWrite(PIN_CHARGE_HIGH, LOW);   
}

void loop() {
  state = !state;
  digitalWrite(LED, (state ? LOW: HIGH));
  digitalWrite(LED, state);
  u8x8.clearDisplay();
  u8x8.setCursor(0, 0);
  u8x8.print("PIN_VBAT=");
  u8x8.setCursor(3, 2);
  u8x8.print((analogRead(PIN_VBAT) * 3 * 3300) / 1024);
  digitalWrite(LED_GREEN, LOW);
  u8x8.setCursor(0, 4);
  u8x8.print("  P0_31=");
  u8x8.setCursor(3, 6);
  u8x8.print((analogRead(P0_31) * 3 * 3300) / 1024);

  Serial.print("PIN_VBAT="); 
  Serial.print((analogRead(PIN_VBAT) * 3 * 3300) / 1024);
  Serial.print(" P0_31=");
  Serial.print((analogRead(P0_31) * 3 * 3300) / 1024);
  Serial.println();
     
  delay(500); 
  setupblink();

}

//========================functions===============

void initdisplay() {
  pinMode(LEDR, OUTPUT);  // initialize the LED pin as an output:
  pinMode(LEDG, OUTPUT);  // initialize the LED pin as an output:
  pinMode(LEDB, OUTPUT);
  pinMode(LED_BUILTIN, OUTPUT);  // initialize the LED pin as an output:
  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 setupblink() {

  setLedRGB(false, true, false);  // Red
  delay(1000);
  setLedRGB(true, false, false);  // Green
  delay(1000);
  setLedRGB(false, false, true);  // Blue 
  delay(1000);
  setLedRGB(false, false, false);  // OFF
}

void setLedRGB(bool red, bool green, bool blue) {

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

Output


Power ON 
 
Test program compiled on Feb 14 2023 at 11:59:31

Processor came out of reset.
PIN_VBAT=8343 P0_31=8459
PIN_VBAT=8382 P0_31=8478
PIN_VBAT=8343 P0_31=8527
PIN_VBAT=8353 P0_31=8517
PIN_VBAT=8343 P0_31=8488
PIN_VBAT=8333 P0_31=8459

Hi PJ,
Thanks for trying.
I have tried with your sketch. I am able to measure the battery voltage without any problem. I don’t know why it differs from your numbers. But the variants files seems to be working fine.
Thanks.

08:32:10.736 -> Power ON 
08:32:10.736 ->  
08:32:10.736 -> Test program compiled on Feb 15 2023 at 08:26:12
08:32:10.736 -> 
08:32:10.736 -> Processor came out of reset.
08:32:14.207 -> PIN_VBAT=4041 P0_31=4041
08:32:17.794 -> PIN_VBAT=4012 P0_31=4021
08:32:21.364 -> PIN_VBAT=4012 P0_31=4041
08:32:24.971 -> PIN_VBAT=4021 P0_31=4021
08:32:28.547 -> PIN_VBAT=4021 P0_31=4041
08:32:32.129 -> PIN_VBAT=4041 P0_31=4050

analogRead

Wow Cool, :sunglasses:
I wonder if the core folder pinDefinition tweek is causing that?
GL :slight_smile:

The pinDefinitions.h patch is not necessary since the variants file will be replaced in v2.9.1.

Hay msfujino, Thanks again for all the help on this thread and battery. So does this mean there will be a v2.9.2 update ?
:v:
:slight_smile:

btw , English IS my Only Language (besides some basic, water, pencil and swear words in others) Your explanations are more clear and Sy sync than I…all day :wink: :+1:

PJ, thanks for always trying my sketches.

As shown in the table in post #30, my patch in post #1 is valid for v2.7.2 to v2.9.0 to get analogRead() and a green LED(LEDG) working, and for v2.9.1,need to replace “variant.cpp” and “pins_arduino.h” with my modified files.
Unfortunately, I have posted some problems to “GitHub - Seeed-Studio/ArduinoCore-mbed” issues so far with no response.
I only hope that Seeed engineers will consider my modified files and v2.9.2 will be officially update.

1 Like

SO just wondering if this thing is on ? And on Seeed Radar . Crickets ?
No updates from them at all?
Yoi :face_with_peeking_eye:

So far no action has been taken.
Unfortunately, I believe Seeed has a policy of not devoting resources to software development.