Forum Rule: Always post complete source code & details to reproduce any issue!
Results 1 to 16 of 16

Thread: DAC/ADC reference inconsistency

  1. #1
    Junior Member
    Join Date
    Jan 2016
    Posts
    11

    DAC/ADC reference inconsistency

    While the code the reference can generically be set as "internal" or "external", only the ADC follows this setting; the DAC (as a result) will be use either the internal reference, either the 3.3V LDO (which may be an external "reference" - not really as it is an LDO - but it is not THE external reference - AREF). Obviously, this is a bug and needs to be addressed. Of course, it would be even better having the ability to set the references independently (ADC and DAC).

    1. Any plans to fix this error?
    2. What is the work around this issue?

    Thanks!

  2. #2
    Senior Member
    Join Date
    Feb 2013
    Posts
    533
    Quote Originally Posted by Black Mamba View Post
    While the code the reference can generically be set as "internal" or "external", only the ADC follows this setting; the DAC (as a result) will be use either the internal reference, either the 3.3V LDO (which may be an external "reference" - not really as it is an LDO - but it is not THE external reference - AREF). Obviously, this is a bug and needs to be addressed. Of course, it would be even better having the ability to set the references independently (ADC and DAC).

    1. Any plans to fix this error?
    2. What is the work around this issue?

    Thanks!
    Not sure I'd call that an error, VDDA *is* a "supply" input; but yeah, that's somewhat confusing. AFAICS, that's the expected behaviour:

    The DAC reference can be selected to be VDDA or the voltage output of the VREF module (VREF_OUT)
    ... but not VREFH ("AREF").

    Looking at the schematic, there's no neat workaround. I suppose you could desolder the ferrite and 470R resistor and supply VDDA from some separate / clean(er) supply; possibly via the AREF pin if you put a 0 ohm resistor instead of the 470R.

  3. #3
    Junior Member
    Join Date
    Jan 2016
    Posts
    11
    Quote Originally Posted by mxxx View Post
    Not sure I'd call that an error, VDDA *is* a "supply" input; but yeah, that's somewhat confusing. AFAICS, that's the expected behaviour:

    ... but not VREFH ("AREF").

    Looking at the schematic, there's no neat workaround. I suppose you could desolder the ferrite and 470R resistor and supply VDDA from some separate / clean(er) supply; possibly via the AREF pin if you put a 0 ohm resistor instead of the 470R.
    Thanks mxxx...

    That is still an error because the chip uses a non-documented reference when it is configured as "external". The references are still toggled but not to the same rails.

    Regardless if it can be considered an implementation error (as I would) or not, I am waiting for Paul's feedback; he replied to me earlier:

    "Yes. The workaround is to write to the hardware registers which control these things."

    and

    "I write detailed tech answers on the forum, so the info becomes a searchable public knowledge base."...

    Thanks in advance, Paul !

  4. #4
    Senior Member
    Join Date
    Feb 2013
    Posts
    533
    Why, I'm pretty sure Paul knows more about it than I do. That said, the quote above is taken from the MK20 datasheet * ; on that basis it's not clear to me what the "non-documented reference" might be? when set to external, the DAC uses VDDA, as documented in the datasheet, which happens to be 3v3.

    The somewhat confusing thing is that the same variable ("analog_reference_internal") is used in analog.c for both analogWriteDAC0() and analogReference(), though "external" (analog_reference_internal = 0) means two different things (VDDA resp. VREFH). that's fixable no problem, but it won't make the DAC track AREF.

    note that's re MK20. teensy LS is different (in which case "The DAC reference can be selected to be VDDA or VREFH.")

    * more verbose (from the MK20 reference manual):
    3.7.3.3.
    For this device VREF_OUT and VDDA are selectable as the DAC reference.
    VREF_OUT is connected to the DACREF_1 input and VDDA is connected to the
    DACREF_2 input. Use DACx_C0[DACRFS] control bit to select between these two
    options.

  5. #5
    Senior Member
    Join Date
    Feb 2013
    Posts
    533
    ps. reading more closely, I realize you weren't all that much concerned about the DAC not tracking AREF. (sorry)

    to make things work independently, the workaround i suppose would be to edit analogWriteDAC() (so it ignores any reference stuff) and set the reference manually. for example

  6. #6
    Junior Member
    Join Date
    Jan 2016
    Posts
    11
    Thanks, mxxx!

    Your code is way above my current level - when I grow up I want to be like you :-)...

    Actually I do care about the ADC and DAC following the same reference - namely the AREF - for better accuracy. I was expecting by setting the reference external to connect the DAC to the same external reference but - as it happens - the DAC reference is either internal, either the 3.3V rail.

    Thus, it would be OK if both DAC and ADC could be set by the same switch to use the same references (INT or EXT) or (better because of the increased flexibility) to have separate switches so the references can be set independently for DAC and ADC. Either way works for me... but the current one.

    In my case, I set the external reference at 2.5V and I was quite surprised to see the DAC voltage hitting 3.3V.

  7. #7
    Senior Member
    Join Date
    Feb 2013
    Posts
    533
    Quote Originally Posted by Black Mamba View Post
    Thanks, mxxx!

    Your code is way above my current level - when I grow up I want to be like you :-)...
    it's Paul's code ...


    Quote Originally Posted by Black Mamba View Post
    Actually I do care about the ADC and DAC following the same reference - namely the AREF - for better accuracy. I was expecting by setting the reference external to connect the DAC to the same external reference but - as it happens - the DAC reference is either internal, either the 3.3V rail.

    Thus, it would be OK if both DAC and ADC could be set by the same switch to use the same references (INT or EXT) or (better because of the increased flexibility) to have separate switches so the references can be set independently for DAC and ADC. Either way works for me... but the current one.

    In my case, I set the external reference at 2.5V and I was quite surprised to see the DAC voltage hitting 3.3V.
    i see. well, as noted above, my understanding is that's not the way it (MK20) works. you can set them independently by bypassing the code in analog.c, but "EXTERNAL" means AREF for the ADC, and VDDA for the DAC; with VDDA tied to VOUT33 (in this case). if you search the forum, you'll find a couple of threads with people wondering about the same thing (why won't the DAC track AREF?)

    what is it that you want to do? if you want/need better accuracy, i'd suggest using an external DAC, reference and so on?

  8. #8
    Junior Member
    Join Date
    Jan 2016
    Posts
    11
    Well, I need to scale the DAC to an accurate 2.5V, without sacrificing the resolution. I already built my PCB and I am unwilling to change it to add components. Besides, it doesn't even make sense; for what I need (speed-wise) a plain Arduino would do but I selected Teensy mostly because it embeds a real DAC... well - faster IOs too.

    Of course, I suppose I can live with fewer steps (about 3.1k, which is not so bad), it is just that it bugs me - "does not compute"; If I could fix it, I would.

  9. #9
    Senior Member
    Join Date
    Feb 2013
    Posts
    533
    Quote Originally Posted by Black Mamba View Post
    Well, I need to scale the DAC to an accurate 2.5V, without sacrificing the resolution. I already built my PCB and I am unwilling to change it to add components. Besides, it doesn't even make sense; for what I need (speed-wise) a plain Arduino would do but I selected Teensy mostly because it embeds a real DAC... well - faster IOs too.
    i see. can't you try with a teensy LC ? i've never tried this but, as mentioned, in that case it should work: "The DAC reference can be selected to be VDDA or VREFH."

  10. #10
    Junior Member
    Join Date
    May 2016
    Posts
    6
    Hi Paul,

    I am having the same problem...we connected external reference 2.5V to AREF, and this works for the ADC, but not the DAC...The DAC is still using 3.3V.
    Please let me know if we are doing something wrong or how can we setuup the ADC and DAC to use the same value that is connected at AREF?
    Thanks...Ness

    Sample code below:

    int ledPin = 13; // select the pin for the LED
    // Pin 13: Arduino has an LED connected on pin 13
    // Pin 11: Teensy 2.0 has the LED on pin 11
    // Pin 6: Teensy++ 2.0 has the LED on pin 6
    // Pin 13: Teensy 3.0 has the LED on pin 13
    int ADC_Pin = A0; // select the A0 input pin 14 for Voltage Measurement
    int DAC_Pin = A14; //use A14 as Analog Out (DAC)
    int i=0; //global loop counter
    void setup()
    {

    Serial.begin(9600);
    pinMode(ledPin, OUTPUT); //Pin 13 Led On/Off
    pinMode(ADC_Pin, INPUT); //Pin 14 = A0 used for Voltage Input
    analogReadResolution(16); //set resolution to 13 bits usable
    analogReference(EXTERNAL); // use AREF for reference voltage (2.5V reference is used)
    analogWriteResolution(12); //set resolution to 12 bit resolution - max for DAC
    analogWrite(DAC_Pin, 0); //default DAC (Iset) = 0

    }

    void loop()
    {

    int DAC_ValueBits = 0;
    float ADC_Measurement = 0.0;
    float ValueInVolts = 0.0;
    Serial.print ("Iteration = ");
    Serial.println (i);

    ADC_Measurement = analogRead(ADC_Pin); // read the value from the AD0 Pin
    ValueInVolts = ADC_Measurement * (2.5/65535); // BitsRead * (VmeasMax/BitsMax) 16 bits = FFFF 65535 and Vmax = external Vref = 2.5V
    Serial.print ("Measure and Display Value in Bits = ");
    Serial.println (ADC_Measurement);
    Serial.print ("Measure and Display Value in Volts = ");
    Serial.println (ValueInVolts);

    DAC_ValueBits = (int)(1.0 * (4096/2.5)); //convert desired volts to bist per 4096 bits (12bit) for 2.5V max (external reference is 2.5V)
    analogWrite(DAC_Pin, DAC_ValueBits); //set DAC
    Serial.println ("Setting DAC output to 1V with 2.5V external reference");
    Serial.print ("\n\tDAC Value in Bits = ");
    Serial.println (DAC_ValueBits);
    analogWrite(DAC_Pin, DAC_ValueBits);


    }

  11. #11
    Senior Member PaulStoffregen's Avatar
    Join Date
    Nov 2012
    Posts
    18,969
    Quote Originally Posted by ness View Post
    Serial.println ("Setting DAC output to 1V with 2.5V external reference");
    Unfortunately, the DAC can not use the AREF voltage. This is a hardware limitation inside the chip, so there is no workaround.

    All the hardware details are in the reference manual. Here's the DAC's block diagram, from page 730:

    Click image for larger version. 

Name:	mk20dx256_figure33-1.png 
Views:	199 
Size:	46.3 KB 
ID:	7259
    (click for full size)

    As you can see, the DAC has only 2 options, DACREF_2 and DACREF_1. The connection of these 2 internal signals is documented on page 107:

    3.7.3.3 12-bit DAC Reference

    For this device VREF_OUT and VDDA are selectable as the DAC reference.
    VREF_OUT is connected to the DACREF_1 input and VDDA is connected to the
    DACREF_2 input. Use DACx_C0[DACRFS] control bit to select between these two
    options.

    Be aware that if the DAC and ADC use the VREF_OUT reference simultaneously, some
    degradation of ADC accuracy is to be expected due to DAC switching.
    The chip simply can't use the AREF pin which connects to VREFH. See the schematic for details.

    Your only options are 3.3V VDDA or 1.2V internal reference, which are selected by analogReference(EXTERNAL) and analogReference(INTERNAL).

    For the ADC, analogReference(EXTERNAL) uses VREFH, which "defaults" to 3.3V due to the 470 ohm resistor. If you apply a reference voltage to AREF, it is used by the ADC, but not by the DAC. Unfortunately, this is simply the way Freescale made the chip, so there's nothing the Teensyduino software can do to give you DAC output based on your 2.5V reference.

  12. #12
    Junior Member
    Join Date
    Nov 2016
    Posts
    10
    Quote Originally Posted by PaulStoffregen View Post
    Unfortunately, the DAC can not use the AREF voltage. This is a hardware limitation inside the chip, so there is no workaround.

    All the hardware details are in the reference manual. Here's the DAC's block diagram, from page 730:

    Click image for larger version. 

Name:	mk20dx256_figure33-1.png 
Views:	199 
Size:	46.3 KB 
ID:	7259
    (click for full size)

    As you can see, the DAC has only 2 options, DACREF_2 and DACREF_1. The connection of these 2 internal signals is documented on page 107:



    The chip simply can't use the AREF pin which connects to VREFH. See the schematic for details.

    Your only options are 3.3V VDDA or 1.2V internal reference, which are selected by analogReference(EXTERNAL) and analogReference(INTERNAL).

    For the ADC, analogReference(EXTERNAL) uses VREFH, which "defaults" to 3.3V due to the 470 ohm resistor. If you apply a reference voltage to AREF, it is used by the ADC, but not by the DAC. Unfortunately, this is simply the way Freescale made the chip, so there's nothing the Teensyduino software can do to give you DAC output based on your 2.5V reference.
    Hi Paul,

    I came across this issue with my Teensy 3.5, I was pretty shocked when I realized that I cant use my external 2.048V reference for the DAC. Absolutely didn't expect that.

    However, I'm not giving up (yet). I was digging in the datasheet and the reference manual of the MCU and according to my understanding it should be possible to tie the VREF_OUT pin which seems to be the internal bandgap reference to any desired level (below VCC of course).

    This is the block diagram of the 1,2V reference which is at VREF_OUT, if I'm correct:

    Click image for larger version. 

Name:	vref.PNG 
Views:	20 
Size:	37.5 KB 
ID:	15159

    In https://www.nxp.com/docs/en/referenc...4M120SF5RM.pdf on page 942 it says:

    "The reference voltage signal is output on a dedicated output pin when the VREF is enabled."

    and:

    38.1.3 Modes of Operation

    ...

    NOTE on page 943:
    When the VREF output buffer is disabled, the status of the
    VREF_OUT signal is high-impedence.
    So wouldn't be it possible to just connect the 2.048V reference to the VREF_OUT pin, when the buffer is turned off and therefore high impedance?

    Anyway, it really was a bummer when I realized that out of the box the AREF is only usable for the ADC, you really might want to make a note on your website regarding this.
    Yes it was my fault to not try it on a breadboard first before making a PCB but I just really didn't expect that at all (I mean, WHY did they do it this way...).

    Thanks!

  13. #13
    Senior Member+ Theremingenieur's Avatar
    Join Date
    Feb 2014
    Location
    Colmar, France
    Posts
    2,114
    And why not simply use the internal bandgap reference and add a rail-to-rail op amp at the output to scale the voltage by 2048/1200? With that, you'd even save by dropping your external reference.

  14. #14
    Junior Member
    Join Date
    Nov 2016
    Posts
    10
    Quote Originally Posted by Theremingenieur View Post
    And why not simply use the internal bandgap reference and add a rail-to-rail op amp at the output to scale the voltage by 2048/1200? With that, you'd even save by dropping your external reference.
    because that would make an even higher gain of the opamp necessary, which is quite high with 2.048V VREF already.
    That raises the minimum output of the DAC you could get to about 50-80mV which is not good for a Lab PSU where you want to regulate your output all the way down zero or at least near zero.

    Calculate the current of 80mV @ 100mOhm (short). Poor series pass transistor...

  15. #15
    Senior Member+ Theremingenieur's Avatar
    Join Date
    Feb 2014
    Location
    Colmar, France
    Posts
    2,114
    Have a look at the MAX44267. It can even output negative voltages with only an unipolar positive power supply. I used it in synth projects to generate negative control voltages without the need of a bipolar supply.

  16. #16
    Junior Member
    Join Date
    Nov 2016
    Posts
    10
    Quote Originally Posted by Theremingenieur View Post
    Have a look at the MAX44267. It can even output negative voltages with only an unipolar positive power supply. I used it in synth projects to generate negative control voltages without the need of a bipolar supply.
    Thanks, good looking device, but the opamp is not the issue if I'm not misleaded.
    I use the OPA2197 which can go all the way down to a few mV with single supply voltage, which is good enough.

    The problem is the DAC, which outputs at least around 5mV or so, which get amplified by the opamp by a gain of 10-20, depending on the VREF (which is very low on the Teensy DAC) so I get at least 50-100mV output.

    I guess I'd have to create an offset at the opamp to shift the voltage down about 50mV but I haven't done this yet, no idea how this is accomplished, while keeping high precision.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •