Sunday, 13 July 2025
     
 
Main Menu
Home Home
Shop Shop
News News
BASCOM-AVR BASCOM-AVR
BASCOM-8051 BASCOM-8051
Products Products
Application Notes Application Notes
Publications Publications
Links Links
Support Center Support Center
Downloads Downloads
Forum Forum
Resellers Resellers
Contact Us Contact Us
Updates Updates
MCS Wiki MCS Wiki
Online Help
BASCOM-AVR Help BASCOM-AVR Help
BASCOM-8051 Help BASCOM-8051 Help
Contents in Cart
Show Cart
Your Cart is currently empty.
Search the Shop

Products Search

User Login
Username

Password

If you have problem after log in with disappeared login data, please press F5 in your browser

RSS News
 
     
 

 
   
     
 
AN #125 - How to set up zero crossing software to trigger a Triac Print
How to set up zero crossing software to trigger a Triac

This AN was submitted by Mike Crean.

Here is some additional info from Mike. He sent this after the first circuit was published. 

If anyone is trying to use the zero crossing detector in AN125 there are corrections.
The 10k resistor from pin 1 of the 4069 hex. Inverter should NOT be pulled LOW
It should be pulled HIGH (5V+). The pulse width on pin 4 should be less than 1ms.
The pull up resistor on the collector of the BC548 should be 1K NOT 1K5.

If anyone is using a sensitive gate TRIAC remember to use a bias resistor (10k) on
the gate to neutral or timing cap line side. This will prevent erratic triggering by
external electrical noise.

The 2nd. zero crossing circuit in AN125 should be used for more stable operation
of the TRIAC.

It also shows how to use Timer0, Urxc ISR and ADCs from the  AT90S8535.

Here are two methods to derive the zero crossing from the mains.

DANGER - WARNING

High voltages are present when equipment 
is connected to a mains supply. 

Some Authorities may only allow suitably 
qualified & licensed persons to connect 
any such equipment to a high voltage 
supply. 

Take CAUTION. Avoid electric SHOCK 

The pulse time will depend on the mains frequency used in your country.
Below you can find the program. You can also download it. 

For a dimmer with fader, download Mikes sample

 


'*****************************************************
'** **
'** 24Volt 40A Battery Charger **
'** **
'** Mike Crean Perth Western Australia **
'** mike.crean@y7mail.com **
'** **
'** mgc Start 02/01/2003 **
'** Finish 23/01/2003 **
'** **
'*****************************************************

'@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
'@@ @@
'@@ This is a program to drive a MOC into a Triac @@
'@@ using an AT90S8535 AVR micro. @@
'@@ @@
'@@ Demo of using INT0 for zero crossing detection @@
'@@ & Timer0 for Triac control, also shows use of @@
'@@ Urxc ISR for comm's interface & use of ADCs. @@
'@@ @@
'@@ The hardware for this project is reserved & @@
'@@ will not be released. @@
'@@  @@
'@@ This battery charger was developed to charge @@
'@@ 24V 500A/Hr batteries on stationary Gen. Sets. @@
'@@ It has to shut OFF when the prime mover is @@
'@@ cranking (500-800A). It has 4 levels of voltage @@
'@@ Control 25, 27, 28 & 28.5V and 4 levels of @@
'@@ current control 40, 12, 8(variable) & 0A. Some @@
'@@ of the current controls very with battery @@
'@@ condition. It has a float & Triac fail @@
'@@ timer (4min.) @@
'@@  @@
'@@ There are a number of features that could be @@
'@@ added, like|- de-sulfate timer with voltage & @@
'@@ current control @@
'@@ @@
'@@ @@
'@@ Must set up AVR-IDE for AT90S8535 @@
'@@ --------------------------------- @@
'@@  @@
'@@ From Options menu, select compiler, chip & @@
'@@ set to 8535, in communications tab set @@
'@@ Fequency to 8000000 @@
'@@ From the programmer menu set programmer to @@
'@@ STK200/STK300 programmer, Auto Flash tick @@
'@@ only and cable to Parallel @@
'@@ This is for the ISP programmer dongle in the @@
'@@ BASCAVR1.PDF manual (about page 396). @@
'@@ @@
'@@ ** F7 Compile @@
'@@ ** F2 Simulate @@
'@@ ** F4 Send to chip @@
'@@ @@
'@@ ** $sim must be included & compiled when @@
'@@ simulate is run. @@
'@@ ** $sim must be REM out when compiled to @@
'@@ send to chip @@
'@@ @@
'@@ FOR MORE INFORMATION ON IDE set up and @@
'@@ programming, READ THE BASCAVR1.PDF manual or @@
'@@ use HELP @@
'@@ @@
'@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@

