XIAO BLE Sense battery level and charging status

I havenā€™t tried to access the LSM6DS3, but hereā€™s the deal:

There are discrepancies between schematic and software that I havenā€™t figured out yet.

Iā€™m leaving this project for the time being (got other fish to fry). Maybe, just maybe someone can get help from the folks at Seeed. Like, perhaps a real schematic and software examples that really work.

Here are some issues (Pardon my verbosity, but I just canā€™t seem to boil it down)

Issue 1:
The schematic shows pin 31 (P0.31) as the input to the ADC to read battery voltage through its voltage divider. We have all discovered that this does not work.

On the other hand, as I discovered, the arduino_pins.h header in the variants directory for this board defined PIN_VBAT to be 32.

Thatā€™s P1.0, but the schematic labels P1.0 as P1.00_PDM_CLK. I havenā€™t tried any PDM functions.

Bottom line: P1.0 works to read the ADC

Score so far: Software wins. (At least as far as reading the Battery Voltage.)

Issue 2:
Everyone on this thread, (including me) has used pin 14 (P0.14) as the active-low signal to ground one end of the voltage divider so that the battery voltage is scaled properly. This is shown on the schematic as P0_14_READ_BAT (with a bar over the ā€˜READ_BATā€™ to indicate active-low).

However, in the arduino_pins.h, there is the following:

#define PIN_LSM6DS3TR_C_POWER (14u)

The Seeed_Arduino_LSM6DS3 library that you are apparently using causes PIN_LSM6DS3TR_C_POWER to go high once (during the begin() method) to access the LSM6DS3. I donā€™t know if that is the actual connection. In this case, the schematic shows the power pins and Chip Select pin for the LSM6DS3 are connected to a signal named 6D_PWR, which goes to P1.08 on the CPU, which is numerically pin 40.

Bottom line: If you can get the LSM6DS3 to work by making pin 14 High and you can read the battery by making pin 14 go low, then you have to set pin 14 high (every time) after reading the battery before accessing the LSM6D3. This might pinpoint the problem, but doesnā€™t sound practical in an application.

The problem is, of course, those connections are hidden below the shield, and Iā€™m not going to pry things apart to see what really goes where, and I donā€™t have time for more software exploration.

Sorry, but Iā€™m done for nowā€”maybe done with Seeed forever. Got other (non-Seeed) things to do that actually pay the bills.

Regards,

Dave

6 Likes

I found a symbol about VBATT in valiantā€¦cpp file.

// VBAT
{ P0_14, NULL, NULL, NULL }, // D31/VBAT_ENABLE
{ P0_31, NULL, NULL, NULL }, // D32/VBAT_READ

So, We can use VBAT_ENABLE with this statement.

#define PIN_VBATENABLE (31u) // this is not defined in pins_arduino.h file.

pinMode(PIN_VBATENABLE, OUTPUT);
digitalWrite(PIN_VBATENABLE, LOW);

I really appreciate your insight on this topic. I have some areas to explore as you indicated. Will post here if I am successful. Thanks again :slight_smile:

Dave, youā€™re a godsend. Have a great week, good luck with your other stuff.

Well, Iā€™m baaaaaaack

Update to mithundotdas (and anyone else out there who is still interested):

I loaded your test program, and a little experimentation indicated that the problem manifests itself with the analogRead() of the ADC value, not the digitalWrite() of the enable signal.

Soā€¦
I wired an external voltage divider that used the XIAO BLE analog pin 3 as the ADC input and digital pin 4 as the enable signal.

Result was: Taa-Daa!

Details:

1.
I connected a 1 Megohm resistor from the + terminal of the battery to Pin A3.

2.
I connected a 560K Ohm from Pin A3 to Pin D4. (The schematic shows 510K here, but my spare parts box didnā€™t have a 510K, so I used something not too different that I did have.)

3.
I made some definitions in the sketch and changed the formula to take into account the changes.

I started the sketch and tested the reported values on the Serial Monitor and on my phone. (Green LED on the XIAO BLE came on, then turned Blue upon successful connection to Central, ADC voltage values were printed out every second, and the phone app could obtain the battery voltage, as expected.)

