Displaying battery power using neopixels


I'm new to the world of Arduino and this is my first ever post!

I have been struggling with a project and wondered if anyone might be able to help?

I'm using a Adafruit Feather 32u4 Bluefruit LE and want to be able to calculate the remaining battery level of the connected LiPo and then display that using some neopixel LED's. The more power the battery has left, the more LED's that are lit up. For example when there is 50% battery, half of the LED's in the strip are lit up.

I have made an attempt:

#include <Adafruit_NeoPixel.h>
#define PIN 6
// Parameter 1 = number of pixels in strip
// Parameter 2 = pin number (most are valid)
// Parameter 3 = pixel type flags, add together as needed:
//   NEO_KHZ800  800 KHz bitstream (most NeoPixel products w/WS2812 LEDs)
//   NEO_KHZ400  400 KHz (classic 'v1' (not v2) FLORA pixels, WS2811 drivers)
//   NEO_GRB     Pixels are wired for GRB bitstream (most NeoPixel products)
//   NEO_RGB     Pixels are wired for RGB bitstream (v1 FLORA pixels, not v2)
Adafruit_NeoPixel strip = Adafruit_NeoPixel(25, PIN, NEO_GRB + NEO_KHZ800);
#define VBATPIN 9 //Battery level pin

// this constant won't change:
const int  buttonPin = 5;    // the pin that the pushbutton is attached to

// Variables will change:
int buttonState = 0;         // current state of the button
int lastButtonState = 0;     // previous state of the button

void setup() {
  // initialize the button pin as a input:
  pinMode(buttonPin, INPUT);
  strip.setBrightness(255); //adjust brightness here
  strip.show(); // Initialize all pixels to 'off'
void loop() {

  //Print battery voltage to serial
  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);
  // read the pushbutton input pin:
  buttonState = digitalRead(buttonPin);
  if (buttonState == HIGH) {
  // Fill along the length of the strip
    colorWipe(strip.Color(  0,   0, 255), 20); // Blue
  colorWipe(strip.Color(  0,   0, 255), 0);
  colorWipe(strip.Color(  0,   0, 0), 0);
  colorWipe(strip.Color(  0,   0, 255), 0);
  colorWipe(strip.Color(  0,   0, 0), 0);
  colorWipe(strip.Color(  0,   0, 255), 0);
  colorWipe(strip.Color(  0,   0, 0), 0);
  colorWipe(strip.Color(  0,   0, 255), 0);
  colorWipe(strip.Color(  0,   0, 0), 10); // Blank?
// Fill the dots one after the other with a color
void colorWipe(uint32_t c, uint8_t wait) {
  for(uint16_t i=0; i<strip.numPixels(); i++) {
      strip.setPixelColor(i, c);

As you can see, I have it so when a connected push button is pressed, a cool wipe function lights up the LED's in the strip. I'm also able to read the battery's voltage and display it in the serial monitor.

If anyone would be able to provide some guidance on how I can limit the number of pixels that are lit in the strip depending on the voltage of the battery I would really appreciate it!

Many thanks,


Better be a big battery if you are going to use NeoPixels as charge indicators. :grinning:

It's an 8800mAh Lithium Ion battery pack and I only want the power to be displayed upon the press of a button, not have the LED's on all the time...

How much load is on that battery, i.e. what is it running apart from the Arduino? Unfortunately the voltage of a Lipo when it's under load is a very poor indication of how much charge is left in it. Only the unloaded voltage after resting for a few minutes gives you a fairly reasonable idea (and that's a long way from accurate).

Are you seeing good voltage measurements from your program now? What voltages do you regard as 100%, 50% and 0%?


Hey @slipstick thanks for replying.

The battery is just running the Feather itself (i'm planning on using it as kind of a bluetooth LE beacon) and the 25 neopixels as status indicators (they will only be on for very brief periods to indicate battery level or some basic bluetooth status)

I'm getting some good readings from the serial monitor (currently reading 3.82v) and the documentation that is associated with the battery states

The output ranges from 4.2V when completely charged to 3.7V... The included protection circuitry keeps the battery voltage from going too high (over-charging) or low (over-use) which means that the battery will cut-out when completely dead at 3.0V

I am new to all this so forgive me for not fully understanding but I would assume that 100% would be 4.2v and 0% would be 3.0v

The LED battery level indicator doesn't have to be massively accurate, it just needs to provide a rough indication as to where the battery is up to.