ADC for ATTiny417 always reads 0x03FF

Go To Last Post
14 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I am using the ATTiny417. It is new to me. I have tried may examples to read the ADC but it always reads 0x03ff or 1032(same as 0x03ff). I have tried to break it down to it simplest form. I am using PA3. I have a 10K resistor in series with a 10K thermistor.

int main(void){
     //initialize ADC0   
    PORTA_pin_set_isc(PIN3_bm,PORT_ISC_INPUT_DISABLE_gc); //Disable  digital input buffer
    PORTA_set_pin_pull_mode(PIN3_bm, PORT_PULL_OFF);
     ADC0.CTRLC = ADC_PRESC_DIV4_gc      /* CLK_PER divided by 4 */
                 | ADC_REFSEL_INTREF_gc /* Internal reference */
                 | 0 << ADC_SAMPCAP_bp; /* Sample Capacitance Selection: disabled */

    ADC0.MUXPOS = ADC_MUXPOS_AIN3_gc; /* ADC input pin 3 */
    ADC0.CTRLA = 1 << ADC_ENABLE_bp     /* ADC Enable: enabled */
                 | 0 << ADC_FREERUN_bp  /* ADC Freerun mode: disabled */
                 | ADC_RESSEL_10BIT_gc  /* 10-bit mode */
                 | 0 << ADC_RUNSTBY_bp; /* Run standby mode: disabled */

    InitializeClock();
    Initialize10mSTimer(PFREQ);
    InitializeIO();
    sei();    //enable global int
    while (1){
        //doOff();
        ADC_Result = ADC_0_get_conversion(3);

     }

}

>

William

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

In problems like this the usual questions are:

1) what is the actual voltage on the ADC pin?

2) What is your VCC?

3) This is common problem when the ADC is overclocked or wrong ADC ref is choosen.

4) post a schematic and or clear picture of your setup

 

Jim

 

Click Link: Get Free Stock: Retire early! PM for strategy

share.robinhood.com/jamesc3274
get $5 free gold/silver https://www.onegold.com/join/713...

 

 

 

 

Last Edited: Tue. Oct 8, 2019 - 06:41 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

1) what is the actual voltage on the ADC pin? 1.6 volts

2) What is your VCC? 3.0 volts

3) This is common problem when the ADC is overclocked or wrong ADC ref is choosen. I have tried to divide by 8 instead of 4.

4) post a schematic and or clear picture of your setup

 

I have also just noticed that the default for the system is a 20MHz internal oscillator and the default was to divide by 4.

Attachment(s): 

William

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Ok, I'm not familiar with the new 0/1 AVRs, but with a mega in that freq range, the ADC prescaler needs to be /128, what is the max clock rate for the ADC? 

IIRC, the default clock has a /6 so runs around ~3MHz, unless set otherwise, how sure are you of your clock rate?

You may want to review these app notes as well, https://www.avrfreaks.net/forum/...

 

Jim

PS: I would try /64 or maybe /32

 

Edit added PS

Click Link: Get Free Stock: Retire early! PM for strategy

share.robinhood.com/jamesc3274
get $5 free gold/silver https://www.onegold.com/join/713...

 

 

 

 

Last Edited: Tue. Oct 8, 2019 - 08:37 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

What did you read when you grounded the ADC pin?  Did you even bother to try?

 

 

Where are your filter caps for you analog signal...while you might get by without them (do avg) , it is not recommended, partly due to aliasing noise.

 

You should be using Vcc (or a divided Vcc) are your ADC ref, not an internal.  That is a no-no in this case.

 

 

When in the dark remember-the future looks brighter than ever.   I look forward to being able to predict the future!

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Thank you for the references. Many of these I have seen.

I will try to drop down the frequency. 

I do not see how to set the Vref in the references and any example code that I found. I want to keep the Vref internal. I see the enum but it is not used anywhere.

typedef enum VREF_ADC0REFSEL_enum
{
    VREF_ADC0REFSEL_0V55_gc = (0x00<<4),  /* Voltage reference at 0.55V */
    VREF_ADC0REFSEL_1V1_gc = (0x01<<4),  /* Voltage reference at 1.1V */
    VREF_ADC0REFSEL_2V5_gc = (0x02<<4),  /* Voltage reference at 2.5V */
    VREF_ADC0REFSEL_4V34_gc = (0x03<<4),  /* Voltage reference at 4.34V */
    VREF_ADC0REFSEL_1V5_gc = (0x04<<4),  /* Voltage reference at 1.5V */
} VREF_ADC0REFSEL_t;

Can someone help me there?

why do you say " You should be using Vcc (or a divided Vcc) are your ADC ref, not an internal.  That is a no-no in this case. "

When I grounded the input pin to the ADC it still read 0x03FF.

William

Last Edited: Tue. Oct 8, 2019 - 10:06 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Your thermistors are driven by a Vcc level.  Therefore, the ADC reference needs to be based on that.  If the Vcc drops 10%,all of your readings will be completely wrong* if you use any internal reference.  You need to use external Vcc ref; that is called a ratiometric measurement.

 

 