'$sim
$regfile = "8535def.dat"
$crystal = 8000000
$baud = 9600
Config Adc = Single , Prescaler = Auto
Config Timer0 = Timer , Prescale = 1 '** Sets T0 / rate
 
'** Values (1,8,64,256 &
Config Int0 = Falling '** Interrupt 0, PIN 16 (Int0)
Config Portd = Input '** Set Portd to Inputs
Config Portb = Output '** Set Portb to Outputs
Config Portc = Output '** Set Portc to Outputs
Cursor Off

'** Config variables

Dim Rx As Byte , Channel As Byte , Flag27 As Byte , Flag28 As Byte
Dim Flagchk As Byte , Lv As Byte , Mv As Byte , Hv As Byte , Ea As Byte
Dim Eep As Byte , Shit As Byte , Fdcount As Byte , Fdmult As Byte
Dim Startflag As Byte , Stod As Byte , Ep As Byte , Ehv As Byte
Dim Count As Integer , Td As Integer , Tds As Integer , Dcount As Integer
Dim Vd As Single , Amps As Single
Dim W As Word , Stuff As Word , Stuffs As Word , Ftd As Word

Startflag
= 0

'** Get Values from Eeprom

Readeeprom Ea , 2
Readeeprom Hv , 3
Readeeprom Mv , 4
Readeeprom Lv , 5
Readeeprom Shit , 6
Readeeprom Fdmult , 7
Readeeprom Stod , 8
Readeeprom Ehv , 9

'** 1st. run after programming, Ea should be 255
'** If Ea > 251 then load defaults to variables & write to Eeprom **

If Ea > 251 Then
 Ea
= 145 : Hv = 141 : Mv = 138 : Lv = 130 : Tds = 110 : Shit = 255
 Dcount
= 0 : Fdcount = 0 : Fdmult = 240 : Stod = 2 : Ehv = 143
 
Writeeeprom Ea , 2
 
Waitms 10
 
Writeeeprom Hv , 3
 
Waitms 10
 
Writeeeprom Mv , 4
 
Waitms 10
 
Writeeeprom Lv , 5
 
Waitms 10
 
Writeeeprom Shit , 6
 
Waitms 10
 
Writeeeprom Fdmult , 7
 
Waitms 10
 
Writeeeprom Stod , 8
 
Waitms 10
 
Writeeeprom Ehv , 9
 
Waitms 10
End If

Ftd
= Shit * 100
Flag27
= 0 : Flag28 = 0 : Flagchk = 0 : Startflag = 0 '** Set Flags
On Urxc Rec_isr '** Call Recv. Interrupt service routine
Enable Urxc '** Enable ISR calls
On Timer0 Tim0_isr '** Call Timer0 ISR
Enable Timer0 '** Enable Timer0 ISR calls
Enable Int0 '** Enable Int0 ISR calls
On Int0 Int0_isr '** Call Int0 ISR
Enable Interrupts '** Enable all interrupts
Stop Timer0 '** Stop the Timer
Start Adc '** Start the Adc
Portc = 0 '** Set Portc LOW (0)
Portc.0 = 1 : Portc.2 = 1 : Portc.3 = 1 : Portc.4 = 1 '** Set Portc
Portb = 255 '** Set all bits on Portb High
 
'** all bits pulled HIGH with
 
'** internal pull up resistors

Portb.2 = 0  '** Pull PortB.2 Low (Triac OFF)

