Understanding the 3.3V pin of the Uno board

Hello everyone! I'm interested in using the 3.3V power output in the Arduino Uno board, as I've read thanks to a rescaling of the Analog input pins spectrum, it can lead to a more precise reading of the voltage output given by sensors such as the TMP36 included in the starter kit.

To get more acquainted with it, I've started shorting it to the analog input pin number 0 and running the following, very simple code, which should simply rescale the 10 bit analog spectrum into the 0..5V voltage value it should read, hence giving me the epd it's being fed.

void setup() {
  Serial.begin(9600);
}

void loop() {
  Serial.println(analogRead(A0)/1023.00*5.00);
  delay(1000);
}

However, the serial monitor output is stable around 3.19 (once in a while printing 3.18 or 3.20 with roughly the same occurrence rate). Shouldn't it be saying 3.30?

Sorry if the issue has been already pointed out somewhere, but looking around brought me nothing on this specific matter.

Thanks everyone and have a good day!

The default analog reference is Vcc. Vcc not be exactly 5.00V. To get accurate results you need to measure Vcc and use the measured value in the formula.

analogRead(A0)/1023.00*Vcc measured value.

Hi there,

You should use this"

Serial.println(map(analogRead(A0), 0, 1023, 0, 5000)); // 5000 being 5000 millivolts = 5V

Instead of:

Serial.println(analogRead(A0)/1023.00*5.00);

Small inaccuracies will always occur due to imperfect wires and internal circuits, there is an offset curve of Arduino analog input pin (I think on data sheet, google it) where it shows RAW input VS read value by Arduino input, you can implement it to get best accuracy.

3Dgeo, that still depends on Vcc (default Vref) being exactly 5.00 volts, which it seldom is.

Minor correction:

analogRead(A0)/1024.0*Vcc

If you don't mind a measuring range of -50C to +50C, then you could use the internal 1.1volt Aref. Leo..

const byte tempPin = A0; // connect TPM36 to 3.3volt A0 and (not-shared) ground
float calibration = 0.1039; // calibrate temp by changing the last digit(s) of "0.1039"
float tempC;

void setup() {
  Serial.begin(9600);
  analogReference(INTERNAL); // use internal 1.1volt Aref
}

void loop() {
  tempC = (analogRead(tempPin) * calibration) - 50.0;
  Serial.print("Temperature:  ");
  Serial.print(tempC, 1); // one decimal place
  Serial.print(" C");
  delay(1000); // use a non-blocking delay when combined with other code
}

Edit: In case you wonder why the 0.1039 This, simplified: Aref*100/1024 See this page. Every Arduino has a sligtly different uncalibrated (but stable) 1.1volt Aref. My Uno was a bit on the low side (~1.064volt).

Using the 3.3volt supply as a reference (and power supply of the TMP36) is also possible.

Connect the 3.3volt pin to the Aref pin, and make sure you set Aref to external (failing to do so will fry the Aref pin). So in setup(). analogReference(EXTERNAL); // use the 3.3volt supply as reference Then use ~3.3volt in the maths line.

Now you get the full temp range of the TMP36 (-50C to +150C), but the penalty is a lower resolution. Leo..

Thanks to everyone for the answers! So I've bought myself a multimeter (for reference to its reliability I attach its model in case anyone knows it - tell me if these kind of links are forbidden as maybe perceived as advertisements and I'll remove it) and proceeded to make some measurements (i.e., 5V, 3.3V and Vin using different power sources).

First, I've attached my Uno board to my laptop using the USB Type-B port and the pin voltages resulted as follows): 5V: 5.169V 3V: 3.302V Vin: between 4.66V and 4.67V (moving the jumpers out of the multimeter and in again gave slight discrepancies)

Then, I've plugged a 12V AC/DC adapter into the board's barrel jack and got these results:

5V: 5.007V 3V: 3.302V Vin: between 15.4V and 15.5V

So one question arises: how comes the 5V output is more accurate with the AC adapter? Is it because, being the USB input less than 5V, Arduino has to "upscale" it? Also, if the adapter is rated as a 12V 500mA output, how comes the Vin is measured as 15.5V? Another adapter, rated 12V 1.5A, gave unchanged results on the 5V output but 11.3~11.4V on the Vin pin, way nearer to the nominal value. Is it a normal consequence of the different current output, or does that mean the first adapter is low quality or corrupted? To give further data, here is the Vin measured with other 12V adapters, each with a different current output:

11.4~11.5V 1.2A 11.3~11.4V 2A 11.4~11.5V 1.5A

Then, I've used a 9V 200mA adapter and here are the results:

5V: 5.017V 3.3V: 3.301V Vin: between 10.4V and 10.5V

Lastly, powering the board through a 9V 800mAh Li-ion rechargeable battery which outputs 8.26V (just charged), the rates are the following: 5V: 5.024V 3.3V 3.301V

Probably the issue has already been covered (didn't find anything though), but from this quick test it seems like the higher the source voltage, the more precise the 5V outlet will be. The 3.3V one seems not to notice the different sources and is always more accurate. Should that be used as a reference?

jremington: Minor correction:

analogRead(A0)/1024.0*Vcc

Thanks for your input. I entered 1023, as I've read in the beginner's projects' book and in the tutorial, because 1024 values go from 0 to 1023, but after your comment I've read a little more and got to this comment by nickgammon which I find quite illuminating - but the overall dicussion it belongs to is really interesting, including the different schools of thought presented there. In particular, from a quick reading I can resume as follows:

  • nickgammon, since every analog value refers to an interval of voltages, finds an acceptable level of approximation in Peter_n's very simple formula of taking the value in the middle of the interval:
float voltage = ((float) rawADC  + 0.5 ) / 1024.0 * 5.0
  • Coding Badly says that if you are adding an offset to solve a problem you should rather using a better ADC, and reminds of the full interval each analog value represents;
  • christop approaches the issue from a mathematical point of view, stating indeed the ADC spectrum is a semi-open interval [0,1024) which projects into the semi-open interval of voltages [0,Vref), hence the maximum value is way nearer to 1024 than it is to 1023.

Very interesting indeed.