Monitor Power Supply Under Load

Hello Guys,

I have a small power supply which I monitor through a divider network. When there is no load the ADC reads perfectly still. When I switch on the load to the power supply under test the ADC goes up and down but my DVM shows the power supply voltage holding steady albeit slightly lower than before load was attached.

I have tried powering via USB/external power same problem. The input voltage is to the divider network is 7.35V and the load is a 3.3ohm 10W. The divider network is a 33K and 10K 9(calculated ratio is 4.408163265306122).

Input voltage to A2 is 1.678v(ADC 343) without load and with load it is steady at 1.571v(at this point the ADC reads anywhere from 300-343 yet input voltage is steady).

I have tried using different divider network like 100K and 10K, 1M and 100K. I have tried switching the load without a relay.

I used external REF at rock solid 4.98v. I ground everything.

The load is switch via a relay connected to a FET and to digital pin 12.

Any help/suggestions would be appreciated as I don't know what else to do.

For voltage measurements it’s better to use Arduino’s inbuild ~1.1volt bandgap reference.
Drop the voltage to measure to <=1volt with the divider, and use analogReference(INTERNAL); in void setup().
There is always noise. Averaging gives a more stable readout.
Make sure load ground current does not run over Arduino pins (star grounding).
Try this. Designed for a <=16volt car battery, but ok for the ~7.35volt you mentioned.
Read the comments about calibrating.
Leo…

/*
  0 - ~16volt voltmeter for 3.3volt and 5volt Arduinos
  uses the stable internal 1.1volt reference
  6k8 resistor from A0 to ground, and 100k resistor from A0 to +batt
  100n capacitor from A0 to ground for stable readings
  (100k + 6k8) / 6k8 = 15.70588 | used in formula
*/
float Aref = 1.075; // ***calibrate here*** | change this to the actual Aref voltage of ---YOUR--- Arduino
unsigned int total; // can hold max 64 readings
float voltage; // converted to volt

void setup() {
  analogReference(INTERNAL); // use the internal ~1.1volt reference  | change (INTERNAL) to (INTERNAL1V1) for a Mega
  Serial.begin(9600); // set serial monitor to this value
}

void loop() {
  for (int x = 0; x < 64; x++) { // multiple analogue readings for averaging
    total = total + analogRead(A0); // add each value to a total
  }
  voltage = (total / 64) * 15.70588 * Aref / 1024 ; // convert readings to volt
  // print to serial monitor
  if (total == (1023 * 64)) { // if overflow
    Serial.print("voltage too high");
  }
  else {
    Serial.print("The battery is ");
    Serial.print(voltage);
    Serial.println(" volt");
  }
  total = 0; // reset value
  delay(1000); // one second between measurements
}

Thanks ... I am going to try that.

Thanks…managed to get it right. here is final code :

#include <PCD8544.h>
#include <DHT.h>

#define DHTPIN 2        //temp humidity sensor pin
#define DHTTYPE DHT22   //what type of sensor it is
#define switchState 9   // my switch under toggle
#define testBedPower 8 // to apply power to test bed
#define loadSwitch 12    // pin for switching on relay for load
#define failLed 13 
#define passLed 11

DHT dht(DHTPIN,DHTTYPE);

float Aref_Ratio = 4.408;

//for humidity and temp sensor
float temperature = 0;
float humidity = 0;

//voltage related 
float dividerVoltage = 0;
float calculatedVoltage = 0;
float initialVoltage,loadVoltage;
float average = 0;

//general purpose
int buttonState = 0;
int x,count = 0;


boolean listenToButton =true;

unsigned char const halo_small_bmp[196] = {
  0,   0, 252, 252, 252, 252,   0, 128, 128, 128, 128, 128,128,   0,   0,   0,   0,   0,   0,   0,   0, 128, 128, 128,128, 128, 128, 128,   0,   0,   0,   0,   0, 252, 252, 252,252,   
  0,   0,   0,   0,   0,   0, 128, 128, 128, 128, 128, 128, 128, 128,   0,   0,   0,   0,   0,  0,   0, 255, 255, 255, 255,  15,   7,   3,   3,   7,   7,255, 255, 254, 252, 
  0,   0, 128, 195, 239, 231, 227, 227,227, 227, 231, 255, 255, 254, 252,   0,   0, 255, 255, 255, 255,   0,   0, 248,254, 255, 255,  15,   7,   3,   3,   3,  7,   7, 159, 
  255, 254, 252, 224,   0,  0,   0,  63,  63,  63,  63,   0,   0,  0,   0,   0,   0, 63,  63,  63,  63,   0,   0,  15,  31,  63,  63,  60,  56, 56,  60,  30,  63,  63,  63,  
  63,   0,   0,63,  63,  63,  63,   0,   0,   3,   7,  15,  31,  62,  60,  60,  56,  56, 60,  62,  31,  31,  15,   3,   0,   0};

static PCD8544 lcd;

void setup() {
  lcd.begin(84, 48); // lcd resolution
  pinMode(switchState,INPUT); //start button
  pinMode(testBedPower,OUTPUT);
  pinMode(loadSwitch,OUTPUT);
  pinMode(failLed,OUTPUT);
  pinMode(passLed,OUTPUT);
  pinMode(A2,INPUT);
  pinMode(A3,INPUT);
  Serial.begin(9600);
}

