I'm new here so, if I make any mistake, sorry. Well, I'm working with Arduino (Mega2560) to construct an Ammeter and found out a little problem... Arduino Mega measures voltage from 0 to 5V, and the AnalogPins return a 10-bit value according with the reading (that is, 1 bit represents 5/(2^10)=4mV (approximately)). But, in the case of ammeter, I need to use a resistor with small resistance so that my circuit don't get changes. So my objective is read the voltage drop and from V = R.I, calculate the current. But, as the voltage drop is such as slowly, the pin can't read any value. Eg.: there is a current flowing from 2mA in the region that I would like to measure. With a resistance of 0.3 ohms (the lower value I found here) , would be: V = 2m . 0.3 = 0.6mV. As I said, the lower posssible value of reading in analogPins is 4mV. Thus, how to improve my precision of reading? For example, instead of 1023 represents only 5V, the same value represents around of 30 or 40mV... 0 - 0 V 1023 - 30/40 mV
-
How about getting a 500ms average voltage read? – Masoud Rahimi May 26 '19 at 20:09
-
How so? I didn't understand. – Luan Souza May 28 '19 at 01:51
-
First If your max voltage is too small you need to step it up, then create a function that read a large sample (e.g 1000) in about seconds then gets an average from it. This would give you the best result you can get from an analog input. – Masoud Rahimi May 28 '19 at 02:31
-
I'm voting to close this question as off-topic because it's about Arduino hardware and interfaces to that best asked on https://arduino.stackexchange.com/ – Rob May 29 '19 at 00:00
3 Answers
You can use 1.1V internal voltage reference, or some more precise external one (This can be archieved by analogReference
). BTW with such a small currents it would be more convenient to use bigger resistor.
Or, forget about limited functionality of analogRead
and do it directly. For example 2.56V reference, differential input with 10x or 200x gain (but you'll get range -512 to 511 -> 2.56/512).

- 3,534
- 2
- 18
- 23
-
The problem about analogReference is because it change the referente of all pins. My real project is constructing a Multimeter. So if I change the reference, I'll get some problems. I've got great results with the others measures (voltmeter, ohmmeter, etc). There's a way to change the reference for only one pin? Thanks for your answer. – Luan Souza May 28 '19 at 01:56
-
You can change it before the measure and after the measure set the default. But you have to wait some time after each switch to reference gets stabilised. Differential input with gain would be much better aproach, but you can't use analogRead, as it suports single ended inputs only. – KIIV May 28 '19 at 05:39
-
Wow, I get it! Thank very much for your answer, I've not thought about this!! – Luan Souza May 28 '19 at 17:21
In below example, voltage_meter
reads 500 samples in about 1 millisecond and returns the average. I set the reference to 1.1v
for better precision.
int battery_pin = A3;
float voltage_meter()
{
//read battery voltage per %
long sum = 0; // sum of samples taken
float voltage = 0.0; // calculated voltage
float output = 0.0; //output value
for (int i = 0; i < 500; i++)
{
sum += analogRead(battery_pin);
delayMicroseconds(1000);
}
// calculate the voltage
voltage = sum / (float)500;
// voltage = (voltage * 5.0) / 1023.0; //for default reference voltage
voltage = (voltage * 1.1) / 1023.0; //for internal 1.1v reference
//round value by two precision
voltage = roundf(voltage * 100) / 100;
return voltage;
}
void setup()
{
analogReference(INTERNAL); //set reference voltage to internal
Serial.begin(9600);
}
void loop()
{
Serial.print("Voltage Level: ");
Serial.print(voltage_meter(), 4);
Serial.println(" V");
delay(1000);
}

- 732,580
- 175
- 1,330
- 1,459

- 5,785
- 15
- 39
- 67
On ATmega based boards (UNO, Nano, Mini, Mega), it takes about 100 microseconds (0.0001 s) to read an analog input, so the maximum reading rate is about 10,000 times a second.
100 Microsecond and no 1000 how the example

- 11
- 2