Many CNC spindles, VFD interfaces, and industrial controllers accept a 0-10 V analog setpoint. An Arduino or GRBL controller typically provides a 0-5 V PWM output. The conversion described here maps PWM duty cycle to a stable 0-10 V voltage, with component choices that remain reliable under real wiring conditions such as long cable runs and electrically noisy environments.
Part 1: RC low-pass design (PWM to DC)
PWM average voltage
Let the PWM amplitude be \(V_\text{PWM}\) and the duty cycle be \(D\in[0\ \ldots\ 1]\). The time average of the PWM waveform is
\[ V_\text{DC}=D\cdot V_\text{PWM}. \]
The RC filter preserves this average while attenuating the ripple introduced by PWM switching.
PWM frequency is an input parameter for the filter design. Typical cases are approximately 490 Hz for Arduino analogWrite() on an Uno, approximately 980 Hz on some Uno pins, and approximately 1 kHz for many GRBL spindle PWM configurations.
RC transfer function and magnitude
A first-order RC low-pass filter consists of a series resistor \(R\) and a capacitor \(C\) to ground. Its transfer function is
\[ H(j\omega)=\frac{1}{1+j\omega RC}. \]
\(H(j\omega)\) is the filter’s transfer function, defined as the complex ratio \(V_\text{out}(j\omega)/V_\text{in}(j\omega)\). As a function of angular frequency \(\omega\), it describes both the amplitude response (attenuation via \(|H|\)) and the phase response (phase shift via \(\arg(H)\)). In this application it provides a quantitative way to determine how effectively the RC network suppresses the PWM switching components and their harmonics, while leaving the DC component that corresponds to the duty-cycle setpoint essentially unchanged.
The magnitude of the RC transfer function is derived as
\[ |H(j\omega)|=\frac{1}{|1+j\omega RC|}=\frac{1}{\sqrt{1+(\omega RC)^2}}. \]
Now the cutoff frequency is defined as
\[ f_c=\frac{1}{2\pi RC}. \]
With \(\omega=2\pi f\), the magnitude can be written as
\[ |H(f)|=\frac{1}{\sqrt{1+\left(\frac{f}{f_c}\right)^2}}. \]
For \(f\gg f_c\), the attenuation is approximately
\[ |H(f)|\approx \frac{f_c}{f}. \]
This approximation is convenient for estimating ripple suppression at \(f_\text{PWM}\).
Two cascaded RC stages
A single RC stage can be sufficient at higher PWM frequencies, but two cascaded stages are usually preferable for 490 Hz to 1 kHz PWM because attenuation multiplies:
\[ |H_\text{total}(f)|\approx |H(f)|^2. \]
This improves ripple suppression significantly while keeping the circuit simple and using standard components.
Recommended standard values
A compact two-stage filter that works well for both 490 Hz and 1 kHz PWM is:
- \(R_1=R_2=3.3,\text{k}\Omega\)
- \(C_1=C_2=4.7,\mu\text{F}\)
Per-stage cutoff:
\[ f_c\approx \frac{1}{2\pi\cdot 3.3,\text{k}\Omega\cdot 4.7,\mu\text{F}} \approx 10\,\text{Hz}. \]
Optional additions that improve behavior in noisy environments:
- \(100\,\text{nF}\) in parallel with each electrolytic capacitor for better high-frequency shunting.
- \(100\,\text{k}\Omega\) from the final filter node to ground to discharge the node to 0 V during reset or if the input becomes floating.
Lower \(f_c\) reduces ripple but increases settling time after duty-cycle changes. For spindle speed control, a settling time in the sub-second range is often acceptable.
Part 2: Amplification (0-5 V DC to 0-10 V DC)
Non-inverting gain stage
After filtering, the signal is a DC voltage \(V_\text{DC}\in[0\ \ldots\ 5,\text{V}]\). Scale it with a non-inverting amplifier:
\[ G=1+\frac{R_f}{R_g}. \]
For \(G=2\), choose \(R_f=R_g\), for example:
- \(R_f=10\,\text{k}\Omega\)
- \(R_g=10\,\text{k}\Omega\)
Then
\[ V_\text{OUT}=2\cdot V_\text{DC}, \]
which produces a 0-10 V setpoint.
Op-amp supply voltage
To generate 10 V output, the op-amp must be powered from a sufficiently high supply. If the op-amp is powered from 5 V, it cannot produce a 10 V output. A 12 V to 24 V supply is appropriate. With a 24 V supply, an LM358 can produce 10 V comfortably because the output is far below the upper rail.
Supply decoupling
Place decoupling capacitors from \(V_+\) to ground:
- \(100\,\text{nF}\) ceramic capacitor placed physically close to the op-amp supply pins.
- \(10\,\mu\text{F}\) to \(100\,\mu\text{F}\) electrolytic capacitor nearby.
These capacitors are connected in parallel, not in series. They reduce supply impedance at the op-amp and help prevent oscillation and sensitivity to PWM edge currents.
Unused second amplifier in LM358
LM358 contains two op-amps. The unused channel should not be left floating. A standard termination is:
- Connect the unused non-inverting input to ground.
- Configure the unused channel as a follower by connecting its output to its inverting input.
- Leave that unused output unconnected externally.
Output stability over long cables and the series resistor
A short bench setup can appear stable even when the final installation is not. A long control cable adds capacitance and increases exposure to EMI. Op-amps can become marginal or oscillate when driving capacitive loads directly. A common symptom is that the output reaches 10 V in a test setup but does not reach 10 V when the real cable and spindle interface are connected.
Place a series resistor at the amplifier output:
- \(R_\text{OUT}\approx 100\,\Omega\) (values up to 220 \(\Omega\) are commonly acceptable)
This isolates the op-amp from cable capacitance and improves stability.
For long or noisy runs, an additional receiver-end capacitor can be used:
- \(C_\text{END}=10\,\text{nF}\) to \(47,\text{nF}\) from signal to signal ground, placed near the 0-10 V input
This provides high-frequency noise suppression without materially affecting the DC setpoint.
Wiring and grounding for long runs
The 0-10 V signal is interpreted relative to its reference. Use a twisted pair for signal and signal ground. Avoid routing alongside motor and mains conductors over long distances. If the same cable also carries 24 V power, return currents can modulate the reference. If spare conductors exist, allocating a dedicated signal ground conductor improves robustness.
Gain calibration with a trimmer
If calibration is required, adjust \(R_g\) or \(R_f\), but avoid allowing \(R_g\) to approach zero because gain becomes very large and the output saturates. A bounded approach is to use a fixed resistor in series with a trimmer, for example:
- \(R_g=8.2,\text{k}\Omega\) in series with a 2 k\(\Omega\) to 5 k\(\Omega\) trimmer
This keeps the adjustment range centered around the target gain.
Failure patterns and likely causes
- Output never reaches 10 V: op-amp supply is too low, commonly due to powering from 5 V
- Works on the bench but fails when connected: missing \(R_\text{OUT}\), inadequate decoupling, or reference and wiring issues
- Ripple or speed jitter: cutoff too high, missing second RC stage, or EMI coupling into the analog line