Hi,
It is my first time using AdaFruit NeoPixels. My project aims to read Li-Ion battery voltage and show its charging state as in the laptop's or mobile phone's battery gauges. It will calculate the percentage and show it on the NeoPixel ring with colors and animations.
Let me explain it with an image:
I have divided the circle into 4 areas. These 4 areas represent the percentage of the battery as the first and red colored area shows it's between %0-%25 and the second area which orange colored shows it's between %25-%50 and so on and so forth. While the battery is charging, my setup reads the voltage, decides on which area should be active, and show an animation to indicate charging and state. The animation is just turning on the LEDs sequentially.
The problem is I have decided on the speed of the animation and if I just run the animation code, there is no problem with the animation speed but whenever I run the whole code which I put below, I cannot control the animation speed, it's working so slowly and independent from the delay I put there to control the speed.
Here is my code:
//CHARGE INDICATE
//Ahmet Faruk Koc
#include <Adafruit_NeoPixel.h>
unsigned long startTime;
int neoPixelPin = 6;
int numPixels = 24;
int startPixel = 0;
int delayTime = 10; // speed of the animation
int chargeState = 1;
const int sensorPin = A0;
Adafruit_NeoPixel strip = Adafruit_NeoPixel(numPixels, neoPixelPin, NEO_GRB + NEO_KHZ800);
// from voltage divider equation
float voltageFactor = 1;
// set initial data point as 1
long measurementNumber = 1;
void setup() {
Serial.begin(9600);
strip.begin();
strip.clear();
startTime = millis();
strip.setBrightness(255);
}
void loop() {
int count = 0;
float periodVoltageSum = 0;
while (count < 10000) {
int rawVoltRead = analogRead(sensorPin);
float voltage = (rawVoltRead / 1024.0) * 5.09 * voltageFactor;
periodVoltageSum += voltage;
count++;
}
float voltageAve = periodVoltageSum / count;
// prints the output to Serial in a CSV format
Serial.print(measurementNumber);
Serial.print(',');
Serial.println(voltageAve, 3);
measurementNumber++;
if (chargeState == 0) {
if (voltageAve > 3.9) {
bolge4();
strip.clear();
} else if (voltageAve > 3.4 && voltageAve < 3.9) {
bolge3();
strip.clear();
} else if (voltageAve > 2.9 && voltageAve < 3.4) {
bolge2();
strip.clear();
} else if (voltageAve < 2.9) {
bolge1();
strip.clear();
}
} else if (chargeState == 1) {
if (startTime + delayTime < millis()) {
if (voltageAve < 2.9) cbolge1();
else if (voltageAve > 2.9 && voltageAve < 3.4) {
strip.setPixelColor(0, 255, 0, 0);
strip.setPixelColor(1, 255, 0, 0);
strip.setPixelColor(2, 255, 0, 0);
strip.setPixelColor(3, 255, 0, 0);
strip.setPixelColor(4, 255, 0, 0);
strip.setPixelColor(5, 255, 0, 0);
cbolge2();
} else if (voltageAve > 3.4 && voltageAve < 3.9) {
uint32_t magenta = strip.ColorHSV(1331, 255, 255);
strip.setPixelColor(0, 255, 0, 0);
strip.setPixelColor(1, 255, 0, 0);
strip.setPixelColor(2, 255, 0, 0);
strip.setPixelColor(3, 255, 0, 0);
strip.setPixelColor(4, 255, 0, 0);
strip.setPixelColor(5, 255, 0, 0);
strip.setPixelColor(6, magenta);
strip.setPixelColor(7, magenta);
strip.setPixelColor(8, magenta);
strip.setPixelColor(9, magenta);
strip.setPixelColor(10, magenta);
strip.setPixelColor(11, magenta);
cbolge3();
} else if (voltageAve > 3.9) {
uint32_t magenta = strip.ColorHSV(1331, 255, 255);
uint32_t sari = strip.ColorHSV(5000, 255, 255);
strip.setPixelColor(0, 255, 0, 0);
strip.setPixelColor(1, 255, 0, 0);
strip.setPixelColor(2, 255, 0, 0);
strip.setPixelColor(3, 255, 0, 0);
strip.setPixelColor(4, 255, 0, 0);
strip.setPixelColor(5, 255, 0, 0);
strip.setPixelColor(6, magenta);
strip.setPixelColor(7, magenta);
strip.setPixelColor(8, magenta);
strip.setPixelColor(9, magenta);
strip.setPixelColor(10, magenta);
strip.setPixelColor(11, magenta);
strip.setPixelColor(12, sari);
strip.setPixelColor(13, sari);
strip.setPixelColor(14, sari);
strip.setPixelColor(15, sari);
strip.setPixelColor(16, sari);
strip.setPixelColor(17, sari);
cbolge4();
}
startTime = millis();
}
}
}
void bolge1() {
strip.setPixelColor(0, 255, 0, 0);
strip.setPixelColor(1, 255, 0, 0);
strip.setPixelColor(2, 255, 0, 0);
strip.setPixelColor(3, 255, 0, 0);
strip.setPixelColor(4, 255, 0, 0);
strip.setPixelColor(5, 255, 0, 0);
strip.show();
}
void bolge2() {
uint32_t magenta = strip.ColorHSV(1331, 255, 255);
strip.setPixelColor(6, magenta);
strip.setPixelColor(7, magenta);
strip.setPixelColor(8, magenta);
strip.setPixelColor(9, magenta);
strip.setPixelColor(10, magenta);
strip.setPixelColor(11, magenta);
strip.show();
}
void bolge3() {
uint32_t sari = strip.ColorHSV(5000, 255, 255);
strip.setPixelColor(12, sari);
strip.setPixelColor(13, sari);
strip.setPixelColor(14, sari);
strip.setPixelColor(15, sari);
strip.setPixelColor(16, sari);
strip.setPixelColor(17, sari);
strip.show();
}
void bolge4() {
strip.setPixelColor(18, 0, 150, 0);
strip.setPixelColor(19, 0, 150, 0);
strip.setPixelColor(20, 0, 150, 0);
strip.setPixelColor(21, 0, 150, 0);
strip.setPixelColor(22, 0, 150, 0);
strip.setPixelColor(23, 0, 150, 0);
strip.show();
}
void cbolge1() {
for (int i = 0; i < numPixels; i++) {
if (i == startPixel) {
for (int i = 0; i < 6; i++) {
strip.setPixelColor(i, 255, 0, 0);
}
} else {
strip.setPixelColor(i - 1, 0, 0, 0);
}
}
strip.show();
startPixel++;
if (startPixel == 24)
startPixel = 0;
}
void cbolge2() {
uint32_t magenta = strip.ColorHSV(1331, 255, 255);
for (int i = 1; i < numPixels; i++) {
if (i == startPixel) {
for (int i = 6; i < 12; i++) {
strip.setPixelColor(i, magenta);
}
} else {
strip.setPixelColor(i + 5, 0, 0, 0);
}
}
strip.show();
startPixel++;
if (startPixel == 24)
startPixel = 0;
}
void cbolge3() {
uint32_t sari = strip.ColorHSV(5000, 255, 255);
for (int i = 1; i < numPixels; i++) {
if (i == startPixel) {
for (int i = 12; i < 18; i++) {
strip.setPixelColor(i, sari);
}
} else {
strip.setPixelColor(i + 11, 0, 0, 0);
}
}
strip.show();
startPixel++;
if (startPixel == 24)
startPixel = 0;
}
void cbolge4() {
for (int i = 1; i < numPixels; i++) {
if (i == startPixel) {
for (int i = 18; i < 24; i++) {
strip.setPixelColor(i, 0, 150, 0);
}
} else {
strip.setPixelColor(i + 17, 0, 0, 0);
}
}
strip.show();
startPixel++;
if (startPixel == 24)
startPixel = 0;
}
Voltage Measurement Part
As I asked further and want to hear your Ideas about precise voltage reading methods, I will share a hand-drawn schematic of my setup here.
Right now for the prototype, I am using Arduino Uno. The nominal voltage of my Li-Ion battery is 3.7 volts and 1500mAh.
Because I need to indicate the charging state with LEDs, I cannot use the standard reference voltage of the Arduino because I want to avoid a change in the reference voltage due to LEDs and the charger. So that's why I have used an external reference voltage circuit here. In the voltage reading part, I have not used a voltage sensor yet because I am still looking for a precise and good one.