Great! it works now! that was a silly mistake, thank you for your help!
Now I have another question. The values I had for the voltage "readings" are way off. I dont know if its just like that but my calculated voltages are about 40 below what seams to work. I cant imagine my DMM being that much off.
As I understand it, the voltage after the divider, on the pin should fit into this equation to find the byte value:
1024*(VOLTAGE/1.1) = VALUE
But like I said It seams off.
Next question, I have used the smoothing example to smooth out my readings and I have made it its own functions. As I though, it should run the amount of numReadings before getting the average. How can I make it loop that function without running the rest of my loop?
Heres the updated code:
/*
Attiny85_batteryMonitor
Ideas borrowed from: https://github.com/unixbigot/Flat-Mate
modified for arduino 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 VL_FULL 613 //about 7.8v
#define VL_GOOD 583 //about 7.3v
#define VL_LOW 510 //about 6.3v
#define VL_CRIT 470
#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 = 3;
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 voltage = average;
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){
/*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);
}
}
}
else if (voltage >= VL_LOW){
/*Fade Up*/
for(byte i=1; i<50; i++) {
byte on = i;
byte off = 50-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<50; i++) {
byte on = 50-i;
byte off = i;
for( byte a=0; a<100; a++ ) {
digitalWrite(led, HIGH);
delayMicroseconds(on);
digitalWrite(led, LOW);
delayMicroseconds(off);
}
}
}
else if (voltage < VL_LOW){
digitalWrite(switchPin, LOW);
digitalWrite(led, HIGH);
delay(100);
digitalWrite(led, LOW);
delay(100);
}
}
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