# PWM as DAC

With the new revision of Replicape, I had to do some voodoo with the electronics in order to reach the new target price. Perhaps the most important change was the removal of the Digital to Analog Converter (DAC) that was used for setting the current limit of the stepper motor controllers digitally. Instead, five of the sixteen channels on the PWM chip (PCA9685) was dedicated to setting the current limit. This eliminated a chip from the board, saving both BOM costs, board space, reduced production costs and freed a single, but important pin, SPI CS0. This blog post explains some of the trade-offs involved in making this decision.

**Short summary of parameters**

– PWM frequency: 10 KHz (PCA9685 is limited to 1 KHz, see below)

– First order low pass filter with R = 10K, C = 47uF

– Corner frequency: fc = 3.38Hz

– Peak to peak ripple voltage: 0.53 mV

– DAC resolution step: 0.61 mV

– DAC max voltage: 2.5V

**Why is it necessary?**

The DAC chip used in Replicape rev A4A was $1.75 in volumes of 500. Removing this cost does seem like a big deal, but when the total BOM cost is $30-40, it makes up a large percentage of the manufacturing costs. But what are the downsides to eliminating this component? Will it give a worse result in any way? Probably not.

**What is the challenge here?**

Well, in summary; to get a programmable bias voltage between 0 and 2.5 V with enough steps (4096 is plenty) and with a low enough ripple voltage (5.3mV should suffice) at a low costÂ (the price of 5 resistors and 5 capacitors).

**Why don’t you use trim pots?**

Trim pot’s are cheap, that’s it. The downside is that the end user will need physical access to the controller board to change it and for 3D-printer manufacturers, they will need to calibrate the current during assembly. This increases cost during assembly for the manufacturer and makes it less use friendly for the end user. An important aspect about Replicape is that physical access should not be necessary once the board is installed.

**The electro-pop**

The PWM chip has a VCC of 5V while the AIN voltage is needs 0-2.5 V. For this reason, a voltage divider is added followed by a first order low pass RC filter.The voltage divider is not really necessary since the AIN input can handle up to 5V with anything above 2.5V being treated as full current. It might be eliminated in a new revision (at the expense of only having half the resolution). Here is the schematic for the filter, the input is a PWM pulse, the output is a bias voltage.

**Possible attainable DAC resolution**

The PCA9685 has a 12 bit resolution. Some quick front of the blog calculations makes the theoretically attainable resolution

[latex]V_{step} = 2.5V/4096 = 0.61 mV[/latex].

This is more than enough. Typically you will change the current limit in steps of 0.1 V, but having a good resolution minimizes the difference between what you want and what you get without pulling out a calculator.

An interesting observation will be to try and measure the noise level on this input pin and see if the noise level on the pin or on the GND plane of the board will be below that.

Conversely, and even if one is not interested in having the option to use every bit of the resolution, having any ripple on the AIN pin will manifest itself in variations in the current cut-off which again will increase the audible level from the steppers.

**PWM frequency**

The frequency/period of the PWM outputs do not really matter for the operation (see the appendix for why). Or rather, it matters, but not for producing a bias voltage. Instead it is critical due to the amount of ripple voltage that is tolerable. To get a point of reference for what is tolerable, in the datasheet for TMC2100, there is a small section on driving the analogue current control from a filtered PWM circuit. In the data sheet, a PWM frequency of “well above 10 kHz” is recommended together with a first order filter with R = 22k and C = 1uF. This should give a corner frequency of fc = 7 Hz, equivalent with a time constant of 22 ms (“several milliseconds” as specified in the data sheet). With the values suggested, the steady state ripple voltage on the input pin is 2.8 mV. This is still an order of magnitude above what is the PWM resolution limit.

**Yeah Bill, but why not simply increase the PWM frequency?**

Normally, I would say go for it, but on Replicape, the PWM chip has multiple uses (It is also very limited, see below). It is also used for controlling the heaters on the board. Since MOSFETs dissipates more heat in the transition phases than in the steady states (on/off), simply increasing the PWM frequency will increase the total amount of heat coming from the MOSFETs. How much will be the topic of a different blog post!

**Lowering cut-off frequency**

An alternative to increasing the PWM frequency is lowering the cut-off/corner frequency. Since the actual cut-off frequency is not critical, it can be a good idea to spend some time finding values on the R and C that can also be used other places on the board to save BOM lines. In the case of Replicape, 10 K and 4.7 uF were used, giving a cut-off frequency of 3.4 Hz and a Vpp ripple of 1.3 mV. This is still above the resolution, but gives very nice (and cheap) R and C values.

**Bandwidth considerations**

Normally, when using a DAC for any application, you are also interested in the bandwidth that the DAC can provide. However, in this case, we are only interested in setting a comparator voltage, which does not have to change very rapidly. That’s why we can get away with having a low cut-off 1st order filter. The DAC has a bandwith of 3.38 Hz, if you need to change the stepper current more often than 3 times pr. second, then dude, you are doing it wrong đŸ™‚

**What are the downsides?**

