Go Down

Topic: analogReference does not compile (Read 2207 times) previous topic - next topic

glovisol

Perhaps someone already mentioned this problem: with Arduino Zero analogReference() does not compile....Any suggestion?

AloyseTech

#1
Mar 29, 2016, 07:58 pm Last Edit: Mar 30, 2016, 11:32 am by AloyseTech
You have to use it with differents enums than other arduino :
  • AR_INTERNAL (2.2297V)
  • AR_EXTERNAL (AREF pin is the ref)
  • AR_INTERNAL1V0 (1.0V)
  • AR_INTERNAL1V65 (1.65V)
  • AR_DEFAULT (1.65V)


These is the analogReference() implementation :

Code: [Select]
void analogReference( eAnalogReference ulMode )
{
 syncADC();
 switch ( ulMode )
 {
   case AR_INTERNAL:
   case AR_INTERNAL2V23:
     ADC->INPUTCTRL.bit.GAIN = ADC_INPUTCTRL_GAIN_1X_Val;      // Gain Factor Selection
     ADC->REFCTRL.bit.REFSEL = ADC_REFCTRL_REFSEL_INTVCC0_Val; // 1/1.48 VDDANA = 1/1.48* 3V3 = 2.2297
     break;

   case AR_EXTERNAL:
     ADC->INPUTCTRL.bit.GAIN = ADC_INPUTCTRL_GAIN_1X_Val;      // Gain Factor Selection
     ADC->REFCTRL.bit.REFSEL = ADC_REFCTRL_REFSEL_AREFA_Val;
     break;

   case AR_INTERNAL1V0:
     ADC->INPUTCTRL.bit.GAIN = ADC_INPUTCTRL_GAIN_1X_Val;      // Gain Factor Selection
     ADC->REFCTRL.bit.REFSEL = ADC_REFCTRL_REFSEL_INT1V_Val;   // 1.0V voltage reference
     break;

   case AR_INTERNAL1V65:
     ADC->INPUTCTRL.bit.GAIN = ADC_INPUTCTRL_GAIN_1X_Val;      // Gain Factor Selection
     ADC->REFCTRL.bit.REFSEL = ADC_REFCTRL_REFSEL_INTVCC1_Val; // 1/2 VDDANA = 0.5* 3V3 = 1.65V
     break;

   case AR_DEFAULT:
   default:
     ADC->INPUTCTRL.bit.GAIN = ADC_INPUTCTRL_GAIN_DIV2_Val;
     ADC->REFCTRL.bit.REFSEL = ADC_REFCTRL_REFSEL_INTVCC1_Val; // 1/2 VDDANA = 0.5* 3V3 = 1.65V
     break;
 }
}

oqibidipo

You have to use it with different MACRO than other arduino :
They're actually enums, not macros.

glovisol

Hi Aloyse,

Thanks a lot. Looking at the implementation I see some Gain Multipliers are admitted: e.g.: 1X and DIV2.

My question is: can other multipiers be used? For instance a standard industrial voltage range is:

0 to 2.5 V.

So to have a multiplier which would implement AR_INTERNAL = 2.5 V would be very useful, because an external ref. generator could be eliminated, at least for preliminary testing.

AloyseTech

They're actually enums, not macros.
Tht's right, I edited the post :)

Glovisol : check the datasheet for possible value of GAIN register and RESSEL register. RESSEL let you choose the base reference voltage and GAIN the multiplier (/2, X1, X2, X4, X8 and X16).
You will only be able to get 2.5V reference with an external voltage I guess.

glovisol

#5
Mar 30, 2016, 06:15 pm Last Edit: Mar 30, 2016, 06:33 pm by glovisol
Hi Aloyse,

The following enum compiles and should work and produce a 2V internal voltage reference, which could be a fair compromise near to 2.5 V.

    ADC->INPUTCTRL.bit.GAIN = ADC_INPUTCTRL_GAIN_2X_Val;      // Gain Factor Selection
    ADC->REFCTRL.bit.REFSEL = ADC_REFCTRL_REFSEL_INT1V_Val;   // 2.0V voltage reference

Furthermore the 1.1 V reference is a high stability precision bandgap reference. According to Table 36.35 variation over wide temp range is +/- 20 mV. The 2.2 V reference would have a tolerance of +/- 40 mV, or +/- 2%, which is a remarkable level of precision.

This could be further refined by linear interpolation of data stored in the chip, by applying data of table 36.38 in reverse, e.g. using data of an ext. temp sensor to correct bandgap voltage, but requires further hard work.

AloyseTech

If exactly 2.5V is not needed, you could use the AR_INTERNAL enum, which is supposed to give around 2.23V

glovisol

Hi Aloise,

I sent you a post which was in error and I deleted it. You are right AR_2V29 can be used for testing before applying AR_EXTERNAL 2.5 V

Apologies,

glovisol

glovisol

Hi, Aloyse Tech,

I tested your long enumerations and they work! See  the PWM change posts. Thanks & my compliments to you.

glovisol

Go Up