
One could let an Arduino just open the Triac for a number of microseconds, but that has the problem that it is unpredictable during what part of the sinus wave the triac opens and therefore the dimming level is unpredictable. Phase cutting One way of doing it is through phase control with a Triac: the Triac then is fully opened, but only during a part of the sinus AC wave. a transistor is not really possible due to the large power the transistor then will need to dissipate, resulting in much heat and it is also not efficient from an energy use point of view. It becomes a bit more tricky if one wants to dim a mains AC lamp with an arduino: just limiting the current through e.g. (I say Arduino, but if you use an 8051 or PIC16F877A microcontroller, there is stuff for you too here.)

Switching an AC load with an Arduino is rather simpel: either a mechanical relay or a solid state relay with an optically isolated Triac. This will only work with a random fire optocoupler: NOT igniting at zerocrossing is the principle of this dimmer. WARNING: Some people try to build this with an optocoupler with zerocrossing coz 'that is better' right? Some are even told in electronics shops it is better to use such an optocoupler.

#Arduino timer interrupt sketch code#
You can of course stop interrupts before calling delayMicroseconds() and enable them afterwards, but that again does impact timing accuracy by the duration of compiled code for enabling/disabling.WAIT!! before you decide to build this, it is good to know that a similar dimmer is available at Aliexpress at cost that is hard to beat (currently 2.70 euro) When an interrupt is received during the execution of the delayMicroseconds(), the timing of delayMicroseconds() will be wrong. "brne 1b" : "=w" (us) : "0" (us) // 2 cyclesīTW: The compiled code is pretty accurate, but be aware of the following: On Arduino there are timed interrupts configured that most are unaware of. account for the time taken in the preceeding commands. per iteration, so execute it four times for each microsecond of the following loop takes a quarter of a microsecond (4 cycles) of the function call yields a delay of approximately 1 1/8 us. for a one-microsecond delay, simply return. for the 16 MHz clock on most Arduino boards 2 microseconds) gives delays longer than desired. calling avrlib's delay_us() function with low values (e.g. Calling _asm_-code from C requires some extra instructions to save CPU registers.įor a normal Arduino only the following code will be compiled: /* Delay for the given number of microseconds. The last -2 microseconds (before the loop is kicked off) is again a correction on compiler introduced overhead.


16MHz/(4×4) = 1MHz, which takes 1 us cycle time, the resolution that we are after. The _asm_-loop compiles into a 4 CPU cycle loop. Then the delay value is multiplied by four ( <<=2). That an assumption of the author! The number of CPU cycles 'burnt' by each instruction is well documented in the Atmel AVR instruction set document.įirst the delay value is checked for being equal to 1, in that case just returning from the routine already spent over a microsecond of CPU time. The code heavily relies on compiler optimization being exactly the same for you as for the developer of the library. For now just focus on this single function, it doesn't rely on any other fucntions.īy inspecting the code you'll notice that it is not about timers, it is all about instruction cycles. Take the effort of finding the file and browsing through it.
#Arduino timer interrupt sketch windows#
Windows systems will have a similar path to the wiring.c file. The source code for this function is fairly well documented and can be found in /usr/share/arduino/hardware/arduino/cores/arduino/wiring.c on Linux systems.
