1.2V battery capacity tester

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:

  1. 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.

  2. 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