This project uses the Arduino PWM Uno or other systems to realize a fully isolated analog output with a range of 0-5 volts or more, changing only the reference voltage.
This project completes the series of my articles about the Arduino analog I/O with the aim to use it as a controller of small automation systems.
In control systems of the industrial plants it is always advisable to isolate both the inputs and the outputs coming from the field. This prevents disturbances caused by power surges, lightning strikes or other EMI sources and also by ground potential differences.
Arduino Uno, or systems based on the ATmega328 chip has no a true analog output, but it may be realized using a PWM output averaged with a low-pass filter.
The use of an averaged PWM signal with 8-bit setting is not comparable with a real DAC, but in the insulation case presents undoubted advantages of simplicity since it is sufficient to use an optocoupler for isolating the PWM digital signal. Recently I designed another circuit to generate a 4-20 mA current with Arduino, that experience gave me the idea for this new project.
The Arduino PWM
Arduino Uno has several pins (3, 5, 6, 9, 10, and 11) that can be configured for PWM output. For this project I used pin 9 because the others were used by various devices (LCD, SD and RTC) in my Arduino system.
The PWM signal on pins D9 and D10 is generated by Timer# 1 of ATmega328. It has a prescaler which divides by 1, 8, 64, 256, 1024, controlled by the three least significant bits of the register TCCR1B. The default value of the prescaler set by the Arduino IDE is equal to Np= 64 (TCCR1B, bits 2-0= 110), which provides an output frequency:
PWM frequency = CPU Clock/(2´Np´TOP) = 16000000/(2´64´255)= 490.196 Hz
Where the TOP value is he maximum Timer/Counter value.
The following table shows the frequencies generated by Timer# 1 of an Arduino Uno (At mega 328) on pins 9 and 10, with a 16 MHz clock and in “phasecorrect PWM” mode. In this mode, the timer counts from 0 to 255 and then back down to 0.
|Prescaler divider (Np)||Prescaler code||PWM frequency|
The prescaler code must be put in the three least significant bits of the register TCCR1B – Timer/Counter1 Control Register B. For example, to generate a PWM of 3921 Hz, the following instruction must be inserted in the setup function:
TCCR1B = TCCR1B & B11111000 | B00000010;// set timer 1 prescaler to 8
Using a common op to coupler with a phototransistor, as 4N25, the frequency is limited because of the high transition times, so I used a faster op to coupler with photodiode and with an open collector output, such as the 6N136.
To eliminate the output noise I utilized a second order active low-pass filter, Sallen-key type, with a cut-off frequency of about 11.2 Hz. The isolation is achieved with an op to coupler, of course you must use for this circuit a power supply different from the one used for Arduino. If the insulation is not required, things become even simpler and connect the filter to the PWM output, in this case not even need the reference source U2.
Read More: An isolated analog output for Arduino Uno