First , I knew nothing.
Then I read a lot, and felt I understood.
Then I read more, and became more uncertain/confused than ever.
So I appeal to help here.
I have a Teensy 3.2 I'm using for this project. It wants 5VDC in but its logic runs at 3.3V. This makes me confused about the reference voltage options.
For analogReference()...
DEFAULT... normally this would be Vin, however Vin is 5V which is out of bounds for the Teensy 3.2's ADC and AREF which must be 3.3V or lower. So is "DEFAULT" 3.3V? How accurate and how stable is the Teensy's 3.3V voltage converter?
INTERNAL... I believe this is 2.56V on the Teensy 3.2, correct? How stable and accurate is this? How is this even relevant considering everything else on the Teensy is working w/ 3.3V? Is the assumption that if you choose "INTERNAL" that you are then externally limiting the range being read on the ADC pin to 0-2.56V?
EXTERNAL... all I'm certain here is that it must be 3.3V or lower. I thought I understood how to use this but no longer, and perhaps I don't need to if DEFAULT (possibly) or INTERNAL (unlikely) end up being good enough for me. At first I thought I could just send it the 3.3V from my external voltage converter, but it seems that one also needs to use a resistor/diode/shunt or something. But it's the external 3.3V that is providing the voltage through the stuff that the ADC pin is reading so maybe I should really try to use this as my external AREF.
For all of the above... what's the way in code to read and use the measured reference voltage, regardless of source? That way if it's at least STABLE, if not "accurate", that can be compensated for. I found this code, but it gets into mux-voodoo that is above my current expertise. It does not run as-is and I don't know what'd be necessary to fix it:
Source: https://forum.arduino.cc/index.php?topic=267827.0
And finally: is bumping the resolution to 12 bits really as simple as using analogReadRes(12)? (from what I read, 13-bit isn't reliable?). But analogReadAveraging() only works w/ 8 or 16-bits, right? So if I wanted to average at 12 bits, do I read and average at 16 bits and discard the last 4 bits?
Then I read a lot, and felt I understood.
Then I read more, and became more uncertain/confused than ever.
So I appeal to help here.
I have a Teensy 3.2 I'm using for this project. It wants 5VDC in but its logic runs at 3.3V. This makes me confused about the reference voltage options.
For analogReference()...
DEFAULT... normally this would be Vin, however Vin is 5V which is out of bounds for the Teensy 3.2's ADC and AREF which must be 3.3V or lower. So is "DEFAULT" 3.3V? How accurate and how stable is the Teensy's 3.3V voltage converter?
INTERNAL... I believe this is 2.56V on the Teensy 3.2, correct? How stable and accurate is this? How is this even relevant considering everything else on the Teensy is working w/ 3.3V? Is the assumption that if you choose "INTERNAL" that you are then externally limiting the range being read on the ADC pin to 0-2.56V?
EXTERNAL... all I'm certain here is that it must be 3.3V or lower. I thought I understood how to use this but no longer, and perhaps I don't need to if DEFAULT (possibly) or INTERNAL (unlikely) end up being good enough for me. At first I thought I could just send it the 3.3V from my external voltage converter, but it seems that one also needs to use a resistor/diode/shunt or something. But it's the external 3.3V that is providing the voltage through the stuff that the ADC pin is reading so maybe I should really try to use this as my external AREF.
For all of the above... what's the way in code to read and use the measured reference voltage, regardless of source? That way if it's at least STABLE, if not "accurate", that can be compensated for. I found this code, but it gets into mux-voodoo that is above my current expertise. It does not run as-is and I don't know what'd be necessary to fix it:
Code:
// Read the analog value of an external voltage at the AREF pin.
//
// Warning: Do no use this sketch !
//
// This sketch is when an external voltage is supplied to the AREF pin.
// That is a very rare situation.
//
// Warning: using an external voltage at AREF might cause an
// internal shortcut when analogRead() is called before the
// reference is set to external.
//
void setup() {
Serial.begin (9600);
Serial.println ("\nRead voltage at AREF pin");
analogReference (EXTERNAL);
}
void loop() {
float voltage = readAref();
Serial.println(voltage);
delay(1000);
}
//
// Function readAref
//
// Reads AREF (when external voltage is supplied).
// When the AREF pin is open, a value of 1.1V is returned.
// This function is only valid for a voltage at AREF of 1.1 to 5V.
//
// The calculations can be translated for integers to prevent
// use of float.
// Only for the Arduino Uno, Nano, Pro Micro at this moment.
// Experimental, no guarantees.
// public domain
//
float readAref (void) {
float volt;
#if defined (__AVR_ATmega8__)
#elif defined (__AVR_ATmega168__)
#elif defined (__AVR_ATmega168A__)
#elif defined (__AVR_ATmega168P__)
#elif defined (__AVR_ATmega328__)
#elif defined (__AVR_ATmega328P__)
// set reference to AREF, and mux to read the internal 1.1V
// REFS1 = 0, REFS0 = 0, MUX3..0 = 1110
ADMUX = _BV(MUX3) | _BV(MUX2) | _BV(MUX1);
// Enable the ADC
ADCSRA |= _BV(ADEN);
// Wait for voltage to become stable after changing the mux.
delay(20);
// Start ADC
ADCSRA |= _BV(ADSC);
// wait for the ADC to finish
while (bit_is_set(ADCSRA,ADSC));
// Read the ADC result
// The 16-bit ADC register is 'ADC' or 'ADCW'
unsigned int raw = ADCW;
// Calculate the Aref.
volt = 1.1 / (float) raw * 1024.0;
#elif defined (__AVR_ATmega32U4__)
#elif defined (__AVR_ATmega1280__) || defined (__AVR_ATmega2560__)
#endif
// Try to return to normal.
analogReference(EXTERNAL);
analogRead(A0); // the mux is set, throw away ADC value
delay(20); // wait for voltages to become stable
return volt;
}
And finally: is bumping the resolution to 12 bits really as simple as using analogReadRes(12)? (from what I read, 13-bit isn't reliable?). But analogReadAveraging() only works w/ 8 or 16-bits, right? So if I wanted to average at 12 bits, do I read and average at 16 bits and discard the last 4 bits?