I used a generic app, LightBlue, instead of the specific app for this program. Itā€™s somewhat awkward, but for debugging, I donā€™t have to worry about understanding (and debugging) some specific program other than the one Iā€™m working on with the XIAO BLE.

Bottom line:
The existing board is useless for the application you have in mind without a little (very little, actually) external circuit . (Pardon me if you have heard this before, but donā€™t those Seeed guys actually test this stuff before releasing hardware and/or software and/or the integration?)

There are other discrepancies on the schematic involving various connections, and it just may happen that my selection of pins for the external voltage divider screw the pooch for other applications, but maybe it gets you past top dead center for further testing.

Final note:
Wiring the new connections on my solderless breadboard was quick and easy, but note that it tends to be pretty noisy unless you dress the leads carefully. Adding a small capacitor from the ADC input pin to ground might help a little. A simple running average in the program will make it settle down a lot. (Or so I claim.)

Hereā€™s my modified sketch:


/**
This prorgam is written to collect IMU data from XIAO BLE Sense and send to EI Blue mobile app. 
EI Blue mobile app uploads the data to Edge Impulse Studio.
Visit https://wiki.seeedstudio.com/XIAO-BLE-Sense-Bluetooth-Usage/ to setup Arduino IDE 
Get EI Blue mobile app from https://github.com/just4give/ei-blue 

Some mods by davekw7x
March, 18, 2022
*/

REDIRECT_STDOUT_TO(Serial);

#include <ArduinoBLE.h>
#include <LSM6DS3.h>
#include <Wire.h>

#define BLENAME                       "EIBLUE"
#define SERVICE_UUID                  "4D7D1101-EE27-40B2-836C-17505C1044D7"
#define TX_PRED_CHAR_UUID             "4D7D1106-EE27-40B2-836C-17505C1044D7"
#define TX_BAT_CHAR_UUID              "4D7D1107-EE27-40B2-836C-17505C1044D7"
#define RX_CHAR_UUID                  "4D7D1108-EE27-40B2-836C-17505C1044D7"
#define SAMPLING_RATE                 50   //Hz
#define DURATION                      1 //seconds


BLEService bleService(SERVICE_UUID); // BluetoothĀ® Low Energy LED Service

// BluetoothĀ® Low Energy LED Switch Characteristic - custom 128-bit UUID, read and writable by central
BLEStringCharacteristic rxCharacteristic(RX_CHAR_UUID, BLEWrite, 1024);
BLEStringCharacteristic txPredCharacteristic(TX_PRED_CHAR_UUID, BLERead | BLENotify, 1024);
BLEStringCharacteristic txBatCharacteristic(TX_BAT_CHAR_UUID, BLERead | BLENotify, 1024);

LSM6DS3 myIMU(I2C_MODE, 0x6A);    //I2C device address 0x6A
float aX, aY, aZ, gX, gY, gZ;
const float accelerationThreshold = 2.5; // threshold of significant in G's


const double vRef = 3.3; // Assumes 3.3V regulator output is ADC reference voltage
const unsigned int numReadings = 1024; 
#define EXTERNAL_VBAT PIN_A3
#define EXTERNAL_VBAT_READ_ENABLE  D4
const double rhik = 1000.0; // 1000K Ohms = 1 Meg to Vref
const double rlok =  560.0;  // 560K Ohms to Gnd
const double dividerFactor = (rhik + rlok)/rlok; // Multiply ADC voltage by this to get Vbat

