Battery voltage indicator using ws2812b matrix

I built a large lithium-ion battery packs and I have been trying out different DIY battery voltage indicator circuits...

I just came up with a cool idea to use an addressable LED Matrix as the display for individual cell voltages.

I came across a project on Adafruit using a neopixel strip to display temperature readings. Which is very close to what I want to do but it's using digitalRead instead analogRead. Also the sketch is only reading one pin and controlling one neopixel strip. I always have an extremely hard time taking a sketch and making it work to read multiple inputs.

Can I just replace the digitalRead with analogRead simply without having to modify the whole code? And how would I go about reading multiple analog inputs? Also I would remove the push button function as well as the LCD readout.

I'll post the code below

I understand that most questions asked Arduino forums are answered with just a hint of an idea how to do something but I'm hoping he's somebody could really help me out since every time I try to make or modifying Arduino sketch I end up pulling my hair out and giving up. So if someone knows of an easy way to accomplish what I'm trying to do, or point me to a project that is really similar that I could just modify a few things that would be great.

Thank you

#include <LiquidCrystal.h>
#include <Adafruit_NeoPixel.h>

// Create a variable that will store the temperature value
int TMPin = 0;
const int button = 12;
int lastColor = -1;


#define aref_voltage 3.3
#define PIN 6


/*
Param 1 == number of pixels
Param 2 == Arduino pin attached to din
Param 3 == pixel type flags, add together as needed
  NE0_KHZ800 800 KHZ bitstream (avg neopix)
  NE0_GRB wired for GRB bitstream
*/
Adafruit_NeoPixel strip = Adafruit_NeoPixel(32, PIN, NEO_GRB + NEO_KHZ800); //call Neopixels, 32 pixels in all, on pin 6, RGB system and 800 KHZ
LiquidCrystal lcd(13, 11, 5, 4, 3, 2); //call LCD display

void setup() 
{
  lcd.begin(16,2); //initialize LCD screen 16 by 2  
  strip.begin(); //begin neo pixel strip
  strip.show(); //initialize strip
  Serial.begin(9600);// serial monitor access
  pinMode(button, INPUT); //button for celsius
  analogReference(EXTERNAL); //analog reference for use with TMP36
}

void loop() 
{
  double temperature;
  double temp;
  double tempF;


  temp = tempMeasure(temperature); //call tempMeasure function
  tempF = (temp * 9.0/5.0 + 32);  //take reading from tempMeasure and convert to faharenheit
  
  
  while(digitalRead(button) == false) //button is depressed readout is in Celsius
  {
    Serial.println(temp); //prints in serial monitor
    lcd.print(temp); //prints on LCD screen
    lcd.setCursor(0,1); //sets cursor
    delay(2000); //2 seconds between readings
    lcd.clear(); //clear LCD after 2 seconds   
}
 
 pixelCaseF(tempF); //call pixelCase function that controls lights
 Serial.println(tempF); //print in serial
 lcd.print(tempF); //print temp in F on LCD
 lcd.setCursor(0,1); //set cursor
 delay(2000); //take reading every 2 seconds
 lcd.clear(); //clear LCD
 
}//end loop


double tempMeasure(double temperature)
{
 // -----------------
// Read temperature
// -----------------

  int reading = analogRead(TMPin); //voltage reading
  double voltage = reading * aref_voltage; //take initial reading and multiply by 3.3 ref voltage for arduino
  
  voltage /= 1024.0; //divide reading by 1024 to map
   
  temperature = (voltage - 0.5) * 100; //converts 10mv per degree with 500 mV offset to (voltage - 500mV) * 100)
   
  return temperature; //return temperature to top level method

}//end tempMeasure

void pixelCaseF(double tempF)
/*
This method controls the neo-pixel for the "analog" readout on the thermometer. With every temperature group, the number of pixels lit changes along with the color
*/

