Difference between revisions of "S17: Boom-Z Equalizer"
Proj user14 (talk | contribs) (→Boom-Z Equalizer) |
(→Grading Criteria) |
||
(73 intermediate revisions by one other user not shown) | |||
Line 1: | Line 1: | ||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
== <span style="color:blue"><b>Boom-Z Equalizer</b></span> == | == <span style="color:blue"><b>Boom-Z Equalizer</b></span> == | ||
− | <center>[[File:CmpE244 S17 TZFORCE done.gif|500px]]</center> | + | <center>[[File:CmpE244 S17 TZFORCE done.gif|border|500px]]</center> |
== Abstract == | == Abstract == | ||
Line 23: | Line 11: | ||
== Objectives & Introduction == | == Objectives & Introduction == | ||
− | |||
=== Introduction === | === Introduction === | ||
Line 221: | Line 208: | ||
== Design & Implementation == | == Design & Implementation == | ||
− | + | In this section we provide an overview of our design methodology for the equalizer and LED matrix individually and then we look at the integration of the two. | |
=== Hardware Design === | === Hardware Design === | ||
Line 231: | Line 218: | ||
The board design is very straight forward. The strobe and reset sources are driven at the same time to both MSGEQ7 chips; left and right audio input are split to each designated MSGEQ7 chip. The output for both chips are fed into the ADC inputs of the SJSUOne board. Voltage regulators are added to power the equalizer system and the SJSUOne board using one DC adapter. The tricky part was to write the software driver to parse the frequency outputs which will be discussed in the software implementation below. | The board design is very straight forward. The strobe and reset sources are driven at the same time to both MSGEQ7 chips; left and right audio input are split to each designated MSGEQ7 chip. The output for both chips are fed into the ADC inputs of the SJSUOne board. Voltage regulators are added to power the equalizer system and the SJSUOne board using one DC adapter. The tricky part was to write the software driver to parse the frequency outputs which will be discussed in the software implementation below. | ||
− | + | [[File:CMPE244_S17_TeamZ_equalizer_schematic.PNG|none|frame|500px|Equalizer schematic]] | |
− | |||
− | [[File:CMPE244_S17_TeamZ_equalizer_schematic.PNG]] | ||
==== LED Matrix ==== | ==== LED Matrix ==== | ||
The LED matrix went through multiple changes throughout the project, but those will be discussed in the ''Testing & Technical Challenges'' section. | The LED matrix went through multiple changes throughout the project, but those will be discussed in the ''Testing & Technical Challenges'' section. | ||
+ | |||
+ | [[File:CmpE244 S17 TZFORCE LEDModule.png|thumb|200px|left|APA102C LED module cut from a strip with wires soldered on]] | ||
+ | A PCB was designed to solder each LED via a plated through-hole. This was done because the LEDs come in a strip that needed to be cut to separate them. It was then possible to solder wires onto each of the copper pads to make the legs of the LED module. | ||
− | + | Since the actual APA102C module was already soldered onto the LED strip, we had to create our own library module for the PCB board. | |
+ | To do this we: | ||
+ | # Created the symbol. The symbol is the image that is displayed on the schematic. | ||
+ | # Created the package which is the physical representation of the part. Also known as the footprint. This is also where you assign names to your pins. | ||
+ | # Created the device which combines the symbol and the package data. | ||
− | [[File: | + | [[File:CmpE244 S17 TZFORCE LEDLib.png|thumb|350px|right|LED module library <br> Left: Device Center: Package Right: Symbol]] |
+ | [[File:CmpE244 S17 TZFORCE LEDSchematic.PNG|left|thumb|350px|Schematic for the LED matrix]] | ||
+ | [[File:CmpE244 S17 TZFORCE LEDDesign.PNG|thumb|350px|right|LED matrix completed PCB design]] | ||
+ | [[File:CmpE244 S17 TZFORCE LEDSchemCloseup.PNG||left|thumb|350px|Close up of components on schematic]] | ||
− | + | Once our library was created, we began the PCB design. We opened the schematic alongside the board layout, to ensure that everything was updated at the same time, and added our LED module library to the schematic by choosing Library → Use. | |
− | + | From there, it was a matter of placing the modules onto the schematic and routing them on the board. We used the | |
− | + | ''polygon tool'' to select the entire board to place one copper plane for our VCC and the same was done with ground. We were able to verify the routing via the ''Ratsnest tool''. | |
− | |||
− | + | Once the design was complete, we ran the DRC (design rule check) and ERC (electrical rule check) to ensure that our design was done properly. | |
+ | In addition to the default DRU, we used the OshPark DRU as an extra test. | ||
− | + | The PCB was also verified by Bay Area Circuits when we placed the order. It took about a week for the board to be completed. | |
+ | |||
+ | Overall, our PCB design consists of the following: | ||
+ | * 98 LEDs (7x14) that make up our matrix using our own library | ||
+ | * 2 Sets of header pins (connected) for VCC, data in, ground, and SCK | ||
+ | ** This was added as an extra precaution since it is a high current drawing device, in case of pin damage | ||
+ | * 14 surface mount capacitors | ||
+ | ** In case of signal stability (voltage drops) to help stabilize our design. We ended up not needing to add these. | ||
+ | * 4 through-holes on each corner for stand-offs | ||
=== Hardware Interface === | === Hardware Interface === | ||
− | |||
− | The Equalizer board is driven using 4 GPIO pins. Two pins are used for left and right strobe pins, while the other two are used for resetting each <b>MSGEQ7</b> chips. | + | The Equalizer board is driven using 4 GPIO pins. |
+ | Two pins are used for left and right strobe pins, while the other two are used for resetting each <b>MSGEQ7</b> chips. | ||
2 ADC pins are used to read the chips' analog outputs. | 2 ADC pins are used to read the chips' analog outputs. | ||
SJSUOne board's SPI interface was used to drive the LED matrix. | SJSUOne board's SPI interface was used to drive the LED matrix. | ||
− | + | [[File:CMPE244_S17_TZFORCE_hardware_interface.png|none|frame|500px|Hardware interface]] | |
− | |||
− | |||
− | [[File:CMPE244_S17_TZFORCE_hardware_interface.png]] | ||
=== Software Design === | === Software Design === | ||
− | |||
− | |||
The Equalizer task reads analog values from the Equalizer Board and converts them into LED Matrix representation values. The analog input values are converted to digital using the onboard ADC. The converted values are then sent to the queue which the Matrix LED driver task is listening. The Matrix LED driver interprets the data and drives the LEDs to display the appropriate signal representation. | The Equalizer task reads analog values from the Equalizer Board and converts them into LED Matrix representation values. The analog input values are converted to digital using the onboard ADC. The converted values are then sent to the queue which the Matrix LED driver task is listening. The Matrix LED driver interprets the data and drives the LEDs to display the appropriate signal representation. | ||
− | + | [[File:CMPE244_S17_TZFORCE_software_diagram.png|none|frame|Integrated Software diagram]] | |
− | |||
− | |||
− | [[File:CMPE244_S17_TZFORCE_software_diagram.png]] | ||
=== Implementation === | === Implementation === | ||
− | |||
==== Equalizer ==== | ==== Equalizer ==== | ||
The <b>MSGEQ7</b> chip has a unique way of outputting the analog signals (as shown in the strobe timing diagram below). The software needs to drive the GPIO pins to generate the <b>strobe</b> signal. The strobe signal is needed to be precisely controlled in order to read the analog outputs properly. Fortunately, the chip doesn't have a very strict timing and only has minimum values for signal widths. | The <b>MSGEQ7</b> chip has a unique way of outputting the analog signals (as shown in the strobe timing diagram below). The software needs to drive the GPIO pins to generate the <b>strobe</b> signal. The strobe signal is needed to be precisely controlled in order to read the analog outputs properly. Fortunately, the chip doesn't have a very strict timing and only has minimum values for signal widths. | ||
− | + | [[File:CMPE244_S17_TZFORCE_strobe_timing_diagram.PNG|none|frame|Strobe timing diagram]] | |
− | |||
− | [[File:CMPE244_S17_TZFORCE_strobe_timing_diagram.PNG]] | ||
<p> | <p> | ||
Line 309: | Line 301: | ||
==== LED Matrix ==== | ==== LED Matrix ==== | ||
− | < | + | To properly display on the LED matrix the received data from the equalizer the SPI communication bus must first be configured. The SPI protocol is what we used to send frequency data to LEDs. The SPI bus was configured to operate at 12mHz thus providing an ample refresh rate for the LED matrix. To send valid data to the LED, the Apa-102c is designed to initially receiving a 'start' over the MOSI line consisting of 32 bits of 0's.This is followed by a an N number of LED frames consisting of 3 bits of 1's ,followed by a 5 bit brightness setting and then 8 bits of blue,green and red values. This is then followed by an 'end' frame consisting of 1's totaling # of LEDs/2. So, in our case of of 98 leds we had to send a total of 48 '1' bits. The end frame is needed to properly update the LEDs since each LED drives the MOSI data line low to properly latch onto the value. This creates the issue where the data is behind the clock, so extra clock cycles are needed to update the LEDs. |
+ | |||
+ | |||
+ | Since the LED's are linked in series the LED task consists of only one 'start' frame and 'end' frame followed by 98 LED frames. With the LED strip starting anew every time frequency data is sent on the queue. The frequency data consists of 2 arrays left and right with 7 elements representing a single frequency band each with values ranging from 0 - 7, . The values determine how many LEDs are turned on for each column. Since we are treating the LED matrix as a 1-D array and we know that there are 14 LEDs for every 2 columns, we send a number of 'off' frames for the LEDs sandwiched between the same frequency band , creating the illusion that they are separate columns. This is described in the code snippet below. | ||
+ | |||
+ | <pre>//Code snippet of LED Matrix Driver | ||
+ | startFrame(); | ||
+ | |||
+ | for (int a = 0; a < 7; a++) { | ||
+ | |||
+ | sendLEDFrame(frequencyData.left[a], leftSpeaker[a]); | ||
+ | |||
+ | uint8_t num = numEmptyFrames(frequencyData.left[a], | ||
+ | frequencyData.right[a]); | ||
+ | |||
+ | if (num > 0) { | ||
+ | |||
+ | sendEmptyFrames(num); | ||
+ | } | ||
+ | |||
+ | sendLEDFrame(frequencyData.right[a], rightSpeaker[a]); | ||
+ | } | ||
+ | endFrame(); | ||
+ | }</pre> | ||
+ | |||
+ | ==== LED Matrix - IDLE State ==== | ||
+ | |||
+ | We decided to create an IDLE state in the absence of data from the equalizer. To detect whether or or not we should go in IDLE mode we check if at least 6 inputs are 0 for 5 consecutive seconds . This reduces the possibility of noise disrupting our IDLE state. The IDLE state itself consists of scrolling text followed by the American Flag. The scrolling text is highly customizable any character can be displayed as we created a library of characters which consists of a 7x4 uint8_t array. In our case for the videos and demo "Hi PREET" is shown. In the case of the IDLE state we use a 7 x 14 2-D array but traverse through it as if it was a 1-D array due to our series linked LED this makes copying the characters much easier. To create the scrolling text effect, we shift each LED column's value to the left and then copy the column of the character. This is done 4 times to successfully copy a character as each character is a 7 x 4 array. The code snippet below shows this. | ||
+ | |||
+ | |||
+ | <pre>//Code snippet of Scrolling Text | ||
+ | |||
+ | switch (lettersWritten) { | ||
+ | case 0: | ||
+ | copyAndShift(H, shiftCount); | ||
+ | break; | ||
+ | case 1: | ||
+ | copyAndShift(I, shiftCount); | ||
+ | break; | ||
+ | case 2: | ||
+ | copyAndShift(space, shiftCount); | ||
+ | break; | ||
+ | case 3: | ||
+ | copyAndShift(P, shiftCount); | ||
+ | break; | ||
+ | case 4: | ||
+ | copyAndShift(R, shiftCount); | ||
+ | break; | ||
+ | }</pre> | ||
+ | |||
+ | |||
+ | <center>[[File:CmpE244 S17 TZFORCE idle.gif|border|400px]]</center> | ||
== Testing & Technical Challenges == | == Testing & Technical Challenges == | ||
− | + | In this section we review the testing procedures used to test the equalizer circuitry, the LED matrix, and the integrated system. We also go over some technical challenges we experienced throughout the project and how we were able to resolve the issues. | |
− | |||
− | |||
− | |||
=== Testing === | === Testing === | ||
==== Equalizer ==== | ==== Equalizer ==== | ||
− | The team used | + | [[File:CMPE244_S17_TZFORCE_MSGEQ7_frequency_response.PNG|left|thumb|350px|Frequency response]] |
+ | [[File:CMPE244_S17_TZFORCE_400Hz_logic_analyzer.PNG|right|thumb|350px|400 Hz output from the logic analyzer]] | ||
+ | The team used Saleae Logic Analyzer and an online frequency generator to test the equalizer. The output of the logic analyzer must match the <b>MSGEQ7</b>'s frequency response. Notice that the output would not give a perfect filtered value but a half-waveform that peaks at the target frequency. | ||
− | + | This same testing was done using an oscilloscope to view the waveforms that were output from the equalizer circuity. By testing the equalizer this way, we knew exactly what to expect. From the logic analyzer and oscilloscope output, we knew exactly what or LED matrix output should look like. We were able to verify our LED matrix driver using the same method. | |
− | |||
− | + | ==== Testing the LED Matrix ==== | |
− | |||
− | + | * Phase 1: Testing the strip | |
− | + | ||
+ | [[File:CmpE244 S17 TZFORCE LEDTest.jpg|right|thumb|200px|Test set up for the LED strip]] | ||
+ | We began by testing the entire strip as soon as we received them. We first referred to the datasheet to learn how the LEDs worked and how to use them. | ||
+ | In addition to testing the LEDs for functionality, tried to figure out the maximum current needed to power the LEDs to ensure we would be able to supply enough current. | ||
+ | This was done doing the following: | ||
+ | # Hook up the LEDs to power supply set to 5v with current output turned all the way down. | ||
+ | # Set task to set 98 of the LEDs to maximum brightness and white (RGB- 255,255,255). | ||
+ | # Slowly supply current. | ||
+ | |||
+ | The reason we chose to only use 98 of the 144 LEDs is because we were already expecting to use only 98. The reasoning for this test was that if we set the LEDs to maximum brightness and the color white, that should require the most amount of current to drive them. Since we are not expecting to ever have all of our LEDs at maximum brightness and have all of them white at the same time, we can ensure that no matter what power configuration we choose, as long as it supports the worst case, we will be able to power the LEDs. | ||
− | + | * Phase 2: Testing the completed LED matrix | |
+ | Before testing the entire system with the equalizer integrated, we tested the LED matrix to ensure they would work. | ||
+ | We tested different configurations - turn on all of the LEDs, turn on the LEDs by column, turn on all of the LEDs where each column is a different color. | ||
− | [[File:CmpE244 S17 TZFORCE 1kHzTest.png|300px]] | + | [[File:CmpE244 S17 TZFORCE 1kHzTest.png|left|thumb|300px|1kHz frequency test]] |
+ | * Phase 3: Integration testing | ||
+ | Once we were satisfied that the LEDs were working properly, we integrated the equalizer and tested the matrix. We supplied the equalizer circuit with different frequencies, in once case use tested 1 kHz, and hooked up the Saleae Logic analyzer to the system to compare the output of the LED matrix to the output captured on the logic analyzer. | ||
+ | The test was satisfied when the images from the logic analyzer and the LED matrix were a match. | ||
=== Technical Challenges === | === Technical Challenges === | ||
− | ==== Equalizer | + | ==== Equalizer Challenges ==== |
− | * Generating strobe and reading the ADC values need precise timing. One missed reading will | + | * Generating strobe and reading the ADC values need precise timing. One missed reading will mess up the data representation of the frequency values. |
** Using digital analyzer greatly helped the team debug the timing issues. | ** Using digital analyzer greatly helped the team debug the timing issues. | ||
* The <b>MSGEQ7</b> chip is very sensitive to noise. In reality, this chip wouldn't perfectly filter-out the surrounding frequencies; thus we should look only to whether or not the target frequency has the highest output voltage. | * The <b>MSGEQ7</b> chip is very sensitive to noise. In reality, this chip wouldn't perfectly filter-out the surrounding frequencies; thus we should look only to whether or not the target frequency has the highest output voltage. | ||
− | ** Using online frequency generators, together with the logic analyzer, helped the team debug the system. | + | ** Using online frequency generators, together with the logic analyzer, helped the team debug the system. |
− | ==== LED Matrix Design ==== | + | ==== LED Matrix Design Challenges ==== |
+ | [[File:CmpE244_S17_TZFORCE_LED Layout Rev_1.jpg|left|thumb|250px|LED matrix - Rev 1]] | ||
* Not all LEDs are created equal. The first set of LEDs that we bought used a non-standard communication protocol with very precise timing (in nanoseconds) | * Not all LEDs are created equal. The first set of LEDs that we bought used a non-standard communication protocol with very precise timing (in nanoseconds) | ||
− | ** The team decided to move on and use a different kind of LEDs which | + | ** The team decided to move on and use a different kind of LEDs which uses a standard SPI protocol |
* Soldering LEDs is very time consuming and prone to mistakes. | * Soldering LEDs is very time consuming and prone to mistakes. | ||
− | ** Since we can't solder them earlier as expected, the team decided to create a back-up LED matrix board just in case the main LED matrix | + | ** Since we can't solder them earlier as expected, the team decided to create a back-up LED matrix board just in case the main LED matrix didn't work. |
− | + | [[File:CmpE244_S17_TZFORCE_LED Layout Rev_2.jpg|right|thumb|250px|LED matrix - Rev 2]] | |
+ | [[File:CmpE244_S17_TZFORCE_LED Layout Rev_3.jpg|left|thumb|250px|LED matrix - Rev 3]] | ||
+ | |||
+ | Designing the LED matrix is where majority of our heartaches and troubles began and was actually the part that taught us the most. | ||
+ | We learned that: | ||
+ | # Keep it simple. | ||
+ | # Use the tools that are given to you. | ||
+ | # You can become an expert at soldering if you decide to do this project too! | ||
+ | |||
+ | The issues began when we decided that we wanted to manually create our own LED matrix. Since the LEDs were already soldered onto the strip, we had to cut each LED apart. This greatly reduced the size of the copper padding so it made it very difficult to solder. Not only was it difficult to solder, but it was very fragile. Many of the wires that were soldered onto the copper pads either fell off or ripped off the copper padding which rendered the LED unusable (we threw out a lot). This issue was actually solved by removing the entire wire casing and soldering them onto the LED modules since the wire was thin enough (26 AWG) to be flexible and not cause too much tension when bending them. | ||
+ | |||
+ | Even though we were dedicated to creating our own matrix, this taught us that as engineers, we should ''use the tools that are provided to us''. In our case, this was creating our own PCB. There was still a lot of work left with having to soldering 98 LEDs (by this time, since we decided not to use the original matrix we started, we had to order another strip and ''re-solder all 98 LEDs''). The reason we didn't re-use the LEDs we originally soldered and cut was because they were too fragile to take apart. It would have ended up taking much more time removing the wire casing from about 800 wires and losing more than half the LEDs (not even including the half we already lost) than to just solder them completely new. | ||
+ | |||
+ | ==== Assembling Difficulties ==== | ||
+ | [[File:CmpE244 S17 TZFORCE assembled.jpg|right|thumb|250px|Everything placed inside shadowbox]] | ||
+ | Once everything was completed and tested, we needed to place the following into the shadowbox: | ||
+ | * SJOne board | ||
+ | * Equalizer PCB | ||
+ | * LED matrix | ||
+ | * 25W Power supply | ||
+ | * Power strip | ||
+ | |||
+ | We had to place all of the contents into the shadowbox and ensure that nothing would come loose and possibly damage other parts in the box. We used zip ties to secure the circuits. We also had to worry about the power supply. To ensure the wires would not be exposed, we used electrical to tape to cover any of the exposed wires. In addition, we used velcro strips to secure the power supply in an upright position on the side of the box to ensure that it would not move. We used a similar method to fit the power strip. Velcro was placed onto the unused side of the power strip and it was secured to the top of the box. We zip tied all cords to keep everything compact and in the end, we were able to fit all of the contents into the box and secure it. | ||
== Conclusion == | == Conclusion == | ||
− | + | In conclusion, we were able to complete our project, but ultimately we learned the most by fighting through the process of creating it. We learned how important it is to test everything iteratively, not just once it was complete. Since we tested each part separately, when we integrated the systems there were very few things we needed to fix. | |
+ | We also learned how important it is to use as many tools that will help us not only for testing like the logic analyzer, but for implementation and design choices as well. If we had designed the LED matrix as a PCB from the beginning, we could have saved ourselves from having to solder an extra 100 LEDs (that's 200 LEDs and 1600 wires soldered total). In addition, this project taught us a lot about not only what it means to be an engineer, but to be better people within a group dynamic. In the end, the interactions we have with our groups are going to be similar to what we will have in the work place. This is a really invaluable time for us to learn what it means to be a part of a team and to learn how to become a better team player, when to learn to follow instructions, and learn when to step up and become a leader. | ||
=== Project Video === | === Project Video === | ||
− | + | https://www.youtube.com/watch?v=eeXu6h_fcvs | |
=== Project Source Code === | === Project Source Code === | ||
Line 361: | Line 439: | ||
== References == | == References == | ||
=== Acknowledgement === | === Acknowledgement === | ||
− | + | A sincere thanks to Preetpal Kang for the knowledge he provided us throughout the semester to not only drive us, but to provide us with the knowledge to create something amazing and to Charles MacDonald, for all his help with answering questions and always challenging us with questions. | |
=== References Used === | === References Used === | ||
− | + | * [https://cpldcpu.files.wordpress.com/2014/08/apa-102c-super-led-specifications-2014-en.pdf APA102C Datasheet] | |
+ | * [https://www.sparkfun.com/datasheets/Components/General/MSGEQ7.pdf MSGEQ7 Datasheet] | ||
+ | * [https://learn.sparkfun.com/tutorials/using-eagle-board-layout Sparkfun PCB Tutorial] | ||
=== Appendix === | === Appendix === | ||
− | + | * [http://www.szynalski.com/tone-generator/ Tone Generator] |
Latest revision as of 03:51, 2 June 2017
Contents
Boom-Z Equalizer
Abstract
The purpose of this project is to allow the team to experiment with a sound reactive project. The team will use a specialized IC to convert the input audio signal into a digital signal that can be parsed by the SJSUone board. The team will also create the LED array grid that will be used to display the waveform/frequency representation of the audio signal. The final project should be able to take an input audio signal (using a regular audio cable/jack) and display some kind of frequency representation using the LED array grid.
Objectives & Introduction
Introduction
The team split the project into two parts: The equalizer and the LED Matrix part. Thus, the team split into two sub-teams to tackle these two parts separately. The Equalizer task focuses on the conversion of audio input into an ADC output that can be parsed and create a data representation for the LED Matrix task. The LED Matrix task's main focus is to parse the converted data and drive the LEDs to display the appropriate representation of the signals.
Objectives
Follow proper engineering and testing practices to design and implement the following:
- Design equalizer hardware
- Design equalizer PCB
- Design LED Matrix hardware
- Design overall software architecture
- Implement equalizer driver
- Implement LED matrix driver
- Integrate equalizer and LED matrix
- Test overall system
Team Members & Responsibilities
- David Bui
- Equalizer Hardware Design
- Equalizer PCB Design
- Marvin Flores
- Overall software design
- Equalizer driver
- Adam Iglesias
- LED Matrix driver
- Mina Yi
- LED Matrix hardware design
Schedule
Week# | Date | Task | Actual |
---|---|---|---|
1 | 3/19 |
|
|
2 | 3/26 |
|
|
3 | 4/2 |
|
|
4 | 4/9 |
|
|
5 | 4/16 |
|
|
6 | 4/23 |
|
|
7 | 4/30 |
|
|
8 | 5/7 |
|
|
9 | 5/14 |
|
|
10 | 5/21 |
|
|
Parts List & Cost
Bill of Materials for Graphic Equalizer
# | Name | Purchase Location | Description | Quantity | Cost |
---|---|---|---|---|---|
1 | MSGEQ7 | DigiKey | 7 Band Graphic Equalizer | 2 | $4.95 |
2 | capacitor | HSC Electronics | .1 uF capacitor | 7 | $0.35 |
3 | capacitor | HSC Electronics | 33 pF capacitor | 2 | $0.40 |
4 | capacitor | HSC Electronics | .33 uF capacitor | 1 | $0.35 |
5 | capacitor | HSC Electronics | 10 uF capacitor | 1 | $0.35 |
6 | capacitor | HSC Electronics | 100 nF capacitor | 1 | $0.35 |
7 | resistor | HSC Electronics | 200kΩ resistor | 2 | $0.05 |
8 | resistor | HSC Electronics | 22kΩ resistor | 2 | $0.05 |
9 | power jack | HSC Electronics | power jack | 1 | $0.45 |
10 | audio jack | HSC Electronics | audio jack | 1 | $0.45 |
11 | voltage regulator | HSC Electronics | 3V voltage regulator | 1 | $0.25 |
12 | voltage regulator | HSC Electronics | 5V voltage regulator | 1 | $0.25 |
13 | male header pins | HSC Electronics | male header pins | 1 | $0.95 |
Bill of Materials for LED Matrix
# | Name | Purchase Location | Description | Quantity | Cost per item |
---|---|---|---|---|---|
1 | LED Strip | Amazon | APA102C LEDs | 1 | $29.88 |
2 | PCB | Bay Area Circuits | 9.6" x 5" | 1 | $30 |
3 | Shadowbox | Michaels | 10" x 10", 4.5" depth | 1 | $32.99 |
4 | Thin Plywood | Home Depot | 9.5" x 9.5" | 1 | Varies |
5 | Power Supply | Amazon | Mean Well 5v 5A power supply | 1 | $13.22 |
6 | 3 Pronged Power Cord | Home Depot | Husky 8ft 3 pronged power replacement cord | 1 | $9.97 |
Design & Implementation
In this section we provide an overview of our design methodology for the equalizer and LED matrix individually and then we look at the integration of the two.
Hardware Design
Graphic Equalizer
The main purpose of the graphic equalizer is to be able to take an audio input and generate an ADC output signal. The output values will be used to drive the LED Matrix values. The team decided to use MSGEQ7 chip for its simple design and ease of use. The MSGEQ7 Graphic equalizer can take an audio signal and 'split' it into 7 different frequencies. The team used two MSGEQ7 chips to separate left and right audio signal; this allowed the team to have more column of frequencies to display in the LED matrix.
The board design is very straight forward. The strobe and reset sources are driven at the same time to both MSGEQ7 chips; left and right audio input are split to each designated MSGEQ7 chip. The output for both chips are fed into the ADC inputs of the SJSUOne board. Voltage regulators are added to power the equalizer system and the SJSUOne board using one DC adapter. The tricky part was to write the software driver to parse the frequency outputs which will be discussed in the software implementation below.
LED Matrix
The LED matrix went through multiple changes throughout the project, but those will be discussed in the Testing & Technical Challenges section.
A PCB was designed to solder each LED via a plated through-hole. This was done because the LEDs come in a strip that needed to be cut to separate them. It was then possible to solder wires onto each of the copper pads to make the legs of the LED module.
Since the actual APA102C module was already soldered onto the LED strip, we had to create our own library module for the PCB board. To do this we:
- Created the symbol. The symbol is the image that is displayed on the schematic.
- Created the package which is the physical representation of the part. Also known as the footprint. This is also where you assign names to your pins.
- Created the device which combines the symbol and the package data.
Once our library was created, we began the PCB design. We opened the schematic alongside the board layout, to ensure that everything was updated at the same time, and added our LED module library to the schematic by choosing Library → Use.
From there, it was a matter of placing the modules onto the schematic and routing them on the board. We used the polygon tool to select the entire board to place one copper plane for our VCC and the same was done with ground. We were able to verify the routing via the Ratsnest tool.
Once the design was complete, we ran the DRC (design rule check) and ERC (electrical rule check) to ensure that our design was done properly. In addition to the default DRU, we used the OshPark DRU as an extra test.
The PCB was also verified by Bay Area Circuits when we placed the order. It took about a week for the board to be completed.
Overall, our PCB design consists of the following:
- 98 LEDs (7x14) that make up our matrix using our own library
- 2 Sets of header pins (connected) for VCC, data in, ground, and SCK
- This was added as an extra precaution since it is a high current drawing device, in case of pin damage
- 14 surface mount capacitors
- In case of signal stability (voltage drops) to help stabilize our design. We ended up not needing to add these.
- 4 through-holes on each corner for stand-offs
Hardware Interface
The Equalizer board is driven using 4 GPIO pins. Two pins are used for left and right strobe pins, while the other two are used for resetting each MSGEQ7 chips. 2 ADC pins are used to read the chips' analog outputs. SJSUOne board's SPI interface was used to drive the LED matrix.
Software Design
The Equalizer task reads analog values from the Equalizer Board and converts them into LED Matrix representation values. The analog input values are converted to digital using the onboard ADC. The converted values are then sent to the queue which the Matrix LED driver task is listening. The Matrix LED driver interprets the data and drives the LEDs to display the appropriate signal representation.
Implementation
Equalizer
The MSGEQ7 chip has a unique way of outputting the analog signals (as shown in the strobe timing diagram below). The software needs to drive the GPIO pins to generate the strobe signal. The strobe signal is needed to be precisely controlled in order to read the analog outputs properly. Fortunately, the chip doesn't have a very strict timing and only has minimum values for signal widths.
The code below shows the ADC reading implementation. As shown, the task loops for 7 times to read 7 different frequencies (for left and right outputs.) A struct was used to represent the frequency values and to make it easier to send to a queue. Take note that the reading only occurs when the strobe pins are driven low. In order to read the next frequency, the strobe pins need to be driven high and then low again.
Code snippet for(int i = 0; i<7; i++) { clear_pin(STROBE_PIN_LEFT); //Clear Strobe_Pin 2.0 clear_pin(STROBE_PIN_RIGHT); //Clear Strobe_Pin 2.2 current_time_us = sys_get_uptime_us() + 36; while(sys_get_uptime_us() < current_time_us); uint16_t leftRawValue = readPinValueP026(); uint16_t rightRawValue = readPinValueP131(); frequencyData.left[i] = convertSignalToMatrixReadable(leftRawValue); frequencyData.right[i] = convertSignalToMatrixReadable(rightRawValue); set_pin(STROBE_PIN_LEFT); //Set Strobe_Pin 2.0 set_pin(STROBE_PIN_RIGHT); //Set Strobe_Pin 2.2 current_time_us = sys_get_uptime_us() + 36; while(sys_get_uptime_us() < current_time_us); }
After this loop, the frequencyData is sent to a queue. The LED Matrix tasks listen to this queue and process the received data to drive the LED Matrix display.
LED Matrix
To properly display on the LED matrix the received data from the equalizer the SPI communication bus must first be configured. The SPI protocol is what we used to send frequency data to LEDs. The SPI bus was configured to operate at 12mHz thus providing an ample refresh rate for the LED matrix. To send valid data to the LED, the Apa-102c is designed to initially receiving a 'start' over the MOSI line consisting of 32 bits of 0's.This is followed by a an N number of LED frames consisting of 3 bits of 1's ,followed by a 5 bit brightness setting and then 8 bits of blue,green and red values. This is then followed by an 'end' frame consisting of 1's totaling # of LEDs/2. So, in our case of of 98 leds we had to send a total of 48 '1' bits. The end frame is needed to properly update the LEDs since each LED drives the MOSI data line low to properly latch onto the value. This creates the issue where the data is behind the clock, so extra clock cycles are needed to update the LEDs.
Since the LED's are linked in series the LED task consists of only one 'start' frame and 'end' frame followed by 98 LED frames. With the LED strip starting anew every time frequency data is sent on the queue. The frequency data consists of 2 arrays left and right with 7 elements representing a single frequency band each with values ranging from 0 - 7, . The values determine how many LEDs are turned on for each column. Since we are treating the LED matrix as a 1-D array and we know that there are 14 LEDs for every 2 columns, we send a number of 'off' frames for the LEDs sandwiched between the same frequency band , creating the illusion that they are separate columns. This is described in the code snippet below.
//Code snippet of LED Matrix Driver startFrame(); for (int a = 0; a < 7; a++) { sendLEDFrame(frequencyData.left[a], leftSpeaker[a]); uint8_t num = numEmptyFrames(frequencyData.left[a], frequencyData.right[a]); if (num > 0) { sendEmptyFrames(num); } sendLEDFrame(frequencyData.right[a], rightSpeaker[a]); } endFrame(); }
LED Matrix - IDLE State
We decided to create an IDLE state in the absence of data from the equalizer. To detect whether or or not we should go in IDLE mode we check if at least 6 inputs are 0 for 5 consecutive seconds . This reduces the possibility of noise disrupting our IDLE state. The IDLE state itself consists of scrolling text followed by the American Flag. The scrolling text is highly customizable any character can be displayed as we created a library of characters which consists of a 7x4 uint8_t array. In our case for the videos and demo "Hi PREET" is shown. In the case of the IDLE state we use a 7 x 14 2-D array but traverse through it as if it was a 1-D array due to our series linked LED this makes copying the characters much easier. To create the scrolling text effect, we shift each LED column's value to the left and then copy the column of the character. This is done 4 times to successfully copy a character as each character is a 7 x 4 array. The code snippet below shows this.
//Code snippet of Scrolling Text switch (lettersWritten) { case 0: copyAndShift(H, shiftCount); break; case 1: copyAndShift(I, shiftCount); break; case 2: copyAndShift(space, shiftCount); break; case 3: copyAndShift(P, shiftCount); break; case 4: copyAndShift(R, shiftCount); break; }
Testing & Technical Challenges
In this section we review the testing procedures used to test the equalizer circuitry, the LED matrix, and the integrated system. We also go over some technical challenges we experienced throughout the project and how we were able to resolve the issues.
Testing
Equalizer
The team used Saleae Logic Analyzer and an online frequency generator to test the equalizer. The output of the logic analyzer must match the MSGEQ7's frequency response. Notice that the output would not give a perfect filtered value but a half-waveform that peaks at the target frequency.
This same testing was done using an oscilloscope to view the waveforms that were output from the equalizer circuity. By testing the equalizer this way, we knew exactly what to expect. From the logic analyzer and oscilloscope output, we knew exactly what or LED matrix output should look like. We were able to verify our LED matrix driver using the same method.
Testing the LED Matrix
- Phase 1: Testing the strip
We began by testing the entire strip as soon as we received them. We first referred to the datasheet to learn how the LEDs worked and how to use them. In addition to testing the LEDs for functionality, tried to figure out the maximum current needed to power the LEDs to ensure we would be able to supply enough current. This was done doing the following:
- Hook up the LEDs to power supply set to 5v with current output turned all the way down.
- Set task to set 98 of the LEDs to maximum brightness and white (RGB- 255,255,255).
- Slowly supply current.
The reason we chose to only use 98 of the 144 LEDs is because we were already expecting to use only 98. The reasoning for this test was that if we set the LEDs to maximum brightness and the color white, that should require the most amount of current to drive them. Since we are not expecting to ever have all of our LEDs at maximum brightness and have all of them white at the same time, we can ensure that no matter what power configuration we choose, as long as it supports the worst case, we will be able to power the LEDs.
- Phase 2: Testing the completed LED matrix
Before testing the entire system with the equalizer integrated, we tested the LED matrix to ensure they would work. We tested different configurations - turn on all of the LEDs, turn on the LEDs by column, turn on all of the LEDs where each column is a different color.
- Phase 3: Integration testing
Once we were satisfied that the LEDs were working properly, we integrated the equalizer and tested the matrix. We supplied the equalizer circuit with different frequencies, in once case use tested 1 kHz, and hooked up the Saleae Logic analyzer to the system to compare the output of the LED matrix to the output captured on the logic analyzer. The test was satisfied when the images from the logic analyzer and the LED matrix were a match.
Technical Challenges
Equalizer Challenges
- Generating strobe and reading the ADC values need precise timing. One missed reading will mess up the data representation of the frequency values.
- Using digital analyzer greatly helped the team debug the timing issues.
- The MSGEQ7 chip is very sensitive to noise. In reality, this chip wouldn't perfectly filter-out the surrounding frequencies; thus we should look only to whether or not the target frequency has the highest output voltage.
- Using online frequency generators, together with the logic analyzer, helped the team debug the system.
LED Matrix Design Challenges
- Not all LEDs are created equal. The first set of LEDs that we bought used a non-standard communication protocol with very precise timing (in nanoseconds)
- The team decided to move on and use a different kind of LEDs which uses a standard SPI protocol
- Soldering LEDs is very time consuming and prone to mistakes.
- Since we can't solder them earlier as expected, the team decided to create a back-up LED matrix board just in case the main LED matrix didn't work.
Designing the LED matrix is where majority of our heartaches and troubles began and was actually the part that taught us the most. We learned that:
- Keep it simple.
- Use the tools that are given to you.
- You can become an expert at soldering if you decide to do this project too!
The issues began when we decided that we wanted to manually create our own LED matrix. Since the LEDs were already soldered onto the strip, we had to cut each LED apart. This greatly reduced the size of the copper padding so it made it very difficult to solder. Not only was it difficult to solder, but it was very fragile. Many of the wires that were soldered onto the copper pads either fell off or ripped off the copper padding which rendered the LED unusable (we threw out a lot). This issue was actually solved by removing the entire wire casing and soldering them onto the LED modules since the wire was thin enough (26 AWG) to be flexible and not cause too much tension when bending them.
Even though we were dedicated to creating our own matrix, this taught us that as engineers, we should use the tools that are provided to us. In our case, this was creating our own PCB. There was still a lot of work left with having to soldering 98 LEDs (by this time, since we decided not to use the original matrix we started, we had to order another strip and re-solder all 98 LEDs). The reason we didn't re-use the LEDs we originally soldered and cut was because they were too fragile to take apart. It would have ended up taking much more time removing the wire casing from about 800 wires and losing more than half the LEDs (not even including the half we already lost) than to just solder them completely new.
Assembling Difficulties
Once everything was completed and tested, we needed to place the following into the shadowbox:
- SJOne board
- Equalizer PCB
- LED matrix
- 25W Power supply
- Power strip
We had to place all of the contents into the shadowbox and ensure that nothing would come loose and possibly damage other parts in the box. We used zip ties to secure the circuits. We also had to worry about the power supply. To ensure the wires would not be exposed, we used electrical to tape to cover any of the exposed wires. In addition, we used velcro strips to secure the power supply in an upright position on the side of the box to ensure that it would not move. We used a similar method to fit the power strip. Velcro was placed onto the unused side of the power strip and it was secured to the top of the box. We zip tied all cords to keep everything compact and in the end, we were able to fit all of the contents into the box and secure it.
Conclusion
In conclusion, we were able to complete our project, but ultimately we learned the most by fighting through the process of creating it. We learned how important it is to test everything iteratively, not just once it was complete. Since we tested each part separately, when we integrated the systems there were very few things we needed to fix. We also learned how important it is to use as many tools that will help us not only for testing like the logic analyzer, but for implementation and design choices as well. If we had designed the LED matrix as a PCB from the beginning, we could have saved ourselves from having to solder an extra 100 LEDs (that's 200 LEDs and 1600 wires soldered total). In addition, this project taught us a lot about not only what it means to be an engineer, but to be better people within a group dynamic. In the end, the interactions we have with our groups are going to be similar to what we will have in the work place. This is a really invaluable time for us to learn what it means to be a part of a team and to learn how to become a better team player, when to learn to follow instructions, and learn when to step up and become a leader.
Project Video
https://www.youtube.com/watch?v=eeXu6h_fcvs
Project Source Code
References
Acknowledgement
A sincere thanks to Preetpal Kang for the knowledge he provided us throughout the semester to not only drive us, but to provide us with the knowledge to create something amazing and to Charles MacDonald, for all his help with answering questions and always challenging us with questions.