* a small change in a thermistor voltage reading may be a big change in temperature.

When in the dark remember-the future looks brighter than ever.   I look forward to being able to predict the future!

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Yup, you need to set VDD as reference for the ADC. This way, you can compare the thermistor with the 10k reference resistor.

 

The reading on the ADC will be 1023 * T/(10k+T), where T is the resistance of the thermistor, independently of VDD.

Or rearranging, T = 10k * ADC / (1023 - ADC), the best way is to set up a lookup table for this, or better yet, for direct temperature reading.

 

But, even though you should not use the internal ref here, for completeness I will tell you that it would need to be configured separately, see the "VREF - Voltage Reference" chapter on the datasheet.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I haven't read all the code yet, but I have doubts on the first and second lines.
Is the pin parameter PIN3_bp?

   
    PORTA_pin_set_isc(PIN3_bm,PORT_ISC_INPUT_DISABLE_gc); //Disable  digital input buffer
    PORTA_set_pin_pull_mode(PIN3_bm, PORT_PULL_OFF);

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

First off I have to thank everyone that chimed in. I have found the answer that works for me.

Changing the Frequency did not help. I tried various frequency reductions. What seem to do the trick was setting the Vref. I used the follow line and it did the charm:

VREF.CTRLA = VREF_ADC0REFSEL_2V5_gc; //enable a Vref of 2.5

 

The software seems to work with 20mHz clock and a divider of 4.

 

I did check the  "VREF - Voltage Reference" from the "AVR® Microcontroller with Core Independent Peripherals and picoPower® Technology" that is referred to as "40001901B ATtiny417-817.pdf".

It has a small reference to VREF.CTRLA with some settings. I think it is amazing that there is no reference to it in any of the coding examples that I found including the example provided by microchip called "ADCBasicswithtinyAVR1-series.atsln".

 

As regard to the disable to the digital input buffer and the turning the the pull up resistor. These make sense, especially the pull up resistor. It can interfere with the 10K thermistor.

I have been doing real-time embedded programming for 20+ year and I have never turned to a community before. But, you guys have been great and I thank you again.

 

This has been for a polling the ADC. Next I will be doing the free running option. Wish me luck...

William

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0



 used the follow line and it did the charm:

VREF.CTRLA = VREF_ADC0REFSEL_2V5_gc; //enable a Vref of 2.5

 NO, you are still messing up...you need to set the reference to Vdd 

just set bit 4 of register CONTROLC for reliable readings

 

When in the dark remember-the future looks brighter than ever.   I look forward to being able to predict the future!

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

kabasan wrote:

 PORTA_set_pin_pull_mode(PIN3_bm, PORT_PULL_OFF);

 

As kabasan said, this is completly wrong. Please take a look at this App. note http://ww1.microchip.com/downloa... so you can understand the C-code and convention for the XMEGA series...

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Got it! I had a delay because of the power outages in California. 3 days, no power. bummer.

 

 The VDD setting worked and it makes sense to do so. I do not understand why the "ADCBasicswithtinyAVR1-series" example sets it to ADC_REFSEL_INTREF_gc and never sets the Vref. The actual flag that I use ADC_REFSEL_VDDREF_gc that is located in iotn417.h.Thank you all gain, you guys have been most helpful.

William

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Yeah thats true, these apps notes a little bit outdated, I suppose in everycase you need to set the VREF and ADC reference, something like this:

 

int8_t VREF_0_init()
{
	VREF_CTRLA = VREF_ADC0REFSEL_1V1_gc /*Voltage ref. at 1.1*/
				| VREF_DAC0REFSEL_0V55_gc;
	VREF_CTRLB = 1 << VREF_ADC0REFEN_bp
				| 0 << VREF_DAC0REFEN_bp;
	
	return 0;
}

if you opened the io417.h, then I suppose you would find a list of ADC reference options, it should be somthing like this:

 

/* ADC0 reference select select */
typedef enum VREF_ADC0REFSEL_enum
{
    VREF_ADC0REFSEL_0V55_gc = (0x00<<4),  /* Voltage reference at 0.55V */
    VREF_ADC0REFSEL_1V1_gc = (0x01<<4),  /* Voltage reference at 1.1V */
    VREF_ADC0REFSEL_2V5_gc = (0x02<<4),  /* Voltage reference at 2.5V */
    VREF_ADC0REFSEL_4V34_gc = (0x03<<4),  /* Voltage reference at 4.34V */
    VREF_ADC0REFSEL_1V5_gc = (0x04<<4),  /* Voltage reference at 1.5V */
} VREF_ADC0REFSEL_t;

in the datasheet Page 359, it says that if the VREF is left without being set, then the default VREF is the internal reference:

 

" onfigure a voltage reference by writing to the Reference Selection bit (REFSEL) in the Control Cregister (ADC.CTRLC). Default is the internal Voltage Reference of the device (VREF, asconfigured there). "