Menu

Unable to start the internal 1.1V reference on ATmega328P

alex_t
2017-03-09
2017-03-09
  • alex_t

    alex_t - 2017-03-09

    Hi, new user here. First up, thank you for GCBasic, it's a great software to work with.

    I am working on a voltmeter based on ATmega328P and have decided to use the internal 1.1V reference since it's believed to be pretty stable. To increase the accuracy of the measurements, I need to find the exact voltage on the AREF pin (by measuring it with a multimeter then using it in my code), but with GCBasic it's always around 0.16V instead of 1.1V (it's like it doesn't get powered on). Here's my code:

    #chip mega328p, 1
    #config osc = int
    
    Dim pmm_temp As Word
    
    #define AD_REF_SOURCE AD_REF_256
    
    pmm_temp = ReadAD10(ADC5) ;Take a reading to enable the ADC
    
    Do
    Loop
    

    On the other hand, with this Arduino sketch, I get 1.08V on AREF, as expected:

    void setup ()
    {
      ADMUX = bit (REFS0) | bit (REFS1);  // Internal 1.1V reference
    }
    void loop () { }
    

    Any idea what I'm doing wrong?

    Best regards.

     
  • kent_twt4

    kent_twt4 - 2017-03-09

    The quick answer is to go ahead and set those ADMUX bits in your program code prior to reading the adc as a work around. Have not looked at the library so it may, or may not, be the problem :)

    Set REFS0 ON
    Set REFS1 ON
    pmm_temp = ReadAD10(ADC5) ;Take a reading to enable the ADC
    
     
  • alex_t

    alex_t - 2017-03-10

    Thanks for the input. I have looked inside a-d.h and it seems like the ReadAD functions overwrite the contents of REFS0 and REFS1 registers when called, but that's not a big problem.

    The issue seems to be a hardware one, after some experiments it looks like the 1.1V reference is connected to the AREF pin only while a reading takes place. Probably ATMEL thought it would save power. I thought that when the internal reference is selected it would be connected to the AREF pin at all times.

     
  • kent_twt4

    kent_twt4 - 2017-03-10

    The data sheet mentions adding a capacitor to Aref to add noise immunity protection. It took a 100uf cap for me to get a stable reading on my UNO! The reading was 1.088-1.091V.

     
  • William Roth

    William Roth - 2017-03-11

    Hi,

    According to my UNO R3 schematic there is a 100nF capacitor connected to AREF (Pin 21). Seems to me that this would be quite sufficient for stabilization of the internal AREF voltage. Anything over 1 uF would seem to be overkill unless possibly Vcc/AVcc is noisy due to a dodgy power source or poor grounding. Having to use a a monster capacitor for stable readings may be indicative of underlying problems.

    A quality power source and good grounding are paramount to good and stable ADC readings. If the Arduino UNO is being powered by the USB Port, then a good quality USB cable should be used. Not one of the cheap unshieded ones. I use a shielded cable that also has a noise filter near the output (printer) end.

    *** Setting the ADMUX bits REFSx in GCB source code will not do anything because they will be overridden at ADC acquisition time.

    With the default settings and a good USB Cable that supplies the power, I get very stable readings with the AVREF set to the internal 1.1V internal reference. The ADC voltage is supplied by a 10K pot to Arduino "A1". My TEK DVM reads 1.098 at the AVREF pin and 1.093 V when the ADC value just barely reaches 255.

    Here is my working Code:

     #chip mega328p, 16
    
       'I2C Stuff
        HI2CMode Master
       #define HI2C_DATA
    
      'Set up LCD
       #define LCD_IO 10
       #define LCD_I2C_Address_1 0x7E
    
       #define AD_REF_SOURCE AD_REF_256   '1.1V for Arduino Uno R3 (328P)
       #define AD_VREF_DELAY 1 ms         ' Must be 1 ms or greater
       #Define AD_DELAY 2 10 us           ' Default setting
       #Define ADSpeed MediumSpeed        ' Default setting 
    
       Wait 500 ms   'stabilize
    
        'read ADC and Display Value 
       Do
           AD_Val = readad(AN1)
           Locate 0,0
           Print AD_VAL : LCDSPACE 2
       Loop
    
     
  • kent_twt4

    kent_twt4 - 2017-03-11

    @William, just to be clear the a-d readings were just fine with the clone UNO and the 1.1V Aref specified using the inbuilt a-d library. Using an unknown quality wall wart to power up the UNO, could be it. Lots of long wires on the breadboard waving around in the air, that also could also be it. Good idea on using the USB port for power, I need to change over.

    Irregardless, now that we have shown it's possible to measure Aref voltage, I won't be revisting this anytime soon :)

     
  • William Roth

    William Roth - 2017-03-11

    Measuring the AVREF:

    If the ADC reads are taking place at a low sampling rate, the AVREF looks like a sawtooth since it cycles on/off with every acquisition. To get a valid reading at low sample rates, the DVM must be able to read DC Peak Voltage. Otherwise the rate must be increased so that the 100nF capacitor on the AVREF pin does not have time to discharge between acquisitions. Reading every 10 ms allows an accurate AVREF voltage measurement, even with a cheap DVM.

    Having a 100uF capacitor on the AVREF pin probably explains why one AVREF measurement was good and another was not so good. The 100uF cap cannot discharge between readings, even at relatively low sample rates. But I suspect the first few readings might not be very accurate until the 100uF cap fully charges, unless the AD_VREF_DELAY is increased significanly.

    Posted By Kent:

    Irregardless, now that we have shown it's possible to measure Aref voltage, I won't be revisting this anytime soon :)

    Me Either :)

     

    Last edit: William Roth 2017-03-11
  • William Roth

    William Roth - 2017-03-11

    @Alex ..

    Are you really operating the 328P at 1 MHz with the internal oscillator ? I would suggest a 16MHz Crystal instead unless you really need 1 MHz .... ? If this is the case then we must assume that are not using an UNO and that you may have not fitted any capacitor at all on AVREF. There must be at least a 100nF cap fitted there and another fitted on Vcc/AVcc

    Your test code for GCB does not have the ADC inside a loop so only one sample is taken and you will never get a good measurement. Put the ADREAD function inside a loop with a sample rate of 10 ms and then measure the voltage. Like this:

    #chip mega328p, 1
    #config osc = int
    
    Dim pmm_temp As Word
    
    #define AD_REF_SOURCE AD_REF_256
    
    Do
          pmm_temp = ReadAD10(ADC5) ;Take a reading to enable the ADC
          wait 10 ms
    Loop
    
     

    Last edit: William Roth 2017-03-11
  • kent_twt4

    kent_twt4 - 2017-03-11

    Heh, my try had a really low sample rate, I did not realize the MUX bits got cleared on exit from adc reading. Nor did I think to use Max reading on the DVM either. So that explains it, for me at least, Thanks!

     
  • alex_t

    alex_t - 2017-03-12

    Indeed, I had used 1 MHz, since it was the default speed,b utit can be changed to anything (i'm not tied to it in any way). In the end i'll probably go with 16 MHz as you suggested. I have the whole circuit on a breadboard, it's more easy to fiddle with :). The setup I have is like this:

    • A coil of 10 uH between +5V and AVCC
    • An electrolytic cap of 2.2uF and an 100nF cap between AVCC and GND (they are in parallel)
    • A capacitor of 100nF from ARef to GND

    Regarding the reference going on / off, here's what I found in the datasheet:

    The reference is on during the following situations:
    1. When the BOD is enabled (by programming the BODLEVEL [2..0] Fuse Bits).
    2. When the bandgap reference is connected to the Analog Comparator (by setting the
    ACBG bit in ACSR).
    3. When the ADC is enabled. [this is what i'm interested in]
    Thus, when the BOD is not enabled, after setting the ACBG bit or enabling the ADC, the > user must always allow the reference to start up before the output from the Analog
    Comparator or ADC is used.

    If we look in the a-d.h header of GCBasic, at line 1215 the ADC is turned on and at line 1222 it's turned off. This explains the fluctuations, etc. So to counter this and be able to measure the internal Vref accurately (i only have a simple, 3 1/2 digit multimeter without peak power measurement) I have used this code:

    #chip mega328p, 1
    #config osc = int
    
    ADMUX = 5 ;e.g. ADC5
    
    ;Use internal ref
    Set REFS0 On
    Set REFS1 On
    
    ;Set a prescaler
    SET ADPS2 On
    SET ADPS1 On
    
    ;Turn on ADC
    Set ADEN On
    
    ;Wait 10 s with the ADC on (the 1.1V reference is now also on). One can measure Aref
    Wait 10 S
    
    ;Here we'd normally make a conversion
    
    ;Turn off the ADC
    Set ADEN Off
    
    ;Finished
    Do
    Loop
    

    With it, I can read a stable 1085 mV. I will keep digging and playing with the code, might also make a small ADC lib (I also want to implement oversampling).

    Thanks for the input.

     

    Last edit: alex_t 2017-03-13
  • stan cartwright

    stan cartwright - 2017-03-13

    I haven't yet needed to change uno ref v for my a-d experiments. Can I assume it's not an issue and if I do want to change it from the supply rail ref it's all sorted?
    I down loaded GCB for pic use but used a uno more. The only code I've done on a uno is GCB. No sketch c install or anything arduino except xloader which I've erased since getting flash hex working and that was me using the wrong com port. Wish more people who find c difficult but basic easier knew GCB is supporting arduino even more and the arduino can be programmed in basic and run fast.

     
  • alex_t

    alex_t - 2017-03-14

    There's no problem with the way GCBasic works. The only issue I had is that with the current AD library the ADC is turned on only while the reading is taking place. This also means that the internal 1.1V reference is on only while the reading takes place. Not being on all the time, I couldn't measure its exact voltage (to use in my calculations). With the above code, the ADC (and thus internal reference) is kept on long enough for one to take a reading of the reference voltage on pin 21 of ATmega328P.

    Depending on your needs, you can use any reference you want, GCBasic will handle it just fine :).

    I'm sure that more people will come over and try GCBasic. It already is very powerful and I bet it will get even better. Hopefully some of us beginners will be able to help as well.

     
  • stan cartwright

    stan cartwright - 2017-03-14

    I'm enjoying using GCB. Wish I'd come across it earlier. As a beginner, I only post things that don't work with picaxe like glcd. I wrote my own plot and line draw in picaxe basic..have a laff :)
    picaxe 28x2 (pic 18f25k22) at 64mhz ext xtal https://www.youtube.com/watch?v=kL3c1wry9ok&t=3s

     
  • alex_t

    alex_t - 2017-03-14

    Sweet, keep it up :).

     

Log in to post a comment.