void setup() {
  Serial.begin(115200);
  while (!Serial);
  
  Serial.println("BLE Test compiled on " __DATE__ " at " __TIME__);
  Serial.println("BLE Test compiled on " __DATE__ " at " __TIME__);
  Serial.print("EXTERNAL_VBAT_READ_ENABLE = ");Serial.println(EXTERNAL_VBAT_READ_ENABLE);
  Serial.print("EXTERNAL_VBAT = "); Serial.println(EXTERNAL_VBAT);
  pinMode(EXTERNAL_VBAT_READ_ENABLE, OUTPUT);
  digitalWrite(EXTERNAL_VBAT_READ_ENABLE,LOW);
  
  // set LED pin to output mode
  pinMode(LEDB, OUTPUT);
  pinMode(LEDR, OUTPUT);
  pinMode(LEDG, OUTPUT);
  
  digitalWrite(LEDR, HIGH);
  digitalWrite(LEDB, HIGH);
  digitalWrite(LEDG, LOW);

  
   
  // begin initialization
  if (!BLE.begin()) {
    Serial.println("starting BluetoothĀ® Low Energy module failed!");

    while (1);
  }

  // set advertised local name and service UUID:
  BLE.setLocalName(BLENAME);
  BLE.setDeviceName(BLENAME);
  BLE.setAdvertisedService(bleService);

  // add the characteristic to the service
  bleService.addCharacteristic(txBatCharacteristic);
  bleService.addCharacteristic(txPredCharacteristic);
  bleService.addCharacteristic(rxCharacteristic);

  // add service
  BLE.addService(bleService);

  BLE.setEventHandler(BLEConnected, blePeripheralConnectHandler);
  BLE.setEventHandler(BLEDisconnected, blePeripheralDisconnectHandler);

  
  // start advertising
  BLE.advertise();

  Serial.println("BLE Peripheral");

  if (myIMU.begin() != 0) {
    Serial.println("Device error");
  } else {
    Serial.println("aX,aY,aZ,gX,gY,gZ");
  }

}


void loop() {
  
  BLEDevice central = BLE.central();

  if (central) {
  Serial.print("Connected to central: ");
  //unsigned int adcCount = 400;
  unsigned int adcCount = analogRead(EXTERNAL_VBAT);
  double adcVoltage = (adcCount * vRef) / numReadings;
  double vBat = adcVoltage*dividerFactor; // Voltage divider from Vbat to ADC
  printf("adcCount = %3u = 0x%03X, adcVoltage = %.3fV, vBat = %.3f\n",
             adcCount, adcCount, adcVoltage, vBat);


    String data="";
    data =  String(myIMU.readFloatAccelX(), 3)+","+String(myIMU.readFloatAccelY(), 3)+","+String(myIMU.readFloatAccelZ(), 3);

    
    txBatCharacteristic.writeValue(String(vBat));
    txPredCharacteristic.writeValue(data.c_str());
  
    delay(1000);
  }
}

void blePeripheralConnectHandler(BLEDevice central) {
  // central connected event handler
  Serial.print("Connected event, central: ");
  Serial.println(central.address());
  digitalWrite(LEDB, LOW);
  digitalWrite(LEDG, HIGH);
  digitalWrite(LEDR, HIGH);

}

void blePeripheralDisconnectHandler(BLEDevice central) {
  // central disconnected event handler
  Serial.print("Disconnected event, central: ");
  Serial.println(central.address());
  digitalWrite(LEDB, HIGH);
  digitalWrite(LEDG, LOW);
  digitalWrite(LEDR, HIGH);
}

Regards,

Dave

7 Likes

Thanks Dave for checking it out. I assumed external circuit with voltage divider would work but did not want to have external circuit due to small form factor of my POC and also as XIAO already has a charging chip in it, this feature should have been out of the box :slight_smile: Hope Seeed will fix this or document it so that someone can read battery without external circuit.

1 Like

Hi mithundotdas,

After some digging, I found a way to read PIN_VBAT value and keep BLE & IMU working at the same time.

Issue:

As noted by Dave, bluetooth drops connection when calling analogRead. It turns out that the current analogRead implementation blocks the thread until reading is completed. Here is the calling stack:

analogRead()
  -> mbed::AnalogIn::read()
    -> mbed::AnalogIn::read_u16()
      -> mbed::analog_read_u16()
        -> nrfx_saadc_sample_convert() // blocking

Fortunately Nordic provides another non-blocking api to convert adc value. Details here SAADC Drivers.

So the solution becomes clear, replace nrfx_saadc_sample_convert() with nrfx_saadc_buffer_convert() in analogRead.

But we canā€™t just modify the source code, because the implementation of mbed::AnalogIn is in the static library libmbed.a.