'***** MAIN PROGRAM LOOP *****

Do

 
nop

Loop


Getadc:

 
'** Read the ADC channels (10 bit ADC) = (0 to 1023 count)

 
For Channel = 0 To 7
 W
= Getadc(channel) '** Loop to read 8 Adcs
 
If Channel = 0 Then Stuff = W / 3 '** Put ADC0 / 3 into Stuff (Amps)
 
If Channel = 1 Then Stuffs = W / 3 '** Put ADC1 / 3 into Stuffs (Volts)
 
Next Channel

 
'** If a start sig. is seen on Pd6

 
If Pind.6 = 1 Then '** Turn OFF Charger & Starter ON
 
If Startflag = 0 Then
 
Portc.0 = 0 : Portc.3 = 1 : Portc.4 = 1
 
Wait Stod
 
Portc.1 = 1
 Startflag
= 1
 
Portc.1 = 1
 
End If
 
End If

 
'** If No start sig. on Pd6

 
If Pind.6 = 0 Then '** Turn Starter OFF & Charger ON
 
If Startflag = 1 Then
 Startflag
= 0
 
Portc.1 = 0
 
Wait Stod
 
Portc.0 = 1
 
End If
 
End If

 
If Startflag = 1 Then Goto Starting '** Jump this lot if Starting

 Td
= Stuff '** Put Stuff (word) into Td (Integer)
 
If Stuffs > Td Then Td = Stuffs

 
If Stuffs < Lv Then '** If Batt < 25.5V set to max C/R
 Flag27
= 0 '** C/R is Charge Rate
 Flag28
= 0
 
Portc.2 = 0 : Portc.3 = 1 : Portc.4 = 1 '** Set LEDs on Portc
 
End If

 
If Stuffs > Mv Then '** If Batt > 27V set 27V Flag
 
If Flag27 = 0 Then
 
If Flagchk = 0 Then
 Flag27
= 1
 
Portc.2 = 1 : Portc.3 = 0 : Portc.4 = 1 '** Set LEDs on Portc
 
End If
 
End If
 
End If

 
If Stuffs > Hv Then '** If Batt > 28V set 28V Flag
 
If Flag27 = 1 Then
 
If Flagchk = 0 Then
 
If Flag28 = 0 Then
 Flag28
= 1
 
Portc.2 = 1 : Portc.3 = 1 : Portc.4 = 0 '** Set LEDs on Portc
 
End If
 
End If
 
End If
 
End If

 
If Stuffs > Ehv Then '** If Batt > 29V set 28V Flag = 2
 
Portb.2 = 0 : '** Turn off Triac
 
Waitms 250 '** Wait .25 Sec.
 
Portc.0 = 0 '** Turn OFF mains relay TRIAC may be
 Flag28
= 2 '** at FAULT (will cycle every 4 min.)
 
Portc.2 = 1 : Portc.3 = 1 : Portc.4 = 1
 
'** Turn all LEDs ON to indicate FAULT
 
End If

 
If Flag28 = 1 Then
 
Portb.2 = 0 '** Set Portb.2 LOW Triac OFF
 Flag28
= 2 : Count = 0
 
End If

 
If Flag28 = 0 Then
 
If Td < Tds Then Td = Tds '** Set Td not < Zero Cross or max amps
 
If Td > 217 Then Td = 217 '** Set Td not > next Zero Cross
 
If Flag27 = 1 Then Td = Ea '** If Batt > 27V Set max Amps to 8
 
End If '** value 145

Starting
:

Return

Int0_isr
: '** Interrupt0 Interrupt Service Routine

Start Timer0 '** Start Timer 0
Gosub Getadc '** Get the Amps & Volts from the ADC
 
'** The ADC conversion & other
 
'** calculations are in this section
 
'** because they take the most time.

Return '** Return to MAIN Program Loop

Tim0_isr
: 'Timer0 ISR, called if T0 overflows

If Startflag = 1 Then '** If Startting set Portb Low
 
Portb = 0
 
Goto Yes_start '** Jump to Yes_start
End If

If Flag28 = 0 Then
 Count