The only real downside I can think of is the increased heat dissipation that will come from the increased switching frequency of the MOSFETs. Also, the previous revision of Replicape used the same PWM chip for also controlling servos. This locked the PWM frequency to 100 Hz (!) which is the period needed for servos. Instead the two servo ports available now are controlled by PWM pins on the SoC. There is always an alternative to add a second order to the filter and then decrease the frequency alternatively tolerate a higher ripple voltage. There might not be much increase in the audible level anyways.

### Second order filter

I’ve later found out a couple of things about the PCA9685 PWM chip. First of all, the maximum frequency attainable is around 1 KHz according to the data sheet (but I’ve measured it to 1.76 KHz). Furthermore, the accuracy of the frequency is not very good. I’ve seen differences of 15% between the frequency given and the frequency it outputs . This is not critical for controlling heaters or making bias voltages, but could prove fatal in other applications such as controlling servos etc.

The upper limit of 1 KHz means that there will likely be a need for a second (equal) filter, making the drop-off -40dB/decade. With a second order RC low pass filter, the peak-to-peak voltage drops to below 0.02 mV. I did a quick bread board implementation of this and with my crappy Oscilloscope measured the ripple voltage to 0.8 mV which is likely the noise floor of the oscilloscope with 256 times averaging. The good news is that the voltage divider can be directly substituted for a second RC low pass filter by replacing R1 with 10 K, R2 with a 4.7uF capacitor.

**Comparing simulation and a physical implementation**

In order to compare the calculated results with a physical implementation, the frequency was lowered to 100 Hz to increase the ripple voltage to something measurable. The V in is 3.3V since this is the Vcc on the PWM circuit on Replicape rev A4A.

The following photo shows a simulation of a PWM (blue) signal, its fourier series implementation (green) and the ripple voltage (red) in the time domain. Also shown is a second order low pass RC filter gain and phase shift. The two RC filters are equal and having the same parameters as previously. The calculated ripple voltage is here 5.0 mV peak to peak. An interesting observation is the 180 degree phase shift

For comparison, here is a picture of the same implementation in hardware. The ripple voltage is here around 10 mV as seen on the oscilloscope.

There is a small difference between the simulated results and the hardware implementation. Looking at the datasheet for the capacitors, one reason might be the bias voltage that lowers the capacitance with about 25% at 3.3V. Implementing this is in the formula gives a Vpp ripple of 9.5 mV which is pretty close to the calculated results.

### Appendix: get your math did

Filtering a PWM signal through a low pass filter will give an analogue bias voltage proportional to the duty cycle of the PWM. This is the wanted signal. In addition to this, there will be an “unwanted” component, a ripple voltage appearing on top of the bias voltage. The appendix shows the calculations for why this is true and also the steps for calculating the ripple voltage.

What we are interested in is the average value of the function, and also looking at the ripple voltage resulting from the chosen filter. 12th grade calculus comes to the rescue in the form of integration! PWM is just a train of pulses, so by integrating over time, the value becomes a constant scaled by the pulse of the width. Look:

A straight forward way to define this signal mathematically is with the use of a Heaviside step function:

[latex]f(t) = K(1-H(t-D))[/latex]

where K is a scale factor, (2.5 V in this case after the voltage divier), D is the “on” time and [latex]H(t)[/latex] is the heaviside delta function which can be written as

[latex]H(t)=\begin{cases}1, & \text{if $t<0$}.\\ 0, & \text{otherwise}.\end{cases}[/latex]

This function is defined in the interval

[latex]\left[0, T\right][/latex]

However, looking at the steady state PWM signal, it can be considerered a piecewise continuous function on [0, T]. Using fourier series, the square wave can be decomposed in to a series of complex exponentials. The normal definition of the fourier series is

[latex]f(x) = a_0+\sum_{n=1}^{\infty}a_n cos(nx)+\sum_{n=1}^{\infty}b_n sin(nx)[/latex]

where

[latex]a_0 = \frac{1}{2\pi}\int_{-\pi}^{\pi} f(x) dx[/latex]

[latex]a_n = \frac{1}{\pi}\int_{-\pi}^{\pi} cos(n x)f(x) dx[/latex]

[latex]b_n = \frac{1}{\pi}\int_{-\pi}^{\pi} sin(n x)f(x) dx[/latex]

[latex]x \in [-\pi, \pi][/latex]

Jeezes, this is hairy! But right off the bat, we can eliminate the [latex]a_n[/latex] coefficients, since the function

is odd.

**Changing integration limits**

The interval on which this is defined is not ideal, instead we change the integration limits

to something a bit more manageable. A PWM signal is usually defined by a period and a duty cycle, so lets change the integration interval from

[latex]\left[-\pi, \pi\right][/latex] to [latex]\left[0, T\right][/latex]. We the have

[latex]x = \frac{2\pi t}{T}[/latex]

[latex]dx = \frac{2\pi dt}{T}[/latex]

We then have

[latex]f(t) = a_0+\sum_{n=1}^{\infty}b_n sin(\frac{2\pi nt}{T})[/latex]