So we need to implement a non-blocking version of analogRead.

Quick hacky solution:

#include <nrf52840.h>
#include <nrfx_saadc.h>
#include <AnalogIn.h>
#include <pinDefinitions.h>

class HackAnalogIn: public mbed::AnalogIn {
  using mbed::AnalogIn::AnalogIn;
  public:
    analogin_t getAnalogIn_t();
};

analogin_t HackAnalogIn::getAnalogIn_t() {
  return this->_adc;
}

void startReadingBatteryLevel (nrf_saadc_value_t* buffer) {
  auto pin = PIN_VBAT;
  PinName name = analogPinToPinName(pin);
  if (name == NC) { return; }
  HackAnalogIn* adc = static_cast<HackAnalogIn*>(analogPinToAdcObj(pin));
  if (adc == NULL) {
    adc = new HackAnalogIn(name);
    analogPinToAdcObj(pin) = static_cast<mbed::AnalogIn*>(adc);
#ifdef ANALOG_CONFIG
    if (isAdcConfigChanged) {
      adc->configure(adcCurrentConfig);
    }
#endif
  }

  nrfx_saadc_buffer_convert(buffer, 1);
  nrfx_err_t ret = nrfx_saadc_sample();
  if (ret == NRFX_ERROR_BUSY) {
    // failed to start sampling
    return;
  }
}

void setup() {
  pinMode(P0_14, OUTPUT);
  digitalWrite(P0_14,LOW);
  // init BLE, IMU and other peripherals here
  ...
}

nrf_saadc_value_t BatteryLevel = { 0 };

void loop() {
  // BLE.poll()
  static unsigned long _lastT = 0;
  unsigned long _t = millis();

  if (_t - _lastT > 1000) {
    // read battery level every 1 second
    startReadingBatteryLevel(&BatteryLevel);
    _lastT = _t;
  }
  
  // check if ADC conversion has completed
  if (nrf_saadc_event_check(NRF_SAADC_EVENT_DONE)) {
    // ADC conversion completed. Reading is stored in BatteryLevel
    nrf_saadc_event_clear(NRF_SAADC_EVENT_DONE);
    float vBat = (float)BatteryLevel / 4096 * 3.3 / 510 * (1000 + 510);
    // write value to characteristic or things you want to do
    ...
  }
  ...
}

here are some test result:

vBat          EXTERNAL_VOLTMETER
4.03          4.13
4.01          4.14
3.96          4.06
3.93          4.04

Although the value is not absolute precise, but a strong linear correlation can be seen. I was able to obtain a pretty good reading by adjusting the conversion function to (float)BatteryLevel / 1340 * 3.3.

Iā€™ll post a proper designed battery reading library later.

Hope it helps.

6 Likes

Nice solution POPOBE97!

Everything works fine with your code when I use it without any modifications.

I have one issue though. When I set the pin mode for the RGB leds to OUTPUT then nrf_saadc_event_check(NRF_SAADC_EVENT_DONE) always returns zero/false. I have no idea why this could cause an issue though. Do you have any ideas?

pinMode(LEDR, OUTPUT);
pinMode(LEDG, OUTPUT);
pinMode(LEDB, OUTPUT);

I will continue to test some more

Edit:

It seems that only LEDG will cause the issue if you set that to pinMode OUTPUT.

Here is the complete sketch/code:

#include <nrf52840.h>
#include <nrfx_saadc.h>
#include <AnalogIn.h>
#include <pinDefinitions.h>

// Reading Battery Level
// https://forum.seeedstudio.com/t/xiao-ble-sense-battery-level-and-charging-status/263248/24

class HackAnalogIn: public mbed::AnalogIn 
{
  using mbed::AnalogIn::AnalogIn;
  public:
    analogin_t getAnalogIn_t();
};

analogin_t HackAnalogIn::getAnalogIn_t() 
{
  return this->_adc;
}