void loop() {
    digitalWrite(passLed,LOW);
    environment_display();
    
    buttonState = digitalRead(switchState);
   //jig toggle not down
    while (buttonState == LOW && temperature < 35 && listenToButton) { // more than 35 load resistor is too hot
         buttonState = digitalRead(switchState);
          lcd.setCursor(10,1);
          lcd.drawBitmap(halo_small_bmp,56,3);
         lcd.setCursor(0,4);  lcd.print("Insert PCB for");
         lcd.setCursor(0,5);  lcd.print("   TESTING    ");
     }

    listenToButton = false;
    
     while(temperature > 35){
      lcd.clear();
      lcd.setCursor(0,3);lcd.print("Jig too HOT!");
      }
     
     lcd.clear();
     
     while (buttonState = HIGH){
         digitalWrite(testBedPower,HIGH); 
         buttonState = digitalRead(switchState);
         environment_display();
         
         //starting the power supply
         getVoltage();
         initialVoltage = ((average/200 * 4.98)/1024); // actual voltage at divider network
                        
         lcd.setCursor(0,2);lcd.print("ADC  :" );lcd.print(dividerVoltage); //actually the raw ADC
         initialVoltage = ((average/200 * 4.98)/1024); // actual voltage at divider network
         lcd.setCursor(0,3);lcd.print("Act  :");lcd.print(initialVoltage);
          initialVoltage = initialVoltage * Aref_Ratio;
         lcd.setCursor(0,4);lcd.print("Volt :");lcd.print(initialVoltage);
         delay(3000);
         
         // check if power supply starts with correct voltage level
         if (initialVoltage < 7.29) {
            lcd.clear();
            lcd.setCursor(0,0);lcd.print("POWER SUPPLY");
            lcd.setCursor(0,1);lcd.print("FAILED INITIAL");
            lcd.setCursor(0,2);lcd.print("STARTUP TEST");
            lcd.setCursor(0,4);lcd.print("Volt  : ");lcd.print(initialVoltage);
            lcd.setCursor(0,5);lcd.print("ADC   : ");lcd.print(dividerVoltage);
            digitalWrite(failLed,HIGH);
            delay(3000);
            asm volatile ("  jmp 0"); 
         }  else {
            digitalWrite(passLed,HIGH);
            delay(20);
            digitalWrite(passLed,LOW);
          
          }  
          
           //load test working correctly  
           lcd.clear();     
           digitalWrite(loadSwitch,HIGH); //apply load
           
           environment_display();
           
           lcd.setCursor(10,1);
           lcd.drawBitmap(halo_small_bmp,56,3);
           lcd.setCursor(0,4);lcd.print(" OUTPUT TEST      PASSED" );
           delay(2000);
           lcd.setCursor(0,4);lcd.print("  LOAD TEST      RUNNING  " );
           delay(3000);
           lcd.clear();
           
           environment_display();
           
            getVoltage();
            
           lcd.setCursor(0,2);lcd.print("ADC  :" );lcd.print(dividerVoltage); //actually the raw ADC
           calculatedVoltage = ((average/200 * 4.98)/1024); // actual voltage at divider network
           if (calculatedVoltage >= 6.70) digitalWrite(passLed,HIGH);
           loadVoltage = calculatedVoltage; 
           lcd.setCursor(0,3);lcd.print("Act  :");lcd.print(loadVoltage);
            loadVoltage = calculatedVoltage * Aref_Ratio; 
           lcd.setCursor(0,4);lcd.print("Calc :");lcd.print(loadVoltage);
           
           digitalWrite(loadSwitch,LOW);
           delay(3000);

            while (loadVoltage < 6.65 && buttonState == HIGH){
                buttonState = digitalRead(switchState);
                lcd.clear();     
                environment_display();
           
                lcd.setCursor(10,1);
                lcd.drawBitmap(halo_small_bmp,56,3);
                lcd.setCursor(0,4);lcd.print(" OUTPUT TEST      FAILED" );
                digitalWrite(failLed,HIGH); 
                delay(2000);
                loadVoltage = 7;
           }

           //digitalWrite(passLed,HIGH);
        
      }//while loop for button power supply under test still in jig
      
      asm volatile ("  jmp 0"); //reset if button is opened during test
      
}//main loop

void environment_display(){
    humidity = dht.readHumidity();
    temperature = dht.readTemperature(); 
    lcd.setCursor(0, 0);
    lcd.print("T:");lcd.print(temperature,0);lcd.print("C  ");
    lcd.print("H:");lcd.print(humidity,0);lcd.print("%");
  }

 void getVoltage(){
          average = 0;
         for (count=0;count<200;count++){
              dividerVoltage = analogRead(A2);
              average = dividerVoltage + average;
         }
  
  }

You still use the potentially unstable default Aref.
Did you understand anything I wrote about 1.1volt Aref.

Why do you put the result of the A/D (0-1023) in a float.
200 readings for averaging is a lot for monitoring a constant voltage.
I didn't see any improvements in my experiments above 30 to 40.
I used an unsigned int to hold up to 64 readings in the sketch in post#1.
Leo..

The A_Ref is from a regulated 7805 measured with a Fluke 15B at all times during test. The entire jig is power by a 3A external power supply with a 7805 running the Arduino.

With 200 samples my end result is exactly like the Fluke reading but I will take your suggestion and try 30-40 samples.

The voltage is not constant as I have 1000 of these miniature power supplies to test. The all fluctuate under load and during startup by a few mV and I wanted to capture the mV differences. the power supply has to maintain a stable voltage under a 20W load which according the the Fluke it does just the Arudino was fluctuating and not displaying correct calculated voltages.

Now my displayed result is exactly like the fluke so I am content that the average sampling method works. I have tested almost 500 power supplies already(worked through the night) and my results were most off by 0.02mV.

But I will still take all your concerns and try them out on the second jig, this one works so I am not going to tinker with it.