where

[latex]a_0 = \frac{1}{T}\int_{0}^{T}f(t) dt[/latex]

[latex]b_n = \frac{2}{T}\int_{0}^{T}f(t) sin(\frac{2\pi nt}{T}) dt[/latex]

**Calculating the bias term**

Looking at the bias term, [latex]a_0[/latex] we have two peicewise continous functions which each can be integrated.

[latex]a_0 = \frac{1}{T}(\int_{0}^{D}1 dt + \int_{D}^{T}0 dt)[/latex]

[latex]a_0 = \frac{1}{T}(\int_{0}^{D}1 dt)[/latex]

[latex]a_0 = \frac{1}{T}(D-0)[/latex]

[latex]a_0 = \frac{D}{T}[/latex]

So, the bias term is simply the fraction of on-time in the period, which is what we wanted to show.

**Calculating the fourier coefficients**

To get the ripple voltage, wee need to know the fourier series coefficients

[latex]b_n = \frac{2}{T}\int_{0}^{T}f(t)sin(\frac{2\pi nt}{T}) dt[/latex]

Splitting this up into two integrals yields

[latex]b_n = \frac{2}{T}\int_{0}^{D}f(t)sin(\frac{2\pi nt}{T}) dt + \int_{D}^{T}f(t)sin(\frac{2n\pi t}{T}) dt[/latex]

The last term disappears since [latex]f(t) = 0[/latex]. The first term reduces to

[latex]b_n = \frac{2}{T}\int_{0}^{D}sin(\frac{2\pi nt}{T}) dt [/latex]

[latex]b_n = \frac{2}{T}\frac{T}{2\pi nt} sin(\frac{2\pi nt}{T})\bigg|_{0}^D [/latex]

[latex]b_n = \frac{1}{\pi n} (-cos(\frac{2\pi nD}{T})+cos(0))[/latex]

[latex]b_n = \frac{1}{\pi n}(1-cos(\frac{2\pi nD}{T})[/latex]

The full fourier series for a the PWM is therefore

[latex]f(t) = \frac{D}{T} +\sum_{n=1}^{\infty}\frac{1}{\pi n}(1-cos(\frac{2\pi nD}{T})) sin(\frac{2\pi nt}{T}) [/latex]

**50% duty cycle**

For a 50% duty cycle, [latex]D = \frac{T}{2}[/latex], so we have

[latex]a_0 = \frac{D}{2D} = \frac{1}{2}[/latex]

[latex]b_n = \frac{1}{\pi n}(1-cos(\frac{\pi nT}{T})[/latex]

[latex]b_n = \frac{1}{\pi n}(1-cos(\pi n))[/latex]

This evaluates to 0 for even n, so it can be simplified to

[latex]b_n = \frac{2}{\pi n}[/latex]

[latex]n = 1,3,5…[/latex]

So for a 50% duty cycle, we have

[latex]f(t) = \frac{1}{2}+\sum_{n=1}^{\infty}\frac{2}{\pi n} sin(\frac{2\pi nt}{T})[/latex]

for [latex]n = 1,3,5…[/latex]

**Calculating the ripple voltage**

So the b_n terms form an infinite sum, but after the first term there is a big fucking drop-off and

also, since this is filtered through a low pass filter, we can choose just one or or two of the terms and still get a pretty good

estimate.

The gain of a first order RC filter can be calculated as

[latex]G(\omega) = \frac{1}{\sqrt{1+(\omega R C)^2}}[/latex]

Plotting this in a Bode diagram yields the usual -20dB/decade roll-off that first order filters provide.

To find the ripple voltage for a low pass filter, we need to calculate the sum of the fourier series coefficients

[latex]V_{ripple} = \sum_{n=1}^{\infty}\frac{1}{\sqrt{1+(n \omega_0 R C)^2}} 2 \frac{2}{\pi n}[/latex]

where [latex]\omega_0 = 2 \pi f_0 = \frac{2\pi}{T}[/latex] is the angular frequency of the PWM signal, R is the resistance and C is the capacitance.

Simplifying yields

[latex]V_{ripple} = \sum_{n=1}^{\infty}\frac{4}{\pi n \sqrt{1+(n \omega_0 R C)^2}}[/latex]

Plugging the chosen values for R, C, and f and summing the first three coefficients will give a peak to peak ripple voltage of

[latex]V_{ripple} = \sum_{n=1}^{3}\frac{4}{\pi n \sqrt{1+(n 2\pi 10^4*4.7*10^{-6})^2}} = 5.4 mV[/latex]

Now the above calculations are somewhat crude in that they do not take the phase of the signal into account. Looking at a physical implementation

will show that the ripple voltage is 90 degrees shifted forward and has a triangle shape. Still it gives an indication of what to expect.

If you want a second-pass filter with divider, you can use R1=R3=5k, replace R2 with 4.7uF, and add R4=10k in parallel with C1. The resistor values are for 2.5V output.

Great! I wanted to do that until I found out that the iref input is 5V tolerable:)