Arduino Zero DAC (Analog Output) Cutoff Below the Rail Voltage

I recently purchased a few Arduino Zero boards for the first time because I wanted a Digital to Analog Converter (DAC; i.e. and Analog Output) and the Arduino Due isn't in stock. Based on [1], my understanding is that the output range on the DAC should be 0-3.3V (i.e. rail-to-rail). Unfortunately, when I try to run a simple sketch to output an analog sine wave, the Zero appears to cut-off the voltage at 2.3V.

To be more specific, I am driving a red LED in series with a 10kOhm resistor from the A0 output on the Zero board. The board is powered through the programming USB (I also tried powering the board via Vin with a 5V power supply with no change in behavior). In the sketch, I configure A0 as an output, set the resolution to 10-bits, and then use "analogWrite" to update the value on A0 as a 10-bit integer (see the attached sketch). I've looked at a few examples for the DAC on the Zero and don't see any other functions being used to configure or control the DAC. I have tried multiple Zero boards as well as I have simply connected the A0 pin directly to an oscilloscope (i.e. no LED) to make sure I am not overloading the DAC. In all cases, the output on the oscilloscope is the bottom half of a nice clean sine wave that is cutoff at 2.3V.

I'm hoping I've made a simple rookie mistake and and that there is a simple fix.

  1. Arduino Zero DAC limitations? - Arduino Zero - Arduino Forum

AnalogOut-Zero.ino (1.88 KB)

Hi jessewp,

remove this line from your code

  pinMode(A0, OUTPUT);        //Set A0 as a DAC

otherwise pin A0 will be set as a digital output and this interferes with the dac output

Marco

Thank you Sulimarco, removing the "pinMode(A0, OUTPUT)" line fixed the problem.

This has been "rediscovered" on the SAMD21 based Adafruit Circuit Playground Express (CPX) board - see discussion on Adafruit Forums: Circuit Playground and Circuit Playground Express: A0 on CPX about a sine wave capped at 2.25V.

It seems a bit odd to me. I can see pinMode() is documented as being for digital use but it doesn't mention that it shouldn't be used for analogue pins and doesn't describe what happens if it is used. There's also no compile time or run time error or warning, those would be useful given that 1) pinMode is not specific with its naming about the type of pin and 2) the behaviour here is so strange.

I'd expect the API to aim to prevent damage to peripherals and to help the programmer to avoid dangerous bugs as much as possible. For a pin which can either be an input or an output, the safest default is a high impedence input until the programmer explicitly enables it as an output.

Is the API here being an overly thin veneer and being too transparent to the original AVR hardware with that approach being continued to hardware that varies?

It seems a bit odd to me

If you look at Fig. 23-2 in the SamD datasheet it is quite clear that a pin must not be configured as an output when using the analog functions. (see attachement)

I'd expect the API to aim to prevent damage to peripherals and to help the programmer to avoid dangerous bugs as much as possible

There is no damage to the peripherals, anyway I agree that the Arduino API could set the pin in the right way automatically.

For a pin which can either be an input or an output, the safest default is a high impedence input until the programmer explicitly enables it as an output

That is.
What happened here was that the programmer explicitly and wrongly set the pin as an output.

Marco