secrets of arduino atmega328p adc
In this tutorials i'm gonna tell you all about the adc present in arduino famous boards like UNO,NANO,MINI....the atmega328p chips consist of the "10-bit resolution adc" inside the uC.
The type of adc is used in is Successive approximation ADC.these are kind are slow but gives good resolution though.let's dig in registers of adc in atmega328p.
To read analog input we need The reg "ADMUX". The adc reg have a Pin called AREF (adc reference voltage). The gives 10-bit number i.e 0-1023, 0-0V & 1023-5V.
Vin = (Analog Ref * analogRead() ) / 1024
we need stable AREF voltage we can use internal 1.1V reference or we need to provide a stable voltage anywhere between 0.3V-5V externally.
we need to write to ADMUX register in order to enable it we need to write these following.
REFS0 REFS1 functioning
0 0 AREF is enabled from external source
0 1 VCC is taken as AREF
1 1 internal 1.1V is AREF
if we use the "01" option we get vcc as reference if ur are powering the Arduino with battery then the voltage changes and voltage regulator also changes it's values even with wall power adapter it happens so use internal reference voltage.
by controlling the ADEN we can save power i made a low power consumption arduino in this post check it out.
Next is the sample rate hack.......we can the sample rate value of adc .the max accuracy is achievable at sample rate clock of 50KHz - 200KHz in atmega328p. The change can be made using the ADCSRA register using a prescaler division.
The ADC clock of Atmega328P is 16 MHz divided by a ‘prescale factor’. The prescale is set by default to 128 which leads to 16MHz/128 = 125 KHz ADC clock. Since a single conversion takes 13 ADC clocks, the default sampling rate is ~ 9600 Hz.
in order to check the default sampling time use the following code.check out these awesome additional info on many more. and this one
byte PS_16 = (1 << ADPS2); byte PS_32 = (1 << ADPS2) | (1 << ADPS0); byte PS_64 = (1 << ADPS2) | (1 << ADPS1); byte PS_128 = (1 << ADPS2) | (1 << ADPS1) | (1 << ADPS0); long starttime, interval; void setup() { // ADCSRA &= ~PS_128; // ADCSRA |= PS_64; Serial.begin(9600); pinMode(A0, INPUT); } void loop() { starttime = micros(); for (int i = 0; i < 100 ; i++) { analogRead(A0); } interval = micros() - starttime; Serial.println(interval); // put your main code here, to run repeatedly: }
Comments
Post a Comment