|
|

HowTo: Simple 8-channel Dimmers
( Masao Kishore)
Step 1 : Simple 8-channel Dimmers
Revised: 11-23-2006
I realize that there are already dimmer projects in How-To, but a glance at one of circuit diagram will turn most people away, and the other one use PIC which will also turn most people away. So I constructed a very simple 8-channel dimmer with 200+ level steps which is controlled by a host computer. Trade off for very simple hardware is complex software to drive it.
|
|
Step 2 : Hardware Requirement:
We assume that all data pins (2, 3, 4, 5, 6, 7, 8, 9) are connected to optocouplers, and each of them drive a triac to switch on/off a 110VAC light. If not, you need at least one such device connected to pin 2 (Data 1) as follows for this project:
(pin 2)---(480 1/4W)---(pin 1 MOC3023 pin 2)---(pin 25)
(AC:hot)---(A2:triac)---(360 1/4W)---(pin 4 MOC3023 pin 6)---(gate:triac)
(AC:ground)---(light)---(A1:triac)
Besides 8 data (pins 2, 3, 4, 5, 6, 7, 8, and 9) and ground (pin 25), you need pin 10 (or any one of pins 10, 11, 12, or 13) for reading the zero crossing of 120v AC 120 times a second. (I used pin 12. See the software below.) Luckily this is normally high (5v), so we only need a device to connect this pin to the ground (pin 25) for each zero crossing. This can be done in many ways. In my first version, I described the simplest way to do this: Use 100k (1/2W) and 5K (1/2W) to get 5v AC, use four diodes and 10K (1/2W) to drive a NPN transistor. I did not recommend this method because 120v AC line is directly connected to your computer. In this revised version (11-23-2006), I removed that schematic, and I will be using 5V to 6V AC transformer in this version. You can get one for $0.99 from
http://www.goldmine-elec-products.com/prodinfo.asp?number=G14373
It is 12v AC center-tapped, and all I have to do is break the case carefully and remove a capacitor.
(A)---(+diode-)--- (one wire 12v AC---B: center tap---the other wire 12v AC)---(A)
If you have a 5v to 6v AC transformer, try this:
(A)--- (+diode-)---(one wire 6v)---(+diode-)---(B)
(A)--- (+diode-)---(the other wire 6v)---(+diode-)---(B)
Now use a small NPN transistor to connect pin 10 and pin 25:
(A)---(470ohm)---(base)
(pin 10)---(collector---emitter)---(B)---(pin 25)
|
|
Step 3 : Software Requirement:
When you download “inpout32_source_and_bins.zip”, a single C++ file “test.c” is included in the directory “Borland C++ test program”. This does not run in Visual Studio .Net, but it runs in Dev C++ (Windows application software), which you can download free from http://www.bloodshed.net/ This is much better than “Borland's Free C++ Command-line Compiler” recommended in “inpout32_source_and_bins.zip”. Other C++ and Visual Basic sample programs are multi-files, and so they are more difficult to understand and modify.
Dimming requires precise timing, and it is impossible to do it in Windows’ environment, where there are unknown number of interrupts occurring at any given moment. So dimming must be done in DOS environment. This is the trade-off between this project and other dimming projects: The hardware of this project is very simple to construct, but the software is more complex, especially if you want to dim two or more lights. The hardware for other projects are too complex for most people to construct, but the software may not be so complex as this one except for one with PIC.
The software for this project is written in assembly language. You can download Nasm16.exe assembler (nasm098r.zip) free from http://www.kernel.org/pub/software/devel/nasm/binaries/dos/
The program below dims and brightens all lights connected to data (pins 2, 3, 4, 5, 6, 7, 8, 9) simultaneously. The name of this file is "dim.asm". You will assemble and run it as follows:
A:>nasm16 dim.asm –o dim.com
A:>dim
Remember that it runs only in true DOS mode started by a diskette, not in a simulated DOS mode started in Windows XP.
It is at most important to find proper values of "bright" and "dark" in the program. "bright" is a value of delay so that the output is about 118v AC and “dark” is a value for delay so that the output is about 5v.
To find proper values of "bright" and "dark", do the following:
1: Change the line "testing" to true. No space before testing:
testing equ true
2: Change the value of "bright" to about 100:
bright equ 100
Run the program and measure the output. It should about 120V AC. If near 0V, increase the value of "bright" by 100, and repeat the procedure until the output is near 120V.
3: Increase the value of "bright" so that the output is near 118v. Increase the value of "bright" to decrease the output (lower voltage); decrease the value of "bright" to increase the output (higher voltage). Refer to the examples in the program for possible values to try. Write down the value &&&& for "bright" when the output is near 118V. This value is used in 6 below.
4: Increse the value of "bright" further, run the program, and measure the output. Repeat the procedure until the output is near 5v. Refer to the examples in the program for possible values to try. Write down the value **** for "bright". This value will be used for "dark" in 7 below.
5: Change "testing" to false. No space before testing.
testing equ false
6: Change the value of "bright" to &&&& obtained in 2 above.
bright equ &&&&
7: Change the value of "dark" to **** obtained in 3 for "bright".
dark equ ****
8: Run the program. The light shouled be dimmed and brighted continuously until you press Q.
As memtioned above, this program will dim and brighten all lights simultaneously. A program to dim and brighten all lights independently is quite complex, and took me over a week to finish. If there is a high demand for it, I will consider publishing it.
Hope you can enjoy this simple project with the program below.
M.K.
|
|
Step 4 : dim.asm
; Dim and brighten lights
; M. Kishore, 11-7-2006, 11-23-2006
; Name of this file is DIM.ASM
; This program runs only in true DOS mode started by a diskette.
; To assemble by NASM16:
; A:>nasm16 dim.asm –o dim.com
; To run this program:
; A:>dim
; Press Q to quit.
; Definition of constants "bright" and "dark":
; bright = delay with about 118v output (out of maximum 120v AC)
; dark = delay with about 5v output
; To find proper values of "bright" and "dark", do the following:
; 1: Change the line "testing" to true. No space before testing:
; testing equ true
; 2: Change the value of "bright" to about 100:
; bright equ 100
; Run the program and measure the output. It should about 120V AC. If near
; 0V, increase the value of "bright" by 100, and repeat the procedure until the
; output is near 120V.
; 3: Increase the value of "bright" so that the output is near 118v. Increase
; the value of "bright" to decrease the output (lower voltage); decrease the
; value of "bright" to increase the output (higher voltage). Refer to the
; examples in the program for possible values to try. Write down the value &&&&
; for "bright" when the output is near 118V. This value is used in 6 below.
; 4: Increse the value of "bright" further, run the program, and measure the
; output. Repeat the procedure until the output is near 5v. Refer to the
; examples in the program for possible values to try. Write down the value ****
; for "bright". This value will be used for "dark" in 7 below.
; 5: Change "testing" to false. No space before testing.
; testing equ false
; 6: Change the value of "bright" to &&&& obtained in 2 above.
; bright equ &&&&
; 7: Change the value of "dark" to **** obtained in 3 for "bright".
; dark equ ****
; 8: Run the program. The light shouled be dimmed and brighted continuously
; until you press Q.
;;;;;;;;;;;;;;;;;;;
org 100h
jmp start
; constants
true equ 1
false equ 0
testing equ false
; 850Mz Dell:
;bright equ 2300
;dark equ 7400
; 1800Mz Dell:
bright equ 500
dark equ 5300
; try: 50 <= dimMax <= 200
dimMax equ 100
dimMax2 equ 2*dimMax
dimMin equ 0
dimSpeed equ 3 ; slower if > 1
dimStep equ 1 ; faster if > 1
ms equ (dark-bright)/dimMax ; some number of mili seconds
brightMs equ bright/ms
; variables
map times 2*dimMax+1 db 0 ; byte array
dimMs2 dw 0 ; 0 <= dimMs2 <= 2*dimMax
dimMs dw 0 ; dimMs = map(dimMs2)
speed dw 0 ; 0 <= speed <= dimSpeed
;;;;;;;;;;;;;;;;;;;
start:
call init
call waitOn
call waitOff
loopTry:
mov ax, dimMin
mov [dimMs2], ax
loopdimMs2:
mov bx, [dimMs2] ; 0 <= dimMs2 <= 2*dimMax
mov al, [map+bx]
mov ah, 0
mov [dimMs], ax ; dimMs = map(dimMs2)
mov ax, dimSpeed
mov [speed], ax
loopSpeed:
; low: 0379h is not 00h
call waitOff ; wait unti low
call switchOff ; turn off the previous cycle
mov cx, bright
loopBright:
call check379h
dec cx
jne loopBright
mov ax, testing
cmp ax, false
je noTest
call switchOn
call waitOn
jmp checkChar
noTest:
mov bx, [dimMs]
mov cx, dimMin
loopDim:
cmp cx, bx
je loopDimEnd
call waitMs
inc cx
jmp loopDim
loopDimEnd:
call switchOn
; high: 0378h is 00h
call waitOn ; wait until high
; if speed > 1, repeat
mov ax, [speed]
dec ax
mov [speed], ax
jnz loopSpeed
; adjust dimMs2
mov ax, [dimMs2]
inc ax
mov [dimMs2], ax
cmp ax, 2*dimMax
jbe loopdimMs2
; check if a key is pressed
checkChar:
mov ah, 06h ; char in al
mov dl, 0FFh ; read
int 21h
jz loopTry ; no char
cmp al, 'q'
jne loopTry
quit:
call switchOff
mov ax,4c00h ; program termination
int 21h
;;;;;;;;;;;;;;;;;;;
; map(i) = dimMax - i if 0 <= i <= dimMax
; map(i) = i - dimMax if dimMax <= i <= 2*dimMax
; if dimMin = 0 and dimMax = 100, map array will be
; 100, 99, ..., 1, 0, 1, ..., 99, 100
init:
mov bx, dimMin
init1:
mov al, bl
mov [map+bx+dimMax], bl
mov ax, dimMax
sub ax, bx
mov [map+bx], al
inc bx
cmp bx, dimMax
jle init1
ret
;;;;;;;;;;;;;;;;;;;
; for pin 10, try 10h
; for pin 11, try 20h
; for pin 12, try 40h as in this program below
; for pin 13, try 80h
waitOn:
; On or high when 00h
call check379h
jne waitOn
ret
waitOff:
; Off or low when not 00h
call check379h
je waitOff
ret
check379h:
mov dx, 0379h
in al, dx
and al, 40h
cmp al, 00h
ret
;;;;;;;;;;;;;;;;;;;
; wait 'some' number of mili seconds
waitMs:
mov di, ms
waitMs1
call check379h
dec di
jnz waitMs1
ret
;;;;;;;;;;;;;;;;;;;
; all lights on
switchOn:
mov al, 0ffh
mov dx, 0378h
out dx, al
ret
; all lights off
switchOff:
mov al, 00h
mov dx, 0378h
out dx, al
ret
|
|
|