Disclaimer: I am not an expert in any of this. There is lots of information online regarding such designs. Although this setup worked for me, do not trust any of my calculations. Please work all this out for yourself and consult many other sources, or it may spontaneously burst into flames.
The contraption is a board containing two lights and a receptacle that are controlled by a computer communicating with the Arduino microcontroller. The project grew out of a desire to learn more about microcontroller programming and some circuit design, something I had never really done before.
Below is a video of the contraption in action. In the video, I control the two light bulbs, as well as a blender, from my computer. (Note: the video does not have sound)
The hardware was laid out on a plain wood board as shown in the photos below.
Note that all power is actually flowing through the breadboard. This is probably not a very good idea, but as we are dealing with only an amp or two at most, I thought it might be satisfactory. I've included both an on/off switch, and a 5A circuit breaker for safety.
The schematic below shows the main circuit used in controlling the power to the lights and the receptacle. This circuit is nearly identical to that found in the MOC3022M datasheet.
The main principle is as follows:
A few notes and equations:
If no voltage is applied to the left side of the MOC3022M, the mains current flow through the T1 triac will stop when the mains voltage reaches the zero-point crossing. The solution is to leave the Arduino output on, which works only if you want the mains circuit completely on. However, for dimming, you must know when the zero cross occurs.
This circuit allows an Arduino input pin to register when the AC mains voltage is in the positive half-wave.
Note that detection by the Arduino of the start of the positive half of the sine wave is delayed, and the detection of the end is too early. Below is an exaggerated diagram.
The counter in the diagram refers to the AVR timer counter that counts ticks between the rising and falling edges. The average of the rising and falling edge counters gives 60Hz. In order to dim, the triac must turn on at a specified point during the sine wave. That point is calculated in the code. Therefore, the timer for turning on the triac must be kept in sync with the timer for the zero-cross detection. This is done by modifying the phase-shifting-timer's counter register when the microcontroller detects a rising edge. A more-accurate value for the phase-shifting counter can be approximated, assuming the symmetry present in the diagram (see the code). This could also be done for the falling edge as well, although would require more code in an interrupt routine, which is generally a bad thing.
Due to the zero-cross behavior, even if the Arduino output is left completely on, there is some delay in turning on the triac due the gate current and voltage required to trigger the triac. This delay can be calculated:
Dimming is accomplished by providing a pulse at the appropriate time, allowing conduction through the triac.
After implementing the dimming, I recorded the following data with an oscilloscope. These plots represent, from top to bottom, reduction of the power output by 75%, 50%, and 25%.
Despite using an Arduino microcontroller, the code is written in straight C using the AVR library. The GUI is written in C++ and uses Qt.
The code can be downloaded or viewed on GitHub.
The documentation is generated from doxygen and available online here.