= Count + 1 '** Start counter (No. of interrupts)
 
'** counts each time T0 overflows
 
If Count > Td Then  '** If the count > AD0 / 3 then send
 Count
= 0 '** pulses & set count to 0
 
Stop Timer0 '** Stop Timer 0
 
'** Send 3 pulses to the Triac
  
Set Portb.2 '** Turn Portb.2 on (high), PIN 3
 
Waitus 100 '** Wait 100 u/s
 
Reset Portb.2 '** Turn Portb.2 off (low), PIN 3
 
Waitus 100 '** Wait 100 u/s
 
Set Portb.2 '** Repeat for 3 pulses
 
Waitus 100
 
Reset Portb.2
 
Waitus 100
 
Set Portb.2
 
Waitus 100
 
Reset Portb.2
 
Waitus 100
 
End If
End If

If Flag28 = 2 Then '** If 28V Battery Flag is set to 2
 
Portb.2 = 0 '** Turn Portb,2 OFF (Triac OFF)
 Dcount
= Dcount + 1 '** Set up a 4min. Timer

 
If Dcount > Ftd Then
 Dcount
= 0 : Fdcount = Fdcount + 1

 
If Fdcount > Fdmult Then
 Fdcount
= 0 : Dcount = 0 : Flag27 = 0 : Flag28 = 0
 
Portc.0 = 1
 
Waitms 250
 
End If
 
End If
End If

Yes_start
:

Return '** Return to MAIN Program Loop

Rec_isr
:  '** Recv. buffer ISR

Rx
= Inkey() '** Get Char (ASCII) from Recv. buffer

If Rx = 63 Then '** 63 = chr ?
 
Print : Print " 24V Battery Charger" '** Send to Tx buffer
 
Print " -----------------------------"
 
Print : Print " | - Get All Values"
 
Print " ! - Set Max Amps (40A) value 110 "
 
Print " @ - Get Volts & Amps"
 
Print " # - Turn 27V & 28V Flags OFF"
 
Print " $ - Turn Voltage Flags ON"
 
Print " % - Set all Micro values & write to Eeprom"
 
Print " ^ - Read Micro values from Eeprom"
End If

If Rx = 124 Then '** 124 = chr |
 
Print : Print " Td = " ; Td '** Send Td to Tx buffer
 
Print " Count = " ; Count
 
Print " Ea = " ; Ea
 
Print " Tds = " ; Tds
 
Print " W = " ; W
 
Print " Stuffs = " ; Stuffs
 
Print " Flag27 = " ; Flag27
 
Print " Flag28 = " ; Flag28
 
Print " FlagChk = " ; Flagchk
 
Print " Eight Amp Value = " ; Ea
 
Print " Ehv 29V Value = " ; Ehv
 
Print " Hv 28V Value = " ; Hv
 
Print " Mv 27V Value = " ; Mv
 
Print " Lv 25V Value = " ; Lv
 
Print " Ftd float time delay = " ; Ftd
 
Print " Dcount = " ; Dcount
 
Print " Fdt Mult. count (Fdcount) = " ; Fdcount
 
Print " Fdmult = " ; Fdmult
 
Print " Startflag = " ; Startflag
 
Print " PortD.6 = " ; Pind.6
 
Print " Stod Start Relay Delay = " ; Stod
End If


If Rx = 33 Then '** 33 = chr !
 
Waitms 100 '** Must turn OFF Recv. ISR
 
Disable Urxc '** & interrupts if Input is used
 
Waitms 50 '** Need short delays
 
Disable Interrupts
 
Waitms 100
 
Input " Enter Tds value " , Tds
 
Waitms 100 '** Need short delays
 
Enable Urxc '** Must turn Recv. ISR ON to
 
Waitms 50 '** enable more Uart ISR's
 
Enable Interrupts
 
Waitms 100
End If

If Rx = 64 Then '** 64 = chr @
 Vd
= Stuffs / 5.0 '** Was 4.75
 Amps
= Stuff / 5.8 '** Was 3.26
 
Print " Volts = " ; Vd
 
