lgt8fx
lgt8fx copied to clipboard
Wrong analogReadResolution on boot
As https://www.arduino.cc/en/Reference.AnalogReadResolution states
It defaults to 10 bits (returns values between 0-1023) for backward compatibility with AVR based boards.
This doesn't seem to be true - at LGT8F. I got values up to 4096, which made my "regular" code not working.
I guess we should change this behaviour.
I can confirm, 12 bit seems to be default. I only see 4064 as max value though, not 4096.
4096 would be impossible in 12 bits, but 4095 should be the highest value ^^
I'd like to change the default in wiring_analog.c
Old:
uint8_t analog_resbit = 0;
uint8_t analog_resdir = 0;
Corrected:
uint8_t analog_resbit = 2;
uint8_t analog_resdir = 1;
Any comments on this?
Well, 12bit being 4096 (including 0) of course, but that is not what I observe. The highest value I measure is 4064.
I'm willing to take a PR to start with 10 bits by default :)
Ok, will PR it (was thinking I already did so LOL)
If in wiring_analog.c at line 30 default variables will be set like below, the analogRead() default resolution could be 10 bit.
uint8_t analog_resbit = 2;
uint8_t analog_resdir = 1;
Ohh sorry. Jayzakk commented it before me.
@seisfeld The gain error correction is the reason of the maximum ADC value is 4064.
// gain-error correction
#if defined(__LGT8FX8E__)
pVal -= (pVal >> 5);
#elif defined(__LGT8FX8P__)
pVal -= (pVal >> 7);
#endif
It is not mentioned by LGT8Fx databook. What is it for this correction?
Good catch @LaZsolt !
Here is a demonstration program of the ADC gain error. I think the ADC gain error should be mentioned in readme.
void setup() {
Serial.begin(38400);
analogReference(INTERNAL2V048);
analogReadResolution(12);
pinMode(DAC0, ANALOG);
//------------------------------------------------------
uint16_t value;
Serial.print(F("If ADMUX set AGND then ADC output: "));
value = analogRead(AGND);
Serial.print(value);
Serial.println( (value == 0) ? F("") : F(" ( Must be 0, is'n it? ADC not linear around zero valtage.)"));
bitSet(ADMUX,4); // ADMUX switch to DAC output
printvalueatDAC(0);
printvalueatDAC(1);
printvalueatDAC(2);
printvalueatDAC(3);
printvalueatDAC(4);
printvalueatDAC(250);
printvalueatDAC(251);
printvalueatDAC(252);
printvalueatDAC(253);
printvalueatDAC(254);
printvalueatDAC(255);
Serial.println();
Serial.println(F("The maximum ADC value should be at the maximum DAC output value, but not. The reason is the gain error."));
Serial.println();
Serial.println(F("End test."));
Serial.println();
}// end setup
void printvalueatDAC(uint8_t x){
delay(100);
analogWrite(DAC0, x);
Serial.print(F("If DAC == "));
if (x < 10 ) Serial.print(F(" "));
if (x < 100) Serial.print(F(" "));
Serial.print(DALR);
Serial.print(F(" then ADC output: "));
Serial.println(directADCread());
}
static uint16_t adcReadNow()
{
// start the conversion
bitSet(ADCSRA, ADSC);
// ADSC is cleared when the conversion finishes
while (bit_is_set(ADCSRA, ADSC));
return ADC;
}
int directADCread(){
uint16_t pVal;
uint16_t nVal;
#if defined(ADCSRA) && defined(ADCL)
#if defined(__LGT8FX8P__)
bitSet(ADCSRC, SPN);
nVal = adcReadNow();
bitClear(ADCSRC, SPN);
#endif
pVal = adcReadNow();
#if defined(__LGT8FX8P__)
pVal = (pVal + nVal) >> 1;
#endif
#else
// we dont have an ADC, return 0
pVal = 0;
#endif
// gain-error correction
#if defined(__LGT8FX8E__)
pVal -= (pVal >> 5);
#elif defined(__LGT8FX8P__)
pVal -= (pVal >> 7);
#endif
return pVal;
}// end directADCread
void loop() {
}
@LaZsolt I have a question regarding this gain correction thing. I'm using 2.048V as reference and set the ADC to 12bit. When I want to calculate expected ADC values like:
What do i use as ADC resolution in that formula? 4096 or 4064?
The resolution is 4064. Slightly bigger gain decrease the resolution. But replace "System Voltage" to "Reference Voltage". Voltage Measured = Reference / Resolution * ADC Reading
Thanks. Will take 4064 in all calculations and verify with multimeter. You're right about the ref voltage of course. (The formula image is not mine, I grabbed it off the web just for illustration.)
@seisfeld
Thanks. Will take 4064 in all calculations and verify with multimeter. You're right about the ref voltage of course. (The formula image is not mine, I grabbed it off the web just for illustration.)
As I writed above "Slightly bigger gain decrease the resolution" is true, but in calculations must use 4096. If the gain error wasn't so big then the ADC value reach the maximum when the input reach the reference voltage. But becase of error the ADC value reach the maximum before the input reach the reference voltage. So the ADC value decreased by gain correction for the good calculation. I hope it is understandable.
4096 Reference Voltage
---- = ---------------------
4063 Max Voltage Mesasured
@jayzakk and @dbuezas: Help wanted? Here it is.
For the backward compatibility of the default analogReadResolution I merged this maintenance with my last Pull request. https://github.com/dbuezas/lgt8fx/pull/130
Is this issue also closed by #130 ?
Yes.