Introduction:
The music visualizer is our final project for EECS 373. The idea behind the project was to create a device that simulated the the sound of music with visual affects. The main goal was to get a round platform covered with LEDs to spin on a motor and light up to the beat of the bass of music. To do this we were to use a simple circuit, an ADC and a processor.
High Level Design:
The basic functionality of the project involved taking a filtered signal and converting it to a digital signal. We then took that signal and compared it to a threshold value. If it was greater than the threshold value we would turn our lights sequence on. The light sequence involved one row being lit first then the next row and then the next to give the pulsing illusion. We also implemented control of the motor with a button. The button could be pushed once to turn the motor on, one more time to speed it up, and then once more to turn it off. Here is a high level diagram of our project:
Member Task Distribution
Joshua DelCastillo:
-Created all necessary circuits: LED Switches, Motor Control, Low Pass Filter, LED circuit
-Design hardware in Xilinx: ADC, Motor Control, Address Decoding
-Mechanics of spinning platform circuit, motor base
Tommie McAfee:
-Design software to work with hardware: Two processor timers, interrupts, ADC conversion
-Design hardware in Xilinx: LED control, Address, Decoding
Hardware Design
The hardware for this project consisted mainly of four things:
-MPC823 processor
-LED control
-Motor control
-ADC control
-Low Pass Filter
For timing we used both of the processor's timers. We would have added an LCD display to display the mode of the device but time did not allow this to happen. The LED control was basically implemented by writing or reading to a certain address. Writes would make the LEDs turn on and, reads would make them turn off. We had three individual rows of LEDs to control. To do this we made three switches. The major problem that we came across was the fact that all the LEDs shared the same ground. This made the switches a little more difficult to design. We ended up using pull down resistors with a FET switch controlled by our signal from the processor. A similar circuit minus the pull down resistor was used to control the motor. Both the motor and the LEDs were designed to be active low. The low pass filter was created with a few resistors, capacitors and an op amp. The cutoff frequency that we used was 50 Hz, which is in the middle of the range of music bass. The filtered music signal was then sent to the ADC for the software to handle.
Software Design
The software that controls our project is composed mainly of two timers running within a main loop. The first timer is used to schedule the sampling of audio to digital conversions with the ADC, and the second regulates the width of pulses being sent to the motor for controlling its speed. Another main functionality of the software was the code that handles EOC (end of conversion) interrupts because this is where the sampled data is tested for generating display to the LED's. lastly, the motor and 3 rows of lights followed the simple functionality of recognizing writes to their address's as being a '1' and reads as being a '0'. The first timer was set up to sample an audio signal at 60 kHz, which in a sense is over sampling for a song playing with a frequency of 44 kHz, but we found that redundant values were useful in our implementation. When a signal is converted in the ADC, the EOC bit is asserted and sends a level 4 interrupt to the core. The EOC's ISR takes this digital value and compares it to a pre-set threshold and if the data received is higher than the threshold, the lights are activated. The reason why redundant values helped is that it gave the perception that the lights had some type of hold time when they were displaying and not blinking too fast to recognize as being 'ON'. Also, when a light is activated, the TCN register is monitored to allow more of a 'hold time' in the lights, by causing them to wait for the value in TCN to change 6 times before going off. Using timer1 for both sampling and as a means for controlling the hold time of the lights caused several problems that forced us to change the way we activated the lights. Initially we wanted to turn on the outer row of lights, and have that 'ON' value propagate to the middle row, and finally to the inner row. First we tried to implement this in hardware by simply delaying the signal that's being sent to each individual row, but it would've take too many states to have the signal wait 1 second before traversing to the next row of lights. So we resolved to use the software to control the delay by creating a variable in memory that counted from 1-3 and basically activated whatever row of lights the variable specified. The following algorithm resulted:
lightVal=1
-write to light1 address (turns on led1)
-hold for 6 counts of TCN1
-lightVal++
-read from light1 address(turns off led1)
-write to light2 address(turns on led2)
-hold for 6 counts of TCN1
-light Val++
...etc
The problem with this is that TCN1 is also controlling the sampling rate of the ADC, and new EOC's were being sent before the lights were done dancing. Because of this we resolved to turn all of the lights ON at the same time to ensure that they all will be displayed in sync and then turn them off out of sync, (i.e the inner row goes off first then middle row, and then the outer). While this method worked when tested on the FPGA's LED's, it couldn't be noticed on the music visualizer because of the strobe effect of turning them all on at the same time. Lastly, timer2 couldn't be used to control the lights because it was used to control the speed of the motor, but in the end we achieved our design goal of flashing the lights for a noticeable amount of time whenever the analog signal reached a certain threshold by receiving redundant values from the ADC and applying a hold time to the values.
As mentioned above Timer2 was used to implement pulse width modulation for the motor, which in short is a method of controlling the mean voltage sent to the motor. When the user presses s1, an external interrupt is sent on irq1 and causes the motor to start at full speed. Pressing s1 again slows the motor to 'medium' speed, which is controlled by timer2 in software. There are two functions that change the duty cycle of the signal sent to the motor called slowInit and fastInit. The function fastInit changes the Pre-scaler in TMR2 from 0x7f to 0x50 and sends a 1 to the motor address. When the TCN reaches 0x50 the ref bit is set in TER and the motors ISR runs slowInit, which resets to Pre-scaler in TMR2 back to 0x7f and sends a 0 to the motor. The ISR will run fastInit the next time it is run based on the global variable motorMode stored in memory. This allowed us to send a pulse less than a 50% duty cycle to the motor to cause it to spin at a medium speed at the users requests.
Results of the Design
The major difficulty that we experienced was with the mechanics of the spinning circuit. We were using small pieces of tin to transfer the current from the board to the spinning platform. These small pieces of tin caused a lot of friction which prevented the motors to spin. We solved this by using a motor form a remote control car.
Our initial design included a small LCD to display the mode of the visualizer. This was not completed due to time constraints for the project. However everything else did work in the end. The LEDs were not as bright as we wanted, but the affect was definitely visible.
Conclusions
In conclusion our initial design did end up working. However it did make a lot of noise that may draw attention away from the music. If we were to do this again we would probably use some sort of commutator to transfer the current to the spinning platform. A lot more options in software would probably be added. We would probably add different modes for the blinking lights. We definitely would add a LCD screen to display the mode of the device also.


