Notifications
Clear all

Why is my Arduino sketch math wrong ?

8 Posts
6 Users
0 Likes
2,272 Views
(@genki)
Member
Joined: 4 years ago
Posts: 10
Topic starter  

Hi,

Looking for an explanation why my Arduino output math seems to fluctuate, or maybe I'm missing something.

I'm very new and this is my first sketch on the arduino, passed the blinking LED.

I watched many many YouTube Videos and read a lot to finally build my Voltage Divider (for measuring a 12v boat battery bank)

The voltage is supplied on the test bench by a Dr Meter Power Supply and is rock solid, measured everything with my UNI-T61E. I even have calibrated the 5v reference value for the Arduino Uno ADC.

But, even though the voltage input is not appearing to change, the Arduino Math appears to be... !!?

The voltage into the ADC on Pin A0 did not change, but the output math fluctuates, can anyone help explain why please?

Output changing from 12.73 at times, to 12.78...

Actual Voltage :12.78
A0 Sensor Input :1.15
Actual Voltage :12.73
A0 Sensor Input :1.15
Actual Voltage :12.78
A0 Sensor Input :1.15
Actual Voltage :12.73
A0 Sensor Input :1.15
Actual Voltage :12.78
A0 Sensor Input :1.15
Actual Voltage :12.78

Here is the sketch

/*
referenceVoltage calibration
measure from +5v Arduino pin to common GND
*/
float referenceVoltage = 5.029;

/*
ResistanceMultiplier calibration
measure total voltage across both R1+R2
then measure across just R2,
then divide first number with second for the multiplier
*/
float ResistanceMultiplier = 11.11;

float voltage = 0.0;
float sensorValue = 0.0;

void setup() {
analogReference(DEFAULT);
// initialize serial communication at 115200 bits per second:
Serial.begin(115200);
}
void loop() {
// read the voltage from Dr Meter Power Supply input on analog pin 0:
float(sensorValue) = analogRead(A0);

// Convert the analog reading (which goes from 0 - 1023) to a voltage (0 - 5V):
float(voltage) = (float(sensorValue) * (float(referenceVoltage) / 1023.0));

// print out the value you read:
Serial.print("A0 Sensor Input :");
Serial.println(float(voltage));

Serial.print("Actual Voltage :");
Serial.println(float(voltage) * float(ResistanceMultiplier));

delay (20000);
}

 

Thanks ahead for any help

 

Genki


   
Quote
hstaam
(@hstaam)
Mr.
Joined: 5 years ago
Posts: 61
 

Try printing out the analog read values with more decimal points. the difference may be due to the mere 10 bits resolution  of the ADC.

Hope this helps

 

hj

hj


   
ReplyQuote
Hunter O'Gold
(@hunterogold)
Member
Joined: 4 years ago
Posts: 23
 

Occam's razor. Start with the most likely source of error first and eliminate it. If that's not the source, move on to the next most likely. And so forth. In no time at all you will isolate your problem. Hope this helps.

The simplest solution is probably correct.


   
ReplyQuote
frogandtoad
(@frogandtoad)
Member
Joined: 5 years ago
Posts: 1458
 

@hstaam

Quite possible:

Serial.println(float, decimal_places);

Forgot to mention also with String:

Serial.println(String(float, decimal_places));

Cheers!


   
ReplyQuote
(@genki)
Member
Joined: 4 years ago
Posts: 10
Topic starter  

Hi,

Thanks for the help !!

I'm still troubleshooting why the ADC A0 Pin is producing different results, even with a stable monitored input voltage.

However, adding the decimal places to the output has further enabled me to watch for the fluctuations to better debug this. 

In case anyone is interested, I've been watching these ADC Accuracy Videos.

Some next steps

Try different R1 and R2 resistors - using 100K and 10K at the moment

Try ignoring first 10 results of ADC on boot

Average the results from the ADC

Thanks

Genki


   
ReplyQuote
byron
(@byron)
No Title
Joined: 5 years ago
Posts: 1112
 

@genki - I wonder if your circuit is picking up some radiated emi that causes your measurement fluctuations.


   
ReplyQuote
 Bob
(@rwf1st)
Member
Joined: 5 years ago
Posts: 1
 

@genki

If you use the Voltage divider formula 'Eout = Ein * R2/ (R1 + R2) you will find that the number 1.15 is correct

With an Input of 12.78 Volts Eout = 12.78 * 10000/ (10000 * 100000) which yields 1.1618.  If you need to print out the correct value multiply your result by 11.  ( 11 * 1.1618  = 12.779)     Hope this Helps.

This post was modified 4 years ago by Bob

   
ReplyQuote
(@genki)
Member
Joined: 4 years ago
Posts: 10
Topic starter  

Hi,

Thank you. I can get it stable and correct to 1 decimal place.

In the end, this accuracy is enough for me. I still have not been able to stop the fluctuations of 1.15 - 1.16 but I moved on. Added in some averaging to try and smooth the results, and added sleep with a wake interrupt when a pin goes high.

Waiting for an RTC module now, so I can wake it up X times a day from deep sleep.

Added a temp sensor and also I got the power usage down to 12ma when asleep and 25ma when it wakes up and takes a temp, voltage reading... but this is an Arduino Uno full boat, and so I would need to strip it down to get better low power results.

Of course now I realize that this needs internet... so I've ordered an ESP32 wifi feather board..

Then the board needs to wake up, set off a relay to turn on the Boat Wifi (a Mikrotik Groove 52) take the sample, send it to Internet and then turn off again..

I only just started with this Arduino stuff and now I'm down rabbit holes, ordering Adafruit boards and stuff off freaking Banggood.

I blame Bill - What have you done to me !!!

🙂   LOL


   
ReplyQuote