Voltage Read with op-amp

Hi
I am hoping someone can help me, im having an issue with my hardware and software. I found this link

http://www.skillbank.co.uk/arduino/measure2.htm

it uses a voltage divider with an op-amp that helps read voltages using my Arduino. However I believe I am doing something wrong, as my voltages keep changing are not consistent and when ever I add a new input voltage, for example a bench power supply or a battery the voltage read out keeps changing. in my code there is a scale fator which i always have to modify as i change power supplys for it to read it exactly, in saying that sometimes when i un power the device and power it back on the scale factor changes again

the scale factor i have to always change is VIN / Sum (from the reading)

This is my code :

const int repeats = 10;
long int sum = 0; 
const long interval = 1000; 
unsigned long previousMillis = 0;
float voltage;
float return_voltage;
int output_tran = 5;
const float scalefactor = 6.1381;
void setup() {
  // put your setup code here, to run once:
Serial.begin(9600);
analogReference(DEFAULT);
pinMode(output_tran, OUTPUT);
}

void loop() {
unsigned long currentMillis = millis();
if (currentMillis - previousMillis >= interval) {
    previousMillis = currentMillis;
      readvoltage();
    Serial.print("sum of ten readings is : ");
Serial.println(sum);
       voltage = sum * scalefactor;
  Serial.print("voltage in mV is : ");
Serial.println(voltage,0);

if(voltage < 10200){   //10200 = 10.5
  digitalWrite(output_tran, LOW);
  
}
if(voltage > 13000){
  digitalWrite(output_tran, HIGH);
  //softReset();
  }
}
}

void readvoltage() {
sum = 0;
for (int j = 0; j < repeats; j++) {
 sum += analogRead(A0);
 delay(7); // choose a short delay that does not add to 20msec.
 }
}

For R1 I am using a 10K ohm resistor and R2 is 100K ohm resistor both 5%, I’m using the same op-amp that is on the link, however it is puzzling me. Unfortunately, I cannot change the design, of the pcb. So I’m hoping it is as simple as changing the resistor or my code. Any help will be great

the voltages i am trying to read are 0 - 15V

Thank you

Please extract the schematics and post here. I don't spend time on that.
Please give the numbers of expected readings and actual readings.

Depending on what voltages you are measuring and whether you care about input impedance , you can get by happily with just a voltage divider .
For accuracy use the processor internal reference , with that code the accuracy depends on the stability of the 5v supply to the Arduino , and your resistor choice doesn’t make use of the full range of the A/D.( 15v , gives around 1.2v at the input to the A/D , the resolution will therefore be poor )

As you are using 10k/100k , then you are better off just using a voltage divider on the analog input .

As above , draw out the circuit and give the outputs , indication of voltages etc

You don't need the op-amp and it will cause more trouble than it's worth! You just need two resistors to make a Voltage Divider so you can read above 5V.

With the default 5V ADC reference only need a 3:1 or 4:1 voltage divider. You may want some "headroom" so about 4:1 might be better...

The default ADC reference is the chip's supply voltage (Vcc). i.e. If Vcc drops, your voltage reading/calculation will increase.

If you are using the onboard 5V regulator Vcc should be fairly stable and "close" to 5V (depending on how much accuracy you need). If you are bypassing the regulator by using USB power or using batteries, or an external supply (or feeding it too low of a voltage into the regulator) your reference can vary and your readings will vary.

The optional-internal 1.1V is super-stable but it has a tolerance (I think 10%) so you may have to calibrate your code. And of course you'll need a different voltage divider resistors since the Arduino won't be able to read above ~1V.

It would be best if you modified your code to print out actual analogRead(A0) without any averaging and / or scale factors. It should be a long.

How much is the value drifting? Is it continually in one direction or does it drift up then down...

Hi

thanks to all who have replied, I have decided to ditch the op-amp and bypassed it with just a voltage divider, which is working out a lot more better, I ditched the 5% and stuck with 1% resistors for better accuracy (still the same values 10K and 100K). I have also updated my code

code below

#define NUM_SAMPLES 10
int sum = 0;                    // sum of samples taken
unsigned char sample_count = 0; // current sample number
float voltage = 0.0;            // calculated voltage
float voltage_change = 0.0;
 
int output_tran = 5;

void setup() {
  // put your setup code here, to run once:

    Serial.begin(9600);
       pinMode(output_tran, OUTPUT);
digitalWrite(output_tran, HIGH);
}
void loop() {
while (sample_count < NUM_SAMPLES) {
        sum += analogRead(A0);
        sample_count++;
        delay(10);
    }
 voltage = ((float)sum / (float)NUM_SAMPLES * 5.09) / 1024.0;
  voltage_change = voltage * 12.000;
if (voltage_change < 9.80) {
  digitalWrite(output_tran, LOW);
} 
  if (voltage_change > 14.00) {
  digitalWrite(output_tran, HIGH);
} 
 sample_count = 0;
    sum = 0;
}

The issue I am facing is that it doesn’t work that well. As you can see by my code the transistor turns off at 9.80 which is actually 10.2 on my bench power supply and turns on at 14.00 which is actually 13.00 on my bench power supply. the difference between the two is that before the voltage drop to 10.2 there is a load and before it comes back on at 13.00 there isn’t a load apart from the Arduino.

the track is connected to a DC- DC converter (traco power) which outputs 12V 2.5A (however only uses 1.5A) to differenct things, example PC, a router and a Radar, which all use 12V. the Vin to the traco is controlled by the Transistor.

is it possible that the issue is the vin voltage is on the same track as the vin to the voltage divider?

You are still using the default voltage reference which is the Vcc supply voltage .
Use the internal voltage reference instead .
What ever you use , some calibration will be needed .

Your power supply may well be noisy, a schematic may help us here ( might be voltage drops etc, depending how it’s wired ).

Hi

i am still having issues with this and literally pulling my hair out. i have decided to upload my schematic hoping it will help

AREF needs 100nF cap to ground as per the datasheet. Otherwise all analog readings will be unstable.

Hi

thank you for the help the signal was a lot more steady, however im having a issue with wires. for example i use a short wire and the readings are 12.8 at 12v from my bench power supply however when i use a long wire more then a meter i get 12.1 which is a lot more closer to the value i require. i know its due to resistance in the wire and a fixed resistor would help, however where would i put it.

below are two images one which i have now and one where i believe i should put the fixed resistor.

which is correct
Current
current
Fixed
fixed

The resistance of any wire that you use should be negligible in comparison to the 10kΩ and 100kΩ resistors.

Hi

Thats what i thought, however im getting such a big difference in changing the wire, using the same power supply

So i tried something to see what the issue could be the voltages are perfect no matter what wire i use, once there is no load on the traco power supply.

the one i am using is this
Traco TEN 30-1212

I don't see where POWER_IN is connected to VCC, or where AVCC is connected to VCC.

Power_IN is connected to a molex connector which is the voltage i am measuring, its the same voltage supplied to the DC-DC converter using the transistor, there is a voltage regulator for 5V (7805) which supplies 5V to AVCC on the micro controller.