Print " Amps. = " ; Amps
End If

If Rx = 35 Then '** 35 chr # - Hold Flags OFF
 Flagchk
= 1
 Flag27
= 0
 Flag28
= 0
End If

If Rx = 36 Then '** 36 chr $ - Set Flags to ON
 Flagchk
= 0
End If

If Rx = 37 Then '** 37 chr % - Set all volts &
 
Waitms 100 '** Amps Values
 
Disable Urxc
 
Waitms 50
 
Disable Interrupts
 
Waitms 100
 
Print : Print " Max. for any Value is 255"
 
Input " Enter Tds max amps (110 = 40A) " , Tds '** Tds max amps (38A) value (110)
 
Input " Enter Lv min volts (130 = 25V) " , Lv '** Lv 25V value (130)
 
Input " Enter Mv med volts (138 = 27V) " , Mv '** Mv 27V value (138)
 
Input " Enter Hv high volts (141 = 28V) " , Hv '** Hv 28V value (141)
 
Input " Enter Ehv Extra high volts (143 = 29V) " , Ehv '** Ehv 29V value (143)
 
Input " Enter Ea 8A (145 max 250) " , Ea '** Ea 8A value (145)
 
Input " Enter Ftd float time delay (255 = 1 Sec.) " , Shit
 
'** Ftd float time delay value ( )
 
Input " Enter Fdt Mult. (Fdcount) (240=4min.) " , Fdmult
 
Input " Stod Start Relay Delay 1 to 255 Sec's " , Stod
 
Waitms 50
 
Writeeeprom Ea , 2
 
Waitms 10
 
Writeeeprom Hv , 3
 
Waitms 10
 
Writeeeprom Mv , 4
 
Waitms 10
 
Writeeeprom Lv , 5
 
Waitms 10
 
Writeeeprom Shit , 6
 Ftd
= Shit * 100
 
Waitms 10
 
Writeeeprom Fdmult , 7
 
Waitms 10
 
Writeeeprom Stod , 8
 
Waitms 10
 
Writeeeprom Ehv , 9
 
Waitms 50
 
Enable Urxc '** Must turn Recv. ISR ON to
 
Waitms 50 '** enable more Uart ISR's
 
Enable Interrupts
 
Waitms 100
End If

If Rx = 94 Then '** 94 ^ Read Eeprom values
 
Waitms 100 '** Amps Values
 
Disable Urxc
 
Waitms 50
 
Disable Interrupts
 
Waitms 100
 
Readeeprom Ep , 2
 
Print : Print " Low amps (8A=145) Ea = " ; Ep
 
Readeeprom Ehv , 9
 
Print " Extra high volts (29V = 143) Ehv = " ; Ehv
 
Readeeprom Ep , 3
 
Print " High volts (28V = 141) Hv = " ; Ep
 
Readeeprom Ep , 4
 
Print " Med. Volts (27V = 138) Mv = " ; Ep
 
Readeeprom Ep , 5
 
Print " Low volts (25V = 130) Lv = " ; Ep
 
Readeeprom Ep , 6
 
Print " Float delay (255 = 255) Shit = " ; Ep
 
Readeeprom Ep , 7
 
Print " Float Mult. (240 = 240) Fdmult = " ; Ep
 
Readeeprom Ep , 8
 
Print " Start delay (2sec = 2sec) Stod = " ; Ep
 
Print
 
Print " Ea = " ; Ea
 
Print " Ehv = " ; Ehv
 
Print " Hv = " ; Hv
 
Print " Mv = " ; Mv
 
Print " Lv = " ; Lv
 
Print " Shit = " ; Shit
 
Print " Ftd = Shit * 100 Ftd = " ; Ftd
 
Print " Fdmult = " ; Fdmult
 
Print " Stod = " ; Stod
 
Waitms 50
 
Enable Urxc '** Must turn Recv. ISR ON to
 
Waitms 50 '** enable more Uart ISR's
 
Enable Interrupts
 
Waitms 100
End If

Rx
= 0

Return '** Return to MAIN Program Loop

End '** End of program and code space