{
 int i;
 strip.setBrightness(64);
 strip.show();
  
  if (tempF >= 90.05)//if above 90 degrees, strip is red and entire strip is lit
 {
   strip.clear();
   for(int i=0;i <= 32;i++)
   {
   strip.setPixelColor(i, strip.Color(255,0,0));
   }
 }
 else if (tempF < 90.2 && tempF >= 80.05) //if 90 > tempF >= 80 orange and strip is partially lit up to 29th pixel
 { 
   strip.clear();
   for(int i=0;i <= 28;i++)
  {
  strip.setPixelColor(i, strip.Color(255,128,0)); 
  }
 }
 else if (tempF < 80.02 && tempF >= 70.5)// if 80 > tempF >= 70 yellow-green and strip is lit up to 25th pixel
 {
   strip.clear();
   for(int i = 0; i <= 24; i++)
   {
    strip.setPixelColor(i,strip.Color(204,255,0)); 
   }
 }  
 else if (tempF < 70 && tempF >= 60.5)// if 70 > tempF >= 60 green and strip is lit up to 21st pixel
{
  strip.clear();
  for(int i = 0; i<= 20; i++)
  {
   strip.setPixelColor(i,strip.Color(0,255,0));
  }
}
 else if (tempF < 60.02 && tempF >= 50.5) //if 60 > tempF >= 50 blue and strip is lit up to 17th pixel
{
  strip.clear();
  for(int i = 0; i <= 16; i++)
  {
    strip.setPixelColor(i,strip.Color(0,0,255));
  }
} 
 else if (tempF < 50.02 && tempF >= 40.5) //if 50 > tempF >= 40 aqua and strip is lit to 13th pixel
 {
   strip.clear();
   for(int i = 0; i <= 12; i++)
  {
   strip.setPixelColor(i, strip.Color(0,255,255));
  }
 }
 else if (tempF < 40.02 && tempF >= 32.5) //if 40 > tempF >= 32 fuschia and strip is lit to 9th pixel
 {
   strip.clear();
   for(int i = 0; i <= 8; i++)
  {
   strip.setPixelColor(i, strip.Color(153, 51,255)); 
  }
 }
 else if (tempF < 32.5) //temp < freezing white and strip is lit to 5th pixel
 {
   strip.clear();
   for(i = 0;i <= 4; i++)
 { 
   strip.setPixelColor(i, strip.Color(255,255,255)); 
 }//end for
 }
 
strip.show(); //update color change

}//end pixelCase

I just came up with a cool idea to use an addressable LED Matrix as the display for individual cell voltages.

Cool plan, what is the visual effect that you envision ?

o if someone knows of an easy way to accomplish what I'm trying to do, or point me to a project that is really similar that I could just modify a few things that would be great.

In general i'd say the approach is a normal way of doing things, but you should consider rather than modifying, to extract the parts you want and understand how they work.

Also the sketch is only reading one pin and controlling one neopixel strip. I always have an extremely hard time taking a sketch and making it work to read multiple inputs.

How hard is it to read multiple inputs ? I suggest you start there, write a small program that reads 'your' inputs and prints out the results onto the Serial monitor, how hard can it be ?
That is 'step 1'
The next step would be to print the results onto the LCD. (step 2)
and then you visual effect to the ws281x.

Just modifying a sketch to suit your needs can be quick (and sometimes easy) solution, but condition is that you completely understand both the sketch as the modification you want to make. (ideally you should be the author of the original sketch, then you really understand) Otherwise it is better to start your own program, and step by step get to your. goal.

Deva_Rishi:
Cool plan, what is the visual effect that you envision ?
Write a small program that reads 'your' inputs and prints out the results onto the Serial monitor
That is 'step 1'
(step 2)
and then you visual effect to the ws281x.

Thanks @Deva_Rishi...

I can read an analog input and display it on the serial monitor without a problem. I've been messing with arduinos for quite a while. but at most I can use some example sketches or some simple code from a project they find and slightly modified them... but I have trouble doing so if I have to read more than one analog input. and I'll explain below why I gave up on my previous project I've been trying to get to work for months for the very same reason.

like I mentioned above I build large lithium ion batteries. Powerwalls, Solar Generators, Backup Power...

so as an example let's say I have 10 battery packs wired in series...

so I would like to do is use a wide led matrix and have every other column represent one of each of the 10 packs. and let's say if just the bottom LED in the column is lit the battery is at 2.8v volts and if all the LEDs are lit the battery is at 4.2v which is the range of a lithium iA2 18650 battery. and maybe use an LED Matrix which has 10 LEDs in each column. So divide that 1.4v difference By the 10 leds. So each of the 10 battery packs would be represented by one of the the columns on the matrix... doing so would give you a graphical indication if the battery packs are balanced and all at the same voltage...

with that being said I've been trying to accomplish this same type of idea with no luck using the blynk dashboard or Adafruit IO dashboard to just give me a graphical interface to see voltage of each battery pack. but like I mentioned in my original post I can read the voltage from 1 analog input and send it to the dashboard and it works fine I just cannot for the life of me figure out how to read more than just one analog input and send it to the dashboard. No matter what I do the sketch always fails to compile. I've even had help on a bunch of forums also.... I wish I knew somebody that I could have look at the code and just tell me what is wrong and how to fix it... it's not like I haven't spent months on it on my own trying to do it myself and just trying to take the easy way out. LOL it has to be something minor so here I am trying this project.

so as an example let's say I have 10 battery packs wired in series...

So what is the sample program that reads the voltages from those batteries and prints them out ? and how have you connected that to the Arduino ?
These are the questions that need to be answered first. If you can show me how you can print them in the Serial monitor, i can help you do the rest.

I can read the voltage from 1 analog input and send it to the dashboard and it works fine I just cannot for the life of me figure out how to read more than just one analog input and send it to the dashboard

Well here is my question, what kind of board do you have ? (only a Mega has more that 8 Analog inputs) And how do you measure the output voltage of a battery while it is connected to 2 others in series.