I need some more help here. After finishing the code and circuit best I could, my discharge rate isn't working properly and I can't work out why. A couple of issues:
-
Can someone please tell me where I should be measuring the discharge current on the schematic below. I'm getting different readings depending where I measure.
-
I'm not sure if there is something wrong with my circuit, coding or calculations. For example, what I anticipate should be a 100mA discharge rate, is discharging at a much lower rate.
I've taken a stack of voltage measurements at different key points on the circuit (see chart below), and at different discharge currents - in case someone can work out what's wrong. I'll also attach the latest schematic I've drawn (hopefully correct this time!) as well as my code.
Fault finding.pdf (35.6 KB)
Capacity_Tester - Schematic.pdf (70.3 KB)
*///******************************************************************************
#include<JC_Button.h>
void measureBattery();
void up_button_check();
void down_button_check();
void start_button_check();
void timerInterrupt();
void timer();
void display1();
float Vref = 1.072; // internal reference calculation factor
const float LowBatteryLevel = 0.80; // Threshold for stopping discharge of NiMh AA battery
const byte PWM_Pin = 10; // Used to to pulse the discharge to achived the 200mA discharge
const byte Buzzer = 9; // Used for various alerts
int CurrentValues[] { 100, 200, 300, 400, 500, 600, 700, 800, 900, 1000}; //my selected mA values
int arrayNum = -1; // Not sure why - this makes the if statement work
float Current = 0; // Set to 0mA at start of program
float PWM = 0; // Calculated PWM to suit selected discharge rate
float Capacity; // Final battery capacity value
bool calc = false, Done = false, Report_Info = true;
Button UP_Button(2, 25, false, true);
Button Down_Button(3, 25, false, true);
int batteryAnalogValue; // used to calculate the voltage of the battery
const byte Battery = A0; // AA battery +ve connected to this pin
float batteryVoltage; // used to monitor AA battery voltage
unsigned long startTime = 0; // Sets when discharge commences
unsigned long endTime = 0; // Sets throughout discharge as well as end
unsigned long totalTime = 0; // used to display the discharge duration time
unsigned long allSeconds; // used in displaying time
int runHours; // used to display discharge "hours"
int secsRemaining; // used to calculate minutes and seconds
int runMinutes; // used to display discharge "minutes"
int runSeconds; // used to display discharge "seconds"
//------------------------------------------------------------------------
void setup ()
{
Serial.begin(9600);
analogReference (INTERNAL); // set Arduino's internal voltage as reference
analogRead (A1); // force voltage reference to be turned on
analogRead (A1); // second reading just to stabalise reading???
pinMode(PWM_Pin, OUTPUT);
pinMode(Buzzer, OUTPUT); // piezzo buzzer
analogWrite(PWM_Pin, PWM);
UP_Button.begin();
Down_Button.begin();
} // end void setup
//------------------------------------------------------------------------
void loop () {
measureBattery();
UP_Button.read();
Down_Button.read();
up_button_check();
down_button_check();
start_button_check();
} // end void loop
//------------------------------------------------------------------------
void measureBattery() {
// measure AA battery voltage - read 20 times then average to smoothen result
for (int i = 0; i < 19; i++) {
batteryAnalogValue = batteryAnalogValue + analogRead(Battery);
} // end for loops
batteryAnalogValue = batteryAnalogValue / 20;
batteryVoltage = ((batteryAnalogValue * Vref / 1024) * (10 + 22) / 22);
} // end void measureBattery
//------------------------------------------------------------------------
void up_button_check() {
// conditions below to allow toggling up through the current value in array
if (UP_Button.wasReleased() && calc == false && arrayNum < 9)
{
Serial.println("Up button released");
arrayNum++;
Current = CurrentValues[arrayNum]; // User to select discharge current
// Given Resistance = 1 ohm, V=IR is V=I
// Current value to be converted to Amps from mA (divide by 1000)
// PWM goes thru a 100k,47k voltage divider (mine actual 98.9,46.8)
// so drops to 46.8/(98.9+46.8) = 0.32 of actual voltage,
// so multiply by 1/0.32.
PWM = ((Current / 1000) * 255) / 3.312 * ((98.9 + 46.8) / 46.8);
Serial.print("arrayNum = ");
Serial.println(arrayNum);
Serial.print("Current Value = ");
Serial.print(Current, 0);
Serial.println("mA");
Serial.print("PWM value = ");
Serial.println(PWM, 0);
} // end if statement
} // end void up_button check
//------------------------------------------------------------------------
void down_button_check () {
// conditions below to allow toggling down through the current value in array
if (Down_Button.wasReleased() && calc == false && arrayNum > 0)
{
Serial.println("Down button pressed");
arrayNum--;
Current = CurrentValues[arrayNum]; // User to select discharge current
PWM = ((Current / 1000) * 255) / 3.312 * ((98.9 + 46.8) / 46.8);
Serial.print("arrayNum = ");
Serial.println(arrayNum);
Serial.print("Current Value = ");
Serial.print(Current, 0);
Serial.println("mA");
Serial.print("PWM value = ");
Serial.println(PWM, 0);
} // end if statement
} // end void down_button check
//------------------------------------------------------------------------
void start_button_check () {
// conditions below to allow discharge commencement
if (UP_Button.pressedFor (1000) && calc == false)
{
startTime = millis();
analogWrite(PWM_Pin, PWM);
// Give a beep to say discharge has commenced
digitalWrite(Buzzer, HIGH);
delay(100);
digitalWrite(Buzzer, LOW);
timerInterrupt();
} // end if statement
} // end void start_button_check
//------------------------------------------------------------------------
void timerInterrupt() {
calc = true;
while (Done == false) {
measureBattery();
timer();
display1();
// once the below condition is met, discharging stops and printout occurs
if (batteryVoltage < LowBatteryLevel) {
endTime = millis();
timer();
Serial.println();
Serial.println("______________________");
Serial.println("Battery discharged to 0.8V");
Serial.print("Total Discharge Time = ");
Serial.print(runHours);
Serial.print(":");
Serial.print(runMinutes);
Serial.print(":");
Serial.println(runSeconds);
Serial.print("Discharge Current = ");
Serial.print(Current, 0);
Serial.println("mA");
Serial.print("Total capacity = ");
Serial.print(Capacity, 0);
Serial.println("mAh");
Serial.println("______________________");
Done = true;
for (int i = 0; i < 5; i++) {
digitalWrite(Buzzer, HIGH);
delay(500);
digitalWrite(Buzzer, LOW);
delay(500);
} // end for loop
} // end if statement
} // end while statement
} // end void timerInterrupt
void timer() {
endTime = millis();
Capacity = (float (totalTime) / 3600) * Current;
totalTime = (endTime - startTime) / 1000;
allSeconds = totalTime;
runHours = allSeconds / 3600;
secsRemaining = allSeconds % 3600;
runMinutes = secsRemaining / 60;
runSeconds = secsRemaining % 60;
// For testing purposes only...
// Serial.print("Battery Voltage = ");
// Serial.print(batteryVoltage, 3);
// Serial.print(" V, ");
// Serial.print("Current = ");
// Serial.print(Current, 0);
// Serial.print("mA, ");
// Serial.print("Discharge Time = ");
// Serial.print(runHours);
// Serial.print(":");
// Serial.print(runMinutes);
// Serial.print(":");
// Serial.print(runSeconds);
// Serial.print(" Capacity = ");
// Serial.println(Capacity, 1);
// delay(1000);
} // end void timer
void display1() {
// For testing purposes only...
Serial.print("Battery Analog = ");
Serial.print(batteryAnalogValue);
Serial.print(" Battery voltage = ");
Serial.println(batteryVoltage, 3);
} // end void display