void startReadingBatteryLevel(nrf_saadc_value_t* buffer) 
{
  auto pin = PIN_VBAT;
  PinName name = analogPinToPinName(pin);
  if (name == NC)
  {
    return;
  }
  HackAnalogIn* adc = static_cast<HackAnalogIn*>(analogPinToAdcObj(pin));
  if (adc == NULL)
  {
    adc = new HackAnalogIn(name);
    analogPinToAdcObj(pin) = static_cast<mbed::AnalogIn*>(adc);
#ifdef ANALOG_CONFIG
    if (isAdcConfigChanged)
    {
      adc->configure(adcCurrentConfig);
    }
#endif
  }

  nrfx_saadc_buffer_convert(buffer, 1);
  nrfx_err_t ret = nrfx_saadc_sample();
  if (ret == NRFX_ERROR_BUSY)
  {
    // failed to start sampling
    return;
  }
}

nrf_saadc_value_t BatteryLevel = { 0 };

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

  Serial.println("Battery Level Example!");  

  pinMode(LEDR, OUTPUT);
  pinMode(LEDG, OUTPUT); // Setting LEDG to pinMode OUTPUT casues the monitoring of Battery Level to stop working
  pinMode(LEDB, OUTPUT);
  
  // Battery Level setup
  pinMode(P0_14, OUTPUT);
  digitalWrite(P0_14,LOW);
}

void loop()
{
  // Monitor the Battery Level
  static unsigned long _lastT = 0;
  unsigned long _t = millis();

  if (_t - _lastT > 1000)
  {
    // read battery level every 1 second
    startReadingBatteryLevel(&BatteryLevel);
    _lastT = _t;
    Serial.print("startReadingBatteryLevel at time ");
    Serial.println(_t);
  }

  // check if ADC conversion has completed
  if (nrf_saadc_event_check(NRF_SAADC_EVENT_DONE))
  {
    // ADC conversion completed. Reading is stored in BatteryLevel
    nrf_saadc_event_clear(NRF_SAADC_EVENT_DONE);
    float vBat = (float)BatteryLevel / 4096 * 3.3 / 510 * (1000 + 510);
    // write value to characteristic or things you want to do
    
    Serial.print("BatteryLevel: ");
    Serial.println(vBat);
  }
}
1 Like

Hi MonsterSmurf,

Unfortunately I have no idea why the code is causing this issue. And Iā€™m moving on to the next project so possibly never going to inspect deeper.

I can provide with you some possible guesses for further inspection, although I strongly suggest you not to because the lack of documentation. (TBH by what we have discussed so far, this hardware really is nothing but a black hole)

  1. What I have placed in the code is a hack way of catching ADC event. This means it will effect all ADC related functionalities. Although LED does not depend on ADC, it does require DAC to function correctly. ADC and DAC may share some resources and therefore causes the problem. Possible solution to this is adding lock before you read/write on DAC related registers.
  2. As you described, only LEDG have this issue. Again, according to what weā€™ve discussed, the circuit diagram they provide is not very credible. So who know where LEDG is attached to. Possible solution to this is use other LEDs. You can combine LEDR with LEDB to generate countless types of color anyways.

Wish you luck with your project

1 Like

Hi, Iā€™m sorry I canā€™t help you. Iā€™ve been working on a similar project recently and have encountered similar problems. When I find a solution to the problem, I will share it with you.

2 Likes

I am also able to get battery reading without LEDG. So I think @POPOBE97 's code is the solution. I am making that a solution. Thanks a lot @POPOBE97

2 Likes

I do not have the hardware yet, but reading the various fixes. Looks like this solution will only work with the Mbed based 2.6.1 version of the board (ArduinoBLE) not the 1.0 version based on Adafruitā€™s libraries. What would be a quick fix for the 1.0 version?

@POPOBE97 thanks for sharing your code! Could anyone explain where the various numbers are coming from in float vBat = (float)BatteryLevel / 4096 * 3.3 / 510 * (1000 + 510); - specifically the 4096, 3.3, 510 and 1510.

Iā€™m using a 3.7v 300mAh battery connected to the pads and it seems to be working well and Iā€™m getting readings using the code from @POPOBE97 but Iā€™m looking to convert that into a rough percentage (or even just a high/medium/low)

