So I've googled a lot and found a lot of people asking simular questions with no final project or answers. I did find this: Make The Future: Flat Mate - protect your LiPo cells from over-discharge
Which is great, but isnt Arduino. So I've been working on the code the last couple days, it compiles without errors, but doesnts work. Im new to coding so maybe I'm missing something obvious.
Ideas?
/*
Attiny85_batteryMonitor
Ideas borrowed from: https://github.com/unixbigot/Flat-Mate
modified for arduion tiny core by DWhacks
*@@ Voltage trigger levels.
*
* Battery voltage is read through a voltage divider and compared to the internal voltage reference.
*
* If
* Vin ----+
* R1
* +----- Vout (BATI)
* R2
* |
* =
* . (gnd)
*
* Then Vout = Vin * ( R2 / (R1 + R2) )
*
* ; Use this Emacs lisp function to calculate divisors
* (defun rn2div (rup rdown) (/ (float rdown) (+ rup rdown)))
*
*
* eg. R1=12k R2=1k => Vout = Vin * (1000 / (1000 + 12000))
* Vin * 0.0769
*
* R1=20k R2=10k => Vout = Vin * 0.3333 Ileak = 0.4mA @ 12v
* R1=2k2 R2=1k => Vout = Vin * 0.3125
* R1=3k3 R2=1k => Vout = Vin * 0.232
* R1=3k9 R2=1k => Vout = Vin * 0.204 Ileak = 2.4mA @ 12v
* R1=39k R2=10k => Vout = Vin * 0.204 Ileak = 0.24mA @ 12v
* R1=4k7 R2=1k => Vout = Vin * 0.175
* R1=10k R2=1k => Vout = Vin * 0.0909 Ileak = 1mA @ 12v
* R1=12k R2=1k => Vout = Vin * 0.0769 Ileak = 0.92mA @ 12v
*
* Fully charged LiPo is 4.23v/cell, discharged is 2.7v/cell (nominal voltage 3.7v/cell)
* For battery endurance, do not discharge below 3.0v/cell (aircraft users commonly use 2.9v/cell as limit)
*
* A 2-cell battery (nominally 7.46v) varies from 8.46v to 5.40v, with low-volt alert at 6.00v
* A 3-cell battery (nominally 11.1v) thus varies from 12.9v to 8.10v, with low-volt alert at 9.00v
* A 4-cell battery (nominally 14.8v) thus varies from 16.9v to 10.8v, with low-volt alert 12 12.0v
* NOTE: a 4-cell battery requires a different voltage divider than 2-and-3 cells (use 15:1 not 12:1)
*
*
*@@ Analog read values for defined voltage levels
*
* For a 3-cell battery, we consider 12v+ to be "full", 11v "good", 10v "low" and 9v "critical"
* (BMV_foo constants are these values in millivolts)
*
* In AVR-worldview, we use 12:1 voltage divider and read 10-bit ADC comparisons versus AREF (1.1v)
*
* So 12v becomes 1.00V when divided.
* Compared to 1.1v reference this gives an ADC result of 1024*(1.0/1.1) == 859
*
* An alternative approach is to use a smaller voltage divisor and compare
* against Vcc (5.0v), but in practice a 12:1 divisor is easier to achieve
* due to the standard first preference resistor value series.
*
* You can use these Emacs lisp defuns to calculate threshold analog values for your voltage levels
*
* (defun volts2int (v sf ref) (round (/ (* 1024.0 (* (float v) sf) ) (float ref))))
* (defun vlist2int (sf ref levels) (mapcar (lambda (v) (volts2int (float v) sf ref)) levels))
* eg. (volts2int 12 0.333 5.0) => 818
* (vlist2int (rn2div 10000 1000) 1.1 '(12 11 10 9)) => (1016 931 846 762)
* (vlist2int (rn2div 20000 10000) 5.0 '(12 11 10 9)) => (819 751 683 614)
* (vlist2int (rn2div 12000 1000) 1.1 '(12 11 10 9))=> (859 788 716 644)
*
* for 4-cell, use a 15:1 divider
* (vlist2int (rn2div 15000 1000) 1.1 '(16 14.5 13 12)) => (931 844 756 698)
*
* The above lines calculate the VL_* values shown below
/* Use a 12:1 voltage divider */
//#define INTERNAL (2)
#define CELL_COUNT 2 // DEFINE THE NUMBER OF CELLS 2,3,4
#if CELL_COUNT == 4
/* Use a 15:1 voltage divider */
#define BMV_FULL 16000
#define VL_FULL 931
#define BMV_GOOD 14500
#define VL_GOOD 844
#define BMV_LOW 13000
#define VL_LOW 756
#define BMV_CRIT 12000
#define VL_CRIT 698
#elif CELL_COUNT == 3
/* Use a 12:1 voltage divider */
#define BMV_FULL 12000
#define VL_FULL 859
#define BMV_GOOD 11000
#define VL_GOOD 788
#define BMV_LOW 10000
#define VL_LOW 716
#define BMV_CRIT 9000
#define VL_CRIT 644
#elif CELL_COUNT == 2
/* Use a 12:1 voltage divider */
#define BMV_FULL 8000
#define VL_FULL 573
#define BMV_GOOD 7300
#define VL_GOOD 523
#define BMV_LOW 6650
#define VL_LOW 476
#define BMV_CRIT 6000
#define VL_CRIT 430
#endif
const int batteryPin = 1; //V+ from battery connected to analog1 physical pin 7
const int switchPin = 0; //physical pin 5
const int led = 3; //physical pin 2
// Define the number of samples to keep track of. The higher the number,
// the more the readings will be smoothed, but the slower the output will
// respond to the input. Using a constant rather than a normal variable lets
// use this value to determine the size of the readings array.
const int numReadings = 4;
int readings[numReadings]; // the readings from the analog input
int index = 0; // the index of the current reading
int total = 0; // the running total
int average = 0; // the average
void setup()
{
analogReference(INTERNAL);
pinMode(batteryPin, INPUT);
pinMode(switchPin, OUTPUT);
pinMode(led, OUTPUT);
for (int thisReading = 0; thisReading < numReadings; thisReading++)
readings[thisReading] = 0; // initialize all the readings to 0
}
void loop()
{
averageVoltage(); //get average voltage from function
int sensorValue = average;
float voltage = sensorValue * (1.1 / 1023.0);
if (voltage > VL_CRIT){ //if battery is above critical, turn on transistor swtich
digitalWrite(switchPin, HIGH);
}
if (voltage >= VL_FULL){ //if the battery is full or higher
digitalWrite(led, HIGH);
}
else if (voltage >= VL_GOOD){
digitalWrite(led, HIGH);
}
else if (voltage >= VL_LOW){
/*Fade Up*/
for(byte i=1; i<100; i++) {
byte on = i;
byte off = 100-on;
for( byte a=0; a<100; a++ ) {
digitalWrite(led, HIGH);
delayMicroseconds(on);
digitalWrite(led, LOW);
delayMicroseconds(off);
}
}
/*Fade Down*/
for(byte i=1; i<100; i++) {
byte on = 100-i;
byte off = i;
for( byte a=0; a<100; a++ ) {
digitalWrite(led, HIGH);
delayMicroseconds(on);
digitalWrite(led, LOW);
delayMicroseconds(off);
}
}
}
}
void averageVoltage() {
// subtract the last reading:
total= total - readings[index];
// read from the sensor:
readings[index] = analogRead(batteryPin);
// add the reading to the total:
total= total + readings[index];
// advance to the next position in the array:
index = index + 1;
// if we're at the end of the array...
if (index >= numReadings)
// ...wrap around to the beginning:
index = 0;
// calculate the average:
average = total / numReadings;
delay(1); // delay in between reads for stability
}
//end