Zedomax DIY120

From Zedomax Wiki

Jump to: navigation, search

Zedomax DIY120: Voice Activated Christmas Lights

In this article we'll show you how to build a Christmas light controller! The basic concept can easily be expanded to many individually-controlled circuits. Any predefined animation pattern can be displayed, and the system can also respond to voice or music.

First of all, check out the video to see how everything works.

Voice Activated Christmas Lights


Circuit Explanation

Next, let's take a look at the schematic. I've constructed this circuit using a CB280 controller on a CB280-Proto board, along with an SSR4 board and several pieces of electrical hardware.

The analog portion of the circuit is based on half of an LM324N quad op-amp I had on hand. The first stage acts as an amplifier for the small signal received by the electret microphone. The second stage acts as an integrator, since we're interested in the overall sound level rather than the actual waveform. The larger the value of C1, the slower the circuit responds to volume changes. This circuit was quickly "designed" on a breadboard and values tweaked until desired operation was achieved. No doubt a better circuit could be developed with a larger time investment, but this does the job.

Additional devices on the breadboard include a potentiometer wired as a voltage divider; this is used with an analog input on the CB280 controller as a simple speed control. There is also a pushbutton with pullup resistor, used for switching display modes. The circuit also uses the CB280-Proto board's integrated piezo speaker on Port 48 to indicate the current display mode after the button has been pressed.


Code Explanation

In the following section, I will go through the controller code and explain the purpose of each part.

Listing 1.

' Sound-reactive Christmas Light Controller
' Also contains several sequences without sound input
Const Device = CB280
Ramclear

' Enable input on ADC Channel 0
Input 24
Input 25

Dim AnalogIn As Integer ' ADC Value
Dim Mode As Byte ' Sequence Mode
Dim LightMap As Byte ' Contains the levels to be sent to the relays
Dim Speed As Integer ' Contains the speed setting


Mode = 0 ' Start in voice-reactive mode
LightMap = 0 ' Clear output register

' Set interrupt to first external interrupt channel on Port 20
' Will generate interrupt on falling edge
On INT0 Gosub ChangeMode
Set Int0 0

In Listing 1 I've initialized the controller and any variables I will need. The code is pretty self-explanatory; the device type is set, the analog inputs are initialized, and the interrupt for the mode change button is started.


Listing 2.

' Main Program Loop
Do

' Read potentiometer for speed adjustment
Speed = 1024 - (Tadin(1))

' Choose the display mode
Select Case Mode

	Case 0
		Gosub SoundReact ' Use outputs as indicator of sound level

	Case 1
		Gosub Expander ' Sequence outputs one at a time from 0 to 3
		
	Case 2
		Gosub Contracter ' Sequence outputs one at a time from 3 to 0
		
	Case 3
		Gosub Bouncer ' Sequence outputs back and forth between 0 and 3
		
	Case 4
		Gosub Filler ' Display a bar graph that rises and falls

End Select
	
	' Write only the lower 4 bits of LightMap to the output
	Out 0,LightMap.BIT0 
	Out 1,LightMap.BIT1
	Out 2,LightMap.BIT2
	Out 3,LightMap.BIT3
	
Loop

The main program loop is contained in Listing 2. Every time the program loops, it checks the analog input that is wired to a potentiometer. The controller converts a 0V to 5V level to a number between 0 and 1023. This is used to provide a delay value to various subroutines, with the net result of adjusting the animation speed. Next, there is a Select...Case statement which chooses one of the animation subroutines to execute, based on the current status of Mode. A subroutine will put the next desired pattern into the LightMap variable. Then the main loop writes the lower four bits of LightMap to the P0, P1, P2, and P3 ports, which are wired to the SSR4 board and then to the Christmas light strings.


Listing 3.

' Responds to interrupt on Pin 20, increments current mode
ChangeMode:

	If (In(20) = 0) Then
		
		Dim k As Byte	
	
		Incr Mode
		If (Mode > 4) Then Mode = 0

		' Beeps the number of times that correspond to current mode
		For k = 0 To Mode
			Beep 48, 30
			Delay 250
		Next

		Delay 500
	Endif
Return

In Listing 3 the external interrupt connected to the pushbutton is used to increment the Mode variable. It then beeps the piezo speaker one through five times, depending on the value of Mode. Then it waits for a short time to minimize double presses and contact bounce.


Listing 4

Expander:
' Sequences light one by one from port 0 to port 3, then repeats

	LightMap = LightMap << 1 ' Shift left
	
	If (LightMap.NIB0 = 0) Then LightMap =
Personal tools