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