Analog Output (DAC) feature

Today I needed to use the DAC Analog Output feature on my STM32F4. This code didn’t work for me…

https://www.ghielectronics.com/docs/10/analog-outputs

When I used 3.3 for the Scale and wrote 0.5 and did not see 1.65, or even anything close.

I changed the scale to 1 and tried again, this time I got 1.6625 (I have a cheap meter, so close enough).

Further testing revealed a Scale of 2 and a Write value of 0.5 has the same effect as a Scale of 1 and a Write value of 1.

Does this seem normal? Are the instructions out of date?

With 10 bit (Precision property of the AnalogInput/Output class)

you can read/write values within the range of 2 to the power of 10 which is 0-1023. That range corresponds to voltage values between 0 and 3.3.

So if you want to use values from 0 to 3.3 in your code you need to use scale value of 1024 / 3.3

I am taking that back. I have just looked at the PK code. Here how it works

Write method expects the values after applying the scale to be in the range of 0 to 1

so if you want to use Write method with [0…3.3] you will need to use Scale = 1/3.3;

With Scale = 1/3.3

Write(3.3) will measure 3.3
Write(1.65) will measure 1.65

With Scale = 1

Write(1) will measure 3.3
Write(0.5) will measure 1.65

With Scale = 1/2

Write(2) will measure 3.3
Write(1) will measure 1.65

Should that article be updated? GHI is the BEST resource I’ve found for netMF. So when I find something in a doc that might be off I bring it up in the hope that I might save the next guy a few minutes.

The example says…

output.Scale = 3.3; //Set scale to maximum voltage offset
output.Write(0.5); //Write half of the maximum

Maybe it should say…

output.Scale = 1; //Set scale to 1:1 of the maximum voltage (3.3v)
output.Write(0.5); //Delivers 50% or 1.65v 

Yes, that tutorial needs a revision. Just for you reference, here is what Write method looks like in PK:

/// <summary>
/// Writes a level to the AnalogOutput, eventually modified by the scale and offset following the formula raw = value * scale + offset.
/// <param name="level">The value to be used.</param>
/// </summary>
public void Write(double level)
{
    if (m_scale != 1.0) level *= m_scale;
    if (m_offset != 0.0)  level += m_offset;
    if (level < 0) level = 0; // avoid overflow
    if (level > 1) level = 1;
    WriteRaw((int)(level * ((1 << m_precision) - 1)));
}
1 Like