It's about time I understood analogref(Internal)

Hi Guys,

Would appreciate some help. I have a Yun. And LCD Keypadshield and a 4 channel relay (

This particular relay requires a digitalwrite HIGH to keep to relay off and LOW to turn it on.

So Basically Yun+ LCD+ 4 relays being held high most of the time = a bit of a power draw.

I am trying to read the temperatures from 2 LM335's which are fed by the 5v pin through 2.2kohm resistors. The problem is, when the relays click on or off the voltage must be changing which is causing the readings to jump around.

Before I started, I read the actual voltage I was getting from the board to be 4.36v with my multimeter so I put am holding that in a float called ActualVoltage. Everything was working fine until I actually built the circuit with the relays plugged in . The reason I am using 980 rather than 1024 is because the actual voltage was lower than I expected.

You can tell I am not very good with analog electronics. They tend to puzzle me

                PanelADC= analogRead(4);                                                                                // Read in a Panel ADC Reading
                PanelTemp=PanelTemp+PanelADC * ActualVoltage / 980 * 100 - 273.15 + config.PanelTempAdj;

The above bit of code is part of a loop. Basically I sample 50 readings of panel temp and then average them.

Can anyone suggest how to alter this code with a software fix probably using analogref(internal) or 2v56 so it wont be affected by the relays coming on and off.

I would really appreciate the help. If this can be fixed in software with just some minor code change and no need to reetch the board that would be brilliant!


Is it possible that your code is too sensitive - in other words, is it necessary for a small change in the reading to cause the relay to switch?

Read about hysteresis.

Post your complete Arduino sketch or, preferrably, the simplest/shortest sketch that demonstrates the problem


Thanks Robin. Well at least the Marquee got your attention.

The code is for a differential temperature controller so its not a question of it being too sensitive. As the temperature rises to a certain point the relays are switched on to activate a pump. But this causes the values read by the sensors to jump. Theres nothing i can do about turning the relays on and off, thats the nature of the project. The relays are turned on by sending digitalwrite low (Yes I know its an odd relay board). Which means the voltage being fed to the sensors suddenly increases.

I've read and read and reread everything I can about analogref but I just cant get my head around it. If the 5v pin feeding the sensors on the arduino is jumping around and the sensors output a linear voltage at different temperatures proportional to their input voltage, how does using analogref help fix the reading.

It can't be that hard. everyone else must face this problem with reading analog sensors. We know you can't rely on the voltage from the 5v pin of the arduino to remain stable so how does anyone ever build anything which gives a consistant output from an analog sensor?

Before try to increase resolution of sensor, two things you would better take care first;-

  1. Use separate power supply to power the Yun and Relay circuit.
  2. Optically isolated relay board is prefer. Now no common ground, no common power supply, Yun output optically isolated.

This is perfect way to eliminate electronic interference by connect two system via Opto-isolator.

Relay board, Price: $6.79 & FREE 2 day Shipping

Now you could use analogReference(INTERNAL) to increase resolution of sensor. Change sensor to LM35 for 0~1.1 V/ 0~110 Celsius range.

float tempC;
int reading;
int tempPin = 0;  // switch to yun analog pin
void setup()
void loop()
reading = analogRead(tempPin);
tempC = reading / 9.31;

mearsy: The code is for a differential temperature controller so its not a question of it being too sensitive. As the temperature rises to a certain point the relays are switched on to activate a pump. But this causes the values read by the sensors to jump.

Sorry if I wasn't clear. What I had in mind is that the change in value due to the relay going on could be within a range that does not cause any change in the relay setting. Another possibility is that you give time for the relay current to settle before taking another temperature reading.

I had assumed you would have separated power supplies, but if not, do so.

Using the internal 1.1v ADC reference voltage is as simple as analogReference(INTERNAL) on a Uno. Of course you then need a voltage divider on your input signal so that its range is 0-1.1v


Currently I have a voltage divider using a 2.2kohm resistor. I measure the board when its not connected to the relays at 4.36v.

The minimum voltage put out by the lm335 to the analog pin is 2.33v which equates to -40. the maximum being 3.73v which equates to 100

I use both of these meximum ranges to signify different things in code. So the total range for the sensors is 1400mv

what would analogref(2v56) give me?

You tried to read from 2.33V to 3.73V, you can not use analogref(2v56) , you should use analogReference(EXTERNAL) and setup EXTERNAL voltage as 3.80V. Wire up 3.80V voltage regulator and feed it output with resistor into AREF pin.

If you use a voltage divider to bring the max voltage from the LM335 down below the internal 2.56v you don't lose any accuracy.

You might also look at the differential voltage options of the ADC. I only came across this recently as it is not a feature of the Atmega328.

I found this YouTube video which helped me understand it.