Browse over 10,000 Electronics Projects

AC Power Control with Thyristor – Pulse Skipping using triac with PIC16F877A

AC Power Control with Thyristor – Pulse Skipping using triac with PIC16F877A


//Programmer: Syed Tahmid Mahbub
//Compiler: mikroC PRO for PIC v4.60
//Target PIC: PIC16F877A
//Program for pulse skipping modulation or cycle control
unsigned char FlagReg;
unsigned char Count;
unsigned char TotalCount;
unsigned char nCount;
unsigned char nTotalCount;
sbit ZC at FlagReg.B0;
void interrupt(){
     if (INTCON.INTF){          //INTF flag raised, so external interrupt occured
        ZC = 1;
        INTCON.INTF = 0;
void main() {
     PORTB = 0;
     TRISB = 0x01;              //RB0 input for interrupt
     PORTA = 0;
     ADCON1 = 7;
     TRISA = 0xFF;
     PORTD = 0;
     TRISD = 0;                 //PORTD all output
     OPTION_REG.INTEDG = 0;      //interrupt on falling edge
     INTCON.INTF = 0;           //clear interrupt flag
     INTCON.INTE = 1;           //enable external interrupt
     INTCON.GIE = 1;            //enable global interrupt
     Count = 6;                 //number of half-cycles to be on
     TotalCount = 10;           //total number of half-cycles control
     nCount = Count;
     nTotalCount = TotalCount;
     while (1){
           if (ZC){ //zero crossing occurred
              if (nCount > 0){
                 PORTD.B0 = 1;
                 PORTD.B0 = 0;
              if (nTotalCount == 0){ //number of required half-cycles elapsed
                 nTotalCount = TotalCount;
                 nCount = Count;
              ZC = 0;
The total number of half-cycles I want to control is stored in the register TotalCount. Count holds the number of half-cycles I want voltage supplied to the load. So, the ratio of Count to TotalCount equals the duty cycle.
Each time the triac is fired, the value of nCount is decremented, until it reaches zero. When nCount equals zero, the triac is no longer fired. At the same time, the register nTotalCount is decremented each zero-crossing. So it keeps track of the number of half-cycles elapsed. Initially nTotalCount is loaded with the value of TotalCount so that nTotalCount keeps track of the number of half-cycles we want to control. After that number of half-cycles elapses, nTotalCount is reloaded with the value of TotalCount and nCount is reloaded with the value of Count. Pulse skipping modulation starts over again.
In our code, we want to control 10 half-cycles, which means 5 cycles. We want voltage to be supplied to the load for 3 cycles and off for 2 cycles. This is done, as nCount counts down from 6 to 0 while firing the triac, firing the triac 6 consecutive half-cycles. For the next 4 half-cycles, while nTotalCount is still counting down to zero, the triac is off. So, voltage is not supplied to the load. The duty cycle is 60%.
The triac is fired right after zero-crossing occurs. One advantage of this is that very little radio frequency interference is produced. However, care must be taken that an unequal number of positive and negative half-cycles must not be present. This will introduce a DC component that can damage motors and other devices. Cycle control also cannot be used with incandescent bulbs because of high unacceptable flickering.
This problem with the DC component is avoided by ensuring that equal numbers of positive and negative half-cycles are present. This is done by ensuring that the Count and TotalCount (in the code above) are both even numbers.

Now let’s take a look at my circuit setup and then the output waveform using this code: