Go Down

Topic: Aref pin on Nano (Read 84 times) previous topic - next topic

Mogaraghu

I am using the following code to provide a stable Vcc reference for Analog Reads . Picked up the code from this forum ..

Code: [Select]

/*
   The function getBandgap() is to calculate the actual Vcc of the
   MCU by using the internal reference of the MCU which is earlier measured
   by uploading the sketch below and then measuring the Vref pin :

    void setup ()
    {
      ADMUX = _BV (REFS0) | _BV (REFS1);
    }
    void loop () { }

   Once you get the Vref actual volts, plug that into the Bandgap() function.
*/

// Function to return the Vcc Volts x 100 to maintain precision

int getBandgap(void) {

#if defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
  const long InternalReferenceVoltage = 1078L;  // Adjust this value to your MEGA boards specific internal BG voltage x1000
  ADMUX = (0 << REFS1) | (1 << REFS0) | (0 << ADLAR) | (0 << MUX5) | (1 << MUX4) | (1 << MUX3) | (1 << MUX2) | (1 << MUX1) | (0 << MUX0);
#else
  const long InternalReferenceVoltage = 1077L;  // Adjust this value to your 168/328 boards specific internal BG voltage x1000
  ADMUX = (0 << REFS1) | (1 << REFS0) | (0 << ADLAR) | (1 << MUX3) | (1 << MUX2) | (1 << MUX1) | (0 << MUX0);
#endif

  delay(10);                                    // Let mux settle a little to get a more stable A/D conversion

  ADCSRA |= _BV( ADSC );                        // Start conversion
  while ( ( (ADCSRA & (1 << ADSC)) != 0 ) );
  int results = (((InternalReferenceVoltage * 1023L) / ADC) + 5L) / 10L; // Scale the value
  return results;
}



The problem is when I measure Aref pin with reference to GND, I am reading 4.63 V.  I think it should measure around 1.1V ?  Is the board cooked ??

GolamMostafa

#1
Sep 17, 2019, 04:21 am Last Edit: Sep 17, 2019, 04:22 am by GolamMostafa
Check your codes against the following bit map of ADMUX Register and asses if you have correctly chosen the bits to select Internal 1.1V for the VREF pin of the ADC. Probably, you haven't!

Mogaraghu

Check your codes against the following bit map of ADMUX Register and asses if you have correctly chosen the bits to select Internal 1.1V for the VREF pin of the ADC. Probably, you haven't!

Thanks. Sadly all this habit of studying the MCU registers has vanished with the advent of Arduino libraries. While the abstraction helps things done fast, it robs the knowledge about the innards of the processor.

I guess maybe this is my problem : If you do an analog read in the default mode of Nano or Uno ( MCU Vcc as reference ) then that voltage appears on the Aref pin. I am not sure if this is correct but measuring two Nano s yielded the same result. And if I do not invoke Analog reads like a simple Blink application then the Aref reads zero.

GolamMostafa

#3
Sep 17, 2019, 10:33 am Last Edit: Sep 17, 2019, 04:02 pm by GolamMostafa
Thanks. Sadly all this habit of studying the MCU registers has vanished with the advent of Arduino libraries. While the abstraction helps things done fast, it robs the knowledge about the innards of the processor.

I guess maybe this is my problem : If you do an analog read in the default mode of Nano or Uno ( MCU Vcc as reference ) then that voltage appears on the Aref pin. I am not sure if this is correct but measuring two Nano s yielded the same result. And if I do not invoke Analog reads like a simple Blink application then the Aref reads zero.
Arduino and Third Party Libraries do not always serve the specific purpose of a user; this is the case when a user needs to write register level codes as you tried to measure the value of Band Gap Voltage (1.1 V Internal) which is connected with Ch-14 of the MUX of the internal ADC (Fig-1 that belongs to UNO).


Figure-1: Structure od ADC of ATmega328P MCU

1.  int x = analogRead(arg); supports only A0 - A5 (ADC Ch-0 to Ch-5) for the argument field. Therefore, one has to use ADMUX and other registers to acquire the signal from Ch-14.

2.  The popular register level codes are:
(1)  Enable ADC and 125 KHz conversion cloak (clkADC) with the help of ADCSRA Register

Figure-2: Bit map of ADCSRA Register

(2)  Select voltage for VREF (1.1V internal) pin of ADC using of ADMUX Register.
(3)  Select Ch-14 with the help of ADMUX Register.

Figure-3: Bit map of ADMUX Register

(4)  Start ADC with the help of ADCSRA Register.
(5)  Wit until conversion is done by polling the ADSC or ADIF flag of ADCSRA Register.
(6)  Read ADC data by executing appropriate codes.
Code: [Select]
byte xL = ADCL;  //always read lower byte first after the execution of the Steps-2(1) to 2(5)
byte xH = ADCH;
int x = xH<<8 | xL;


Or

Code: [Select]
int x = ADCW;
(7)  Show internal band-gap (1.1V) voltage on Serial Monitor.

3.  Instruction coding for the text codes of Step-2
Code: [Select]
void setup()
{
  Serial.begin(9600);
  ADCSRA = 0b10000111;  //covers: Step-2(1)
  ADMUX = 0b11001110;    //Covers: Step-2(2) and 2(3)
}

void loop()
{
  byte x = ADCSRA;  //covers: Step-2(4)
  x = x | 0b01000000; //covers: Step-2(4)
  ADCSRA = x;

  while (bitRead(ADCSRA, ADSC) != LOW) //covers: Step-2(5)
  {
    ;
  }
  int y = ADCW;   //covers: Step-2(6)
  float z = (float)(1.1 / 1023.0) * y;  //covers: Step-2(7)
  Serial.print("Value of Internal 1.1V is found as: ");
  Serial.print(z, 1);
  Serial.println(" V");
  delay(1000);
}


Screenshot:

Figur-4:

Please, measure voltage at REF-pin of NANO and AREF-pin of UNO, you will get 1.1V.

Go Up