Uno - Switching analogReference in sketch - RESOLVED

I have 3 analog sensors on my project - a pair of 0-5V inputs and a single 0-1.8v input. I’ve read the information on the work-around for being able to switch analogReference() back and forth between DEFAULT and EXTERNAL and have a 10k resistor on the 1.9V AREF input. I’m having trouble getting them switched however. If I run without any analogReference statements, it runs the default 5v and the two 0-5V inputs work as they should but the smaller input suffers terrible resolution. If I run the sketch with an analogReference(EXTERNAL), the small sensor signal works beautifully, but the two 0-5V inputs max out rather early - as expected.

I’ve tried to switch between them with no luck like this:

void loop() {
analogReference(DEFAULT);
int garbage = analogRead(somePin);  // analog read pin to set ADC ref v
delay(60);	// tried with and without delays

theOne = analogRead(inputOne);
theTwo = analogRead(inputTwo);
theOne = map(theOne, 0, 1023, 0, 100); // map input values to 0-100% scale
theTwo = map(theTwo, 0, 1023, 0, 100);
<output mapped values to Parallax LCD>
/*************************/
// Small Sensor code //
analogReference(EXTERNAL);	
garbage = analogRead(somePin);
delay(60);  // again with and without the delay
theSmall = analogRead(smallPin);
theSmall = ((100*1.9*theSmall)/1024)*10;	// map input 
<process and output theSmall to Parallax LCD>
}

As I noted, the code processes properly with the exception of switching the analog reference voltage around. Once it goes to the EXTERNAL ref, it doesn’t come back.
Have I created this headache for myself by using a resistor twice the size recommended? It’s what happened to be laying in front of me when I was building it up.

It's my understanding that you should not have an external voltage source connected to the AREF pin when using the DEFAULT analogReference as you will short the supplies.

http://arduino.cc/en/Reference/AnalogReference Did I misunderstand the comment about the 5k resistor here then?

Don't use anything less than 0V or more than 5V for external reference voltage on the AREF pin! If you're using an external reference on the AREF pin, you must set the analog reference to EXTERNAL before calling analogRead(). Otherwise, you will short together the active reference voltage (internally generated) and the AREF pin, possibly damaging the microcontroller on your Arduino board.

Alternatively, you can connect the external reference voltage [u]to the AREF pin through a 5K resistor, allowing you to switch between external and internal reference voltages[/u]. Note that the resistor will alter the voltage that gets used as the reference because there is an internal 32K resistor on the AREF pin. The two act as a voltage divider, so, for example, 2.5V applied through the resistor will yield 2.5 * 32 / (32 + 5) = ~2.2V at the AREF pin.

Those two paragraphs seem contradictory to me so I'll defer to someone else who has more experience using the EXTERNAL reference.

Add a very large delay immediately after changing your reference, but before the next analogRead.

I vaguely recall problems occurring if you do an analogRead() too soon after changing the reference.

When I say large, I mean a couple hundred (to 1000) milliseconds, at least as a trouble shoooting step.

If using a large delay doesn't work, and you just want it to start working... you could just scale the 0-5v signal down to 0-1.8v with a simple voltage divider... two resistors. Or you could make a buffer stage with gain (reduction, actually) to do the same thing but with no load on the 0-5v signal to alter it's reading. That would just take an op-amp and a couple resistors, but may require a negative voltage source to go all the way to zero.

I know this doesn't really address your concern about switching Aref voltages, but are just work-arounds.

Thanks for the info - putting the delay ahead of the first read seems to have worked but now I have new strangeness that appears to be tied to switching the ref voltage.

theSmall = analogRead(smallPin);
Serial.print(theSmall);

gives me an output of 145, while

Serial.print(analogRead(smallPin));

gives me 378 (which is the value I expected). If I remove the analogReference(EXTERNAL), I end up with a matching 145 from either. What's going on with my variable - it's stuck with the default ref? I tried obscene delays (10000), half-a-dozen garbage reads...I must admit to being rather confused now.

I'm thinking the only way I'm going to be able to run these 3 sensors together is to buffer the output of the small sensor.

What data-type is theSmall?

Try performing three successive calls analogRead after changing the reference.

Add a very large delay immediately after changing your reference, but before the next analogRead.

Actually you need to put the delay after the first analogRead after changing the reference. Issuing a call to analogReference does not actually change the reference, the change takes place when you issue the first analogRead after analogReference...it's a safety mechanism. Also when switching the reference from a high voltage (DEFAULT) to a lower voltage will require several garbage reads before you get a stable reading. http://arduino.cc/forum/index.php/topic,22922.0.html

When switching from the DEFAULT to internal 3.3V reference you have to throwaway about 50 readings (5.5 ms) before the reference voltage stabilizes. The reason for this is because of the 100nF bypass capacitor on the Aref pin. So I would guess that switching from 5v to 1.9v will increase the stabilization time even more.

theSmall is an INT. Wayne - if I run the above code in succession with repeated sampling, theSmall is always 144 and the direct read/output of the pin is always right (or what I expect). I can call them one after the other in succession and I get 144, 378, 144, 378, on and on.

I'll try moving the delay when I get back home tonight, and I'll post the code in it's entirety with the results.

Thanks again for the input gentlemen (I presume).

wayneft:

Add a very large delay immediately after changing your reference, but before the next analogRead.

Actually you need to put the delay after the first analogRead after changing the reference. Issuing a call to analogReference does not actually change the reference, the change takes place when you issue the first analogRead after analogReference...it's a safety mechanism. Also when switching the reference from a high voltage (DEFAULT) to a lower voltage will require several garbage reads before you get a stable reading. http://arduino.cc/forum/index.php/topic,22922.0.html

When switching from the DEFAULT to internal 3.3V reference you have to throwaway about 50 readings (5.5 ms) before the reference voltage stabilizes. The reason for this is because of the 100nF bypass capacitor on the Aref pin. So I would guess that switching from 5v to 1.9v will increase the stabilization time even more.

Very interesting...will have to remember that one.

That was the trick! Putting the delay after the first analog read sorted it out.