4096 : this is the range limit of the 12-bit ADC (so 0=0% and 4095=100%) . (Although I think the code should use 4095 not 4096? :thinking: )

3.3 : this is supposed to correspond to the reference voltage being used by the ADC here, i.e. 100% on ADC corresponds to 3.3v on the analog input pin. Although as I understood it the default vref is actually 3.6v . So readings will be wrong if you have the wrong value here.

510 and 1000 correspond (as noted in the comments in the earlier source code) to the voltage divider in the Xiao schematic (built-in), which lies between the battery output, the vbat pin, and ground. According to the schematic, thereā€™s 1 M Ohm (1000 K Ohm) to battery, and 510K Ohm to ground

Hi everyone! I have a question related to the wiring of a LiPo battery to the Xiao BLE. Must the battery be connected to the VIN/GND pads located underneath the Xiao BLE board? Or can it be connected to pin #13 (the so-called ā€œ5Vā€ pin) and pin #12 (GND pin)? I am asking because soldering a wire to these flat pads is a little tricky. I was able to do it, but itā€™s tricky. Whereas soldering a wire to a pin is a lot easier.

I have yet to receive my Xiao BLE, but I experimented a little on a Xiao SAMD21, and it looks like the voltage of the VIN pad and that of the ā€œ5Vā€ pin (#13) are identical. I connected my bench DC power supply to the VIN pad and gave it 3.7V or 5.5V, and pin #13 showed the same exact voltage.

Note: As long as I power the board with a voltage > 3.3V, pin #11 is always at 3.3V.

Thanks in advance!

It depends: do you want to use the onboard battery charger and MOSFET circuitry that switches off the battery when USB-C is plugged? use the battery pad.
If not, then the 5V pin works but you wonā€™t be taking full advantage of the battery capacity.

So Iā€™m looking at the schematic and I can read the notes, but Iā€™m needing a
Howard Cosell :nerd_face: or John Madden :cowboy_hat_face: Color Announcer/Tutor. Can anyone add to the two notes there regarding ā€œDisable temp sensorā€ and ā€œSet output sink onlyā€ TIA any caveats?

The ā€œdisable temp sensorā€ : the onboard battery charger IC uses a battery temperature sensing circuit. Normally itā€™s a 10K thermistor that is embedded in the lipo, but you can bypass this function by using a 10k resistor. Using a resistor you will not get any real battery monitoring from the charging IC, but it must have that 10K resistor for it to work. In this case, the 10K resistor is already on the XIAO board so you do not need to do anything. Every recently made lipo should have an internal safety circuit that measures lipo temperature shuts downs the lipo independently from the XIAO or anything that is connected to it. You can read more an this in the charging ICā€™s datasheet.

The ā€œoutput sinkā€ for the ā€œbattery readā€ means that you need to set p0.14 pin where the MCUā€™s internal port resistance (usually 10k-50k) will provide current sink for the voltage divider circuit measuring battery voltage:

#define BAT_READ 14 // P0_14 = 14 Reads battery voltage from divider on signal board. (PIN_VBAT is reading voltage divider on XIAO and is program pin 32 or P0.31)

pinMode(BAT_READ, OUTPUT); digitalWrite(BAT_READ, LOW); // This is pin P0_14 = 14 and by pulling low to GND it provides path to read on pin 32 (P0,31) PIN_VBAT the voltage from divider on XIAO board

1 Like

Excellent, the 10K is already there. NICE TY :wink: :+1:
basically enabling the divider. OK iā€™ll run with that :slight_smile:
Just needed that push.
GL :-p

I had trouble analogRead() battery voltage in ā€œmbed 2.7.2ā€ and after trial and error, the macro ā€œanalogPinToPinName(P)ā€ in ā€œpinDefinitions.h;22ā€ seems a bit strange.
I modified it as follows and was able to ā€œanalogRead()ā€ the battery voltage.
I am attaching a sketch for reference.

/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)
#define analogPinToPinName(P)       (P >= PINS_COUNT ? NC : P < A0 ? g_AAnalogPinDescription[P+A0].name : g_AAnalogPinDescription[P].name)
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);
}
3 Likes