I am designing a control module for RC aircraft and I have to monitor battery voltage in addition to other tasks.
I have truncated the code which is too long to post here. I have a function called "checkvolt()" which performs two succesive analogRead() and calculates the battery voltage. Then I print the result on an OLED display.
First let's have a look at the code:
As you can see, this is a test code but the voltage check is similar to the main code.
There are two voltage checks. One at the beginning, in the function "selftest()" and second in the "loop()".
They all use the function "checkvolt()" to check and calculate the voltage.
The variables (int)volt and (float)voltage are globally defined.
The battery is a 2S LiPo (nominal voltage 7.40 V).
In the circuit, there is a voltage divider from the battery to the "batterytestpin" of the Atmega328. It consists of a 100k and a 10k resistor. That means the battery voltage is being divided by a factor of 11.
For the voltage measurement I am using the internal 1.1V of the Atmega328.
I havea 100nF capacitor connected between the Aref pin and ground.
The problem:
* When I read the voltage from the function selftest() I get a result of 3.20 V.
* When I read the voltage from the loop() I get a result of 8.10V (The LiPo is almost fully charged) and this is the correct reading.
* Both functions call "checkvolt()" for the voltage measurement!
I cannot find any explanation for this behaviour.
Any ideas and suggestions are welcome...
I have truncated the code which is too long to post here. I have a function called "checkvolt()" which performs two succesive analogRead() and calculates the battery voltage. Then I print the result on an OLED display.
First let's have a look at the code:
Code:
#include "SSD1306Ascii.h"
#include "SSD1306AsciiWire.h"
#define I2C_ADDRESS 0x3C
#define RST_PIN -1
#define batteryTestpin 14
SSD1306AsciiWire oled;
int volt;
float voltage;
void setup ()
{
Wire.begin();
Wire.setClock(400000L);
analogReference(INTERNAL);
oled.begin(&Adafruit128x64, I2C_ADDRESS);
oled.setFont(Callibri15);
oled.setLetterSpacing(2);
oled.clear();
selftest();
}
void loop()
{
for(int n = 0; n < 8; n = n + 2) // Continuously read and print the voltage values
{
checkvolt();
oled.setCursor(0, n);
oled.print(" ");
oled.setCursor(0, n);
oled.print(volt);
oled.setCursor(64, n);
oled.print(voltage);
}
}
void selftest()
{
oled.clear();
oled.println("Testing...");
checkvolt();
oled.print("Battery: ");
oled.println(voltage);
delay(3000);
oled.clear();
}
void checkvolt()
{
volt = analogRead(batteryTestpin);
volt = analogRead(batteryTestpin); // Two reads for better analogRead function
voltage = volt * 11.8 / 1000.0; // voltage in Volts
}
There are two voltage checks. One at the beginning, in the function "selftest()" and second in the "loop()".
They all use the function "checkvolt()" to check and calculate the voltage.
The variables (int)volt and (float)voltage are globally defined.
The battery is a 2S LiPo (nominal voltage 7.40 V).
In the circuit, there is a voltage divider from the battery to the "batterytestpin" of the Atmega328. It consists of a 100k and a 10k resistor. That means the battery voltage is being divided by a factor of 11.
For the voltage measurement I am using the internal 1.1V of the Atmega328.
I havea 100nF capacitor connected between the Aref pin and ground.
The problem:
* When I read the voltage from the function selftest() I get a result of 3.20 V.
* When I read the voltage from the loop() I get a result of 8.10V (The LiPo is almost fully charged) and this is the correct reading.
* Both functions call "checkvolt()" for the voltage measurement!
I cannot find any explanation for this behaviour.
Any ideas and suggestions are welcome...