adafruit / Adafruit_BluefruitLE_nRF51

Arduino library for nRF51822-based Adafruit Bluefruit LE modules
197 stars 122 forks source link

Read from Lipo batt level always returns 0 #54

Open billyjoker opened 4 years ago

billyjoker commented 4 years ago

Hi, I have tried two ways in order to get a value read from the Lipo:

1) With the official docs, simply as follows:

#define VBATPIN A9
float measuredvbat = analogRead(VBATPIN);
measuredvbat *= 2; // we divided by 2, so multiply back
measuredvbat *= 3.3; // Multiply by 3.3V, our reference voltage
measuredvbat /= 1024; // convert to voltage
Serial.print("VBat: " ); Serial.println(measuredvbat);

I have read VBatt: 0

2) I've executed the code supplied with battery.ino and I've got an ERROR displayed with the Serial

What could be happening?

billyjoker commented 4 years ago

I self answer, the way to get the value read is just including the snippet code inside the loop of battery.ino code. So, my commented steps must both to work together.

I do not know why the code of battery.ino is incompleted, so the user must complete the jigsaw reading the official docs, - page 29 - and to have intuition to get it work properly.

#define VBATPIN A9

void loop(void)
{
  // Should get Battery value from LIPO and update
  Serial.print("Update battery level = ");
  Serial.println(value);

  battery.update(value);

  value--;
  if (value == 0) value = 100;

  float measuredvbat = analogRead(VBATPIN);
  measuredvbat *= 2; // we divided by 2, so multiply back
  measuredvbat *= 3.3; // Multiply by 3.3V, our reference voltage
  measuredvbat /= 1024; // convert to voltage
  Serial.print("VBat: " ); Serial.println(measuredvbat);

  delay(5000);
}

But it is needed a conversion to a percentage value, and a way to send the level to the device in other thread

isharrrry commented 4 years ago

What is the reference voltage range used for ADC sampling and the value range of sampling results when using AT+HWADC command

aidanwhelan commented 1 year ago

@billyjoker

If I understand correctly, the two steps you've combined are not meant to do the same thing, and while there may not be any Serial errors, they are not working together:

From battery.ino, the battery.update() method only reports what you provide to it; it will change what it reports when you call this method again and make that provided percentage value ready for BLE communication as a battery level. It is up to you to get the actual battery voltage some other way and compute the percentage that goes into battery.update(). In your example above, value is the variable that should be the calculated percentage of battery capacity, however it currently looks like it just decrements by 1 until it gets to 0, then loops back to 100.

Separately, the second half of your example (starting from float measuredvbat = analogRead(VBATPIN);) is where you actually sample the voltage of your battery. Note, this requires that you use a resistor divider to connect your BAT pin to an I/O pin (in this case, A9). While this measuredvbat variable is actually informed by the battery (unlike value in the code above), it is not a percentage of the battery capacity, just a voltage. To get a percentage, you will need to estimate using the approximate discharge curve for your battery. For the purposes of calculating battery percentage, it would be amazing if the discharge was linear, however in reality, LiPoly batteries are 'maxed out' at 4.2V and stick around 3.7V for much of the battery life, then slowly sink down to 3.2V or so before the protection circuitry cuts it off.