+ All Categories
Home > Documents > A-V LED Cube Final Report

A-V LED Cube Final Report

Date post: 03-Apr-2018
Category:
Upload: juan-pablo
View: 215 times
Download: 0 times
Share this document with a friend

of 42

Transcript
  • 7/28/2019 A-V LED Cube Final Report

    1/42

    Audio Visual LED Cube

    ECE 791/792 Final ReportTeam Members: Matthew Daigle, Robert Hunter, Kendra Kreider

    Advisor: Dr. Richard Messner

    Date: May 2011

  • 7/28/2019 A-V LED Cube Final Report

    2/42

    D a i g l e , H u n t e r , K r e i d e r | 2

    Acknowledgments

    This projects realization is due in part to the sponsorship granted from Raytheon as well as the

    funding provided by the University of New Hampshire. Special thanks go out to both of these

    organizations for providing us with the freedom to pursue our own project and their full support along

    the way. The A/V LED team would also like to acknowledge the support of Dr. Richard Messner, whos

    push for us to stay on track, as well as his intrigue and excitement for the project, really allowed the A/V

    LED cube to be the best possible project it could be.

    Project Team

    From left to right: Matthew Daigle, Robert Hunter, Kendra Kreider, Professor R. Messner

  • 7/28/2019 A-V LED Cube Final Report

    3/42

    D a i g l e , H u n t e r , K r e i d e r | 3

    Abstract

    The goal of this project was to create a three dimensional 5x5x5 array of RGB LEDs powered by

    the Arduino microcontroller. This array of LEDs creates a cube shape that, with simple C programming,

    can display full color visual images through the use of multiplexing and serial in, parallel out shift

    registers. The cube can also produce visual effects that correspond to an audio input in real time

    through the use of the MSGEQ7 integrated circuit, which is a seven-band graphic equalizer IC.

    The cube also has commercial potential due to its unique and interesting design, though not at

    its current cost of construction. All design goals were met for this project, and future improvement will

    most likely consist of interactivity between the cube and the user.

  • 7/28/2019 A-V LED Cube Final Report

    4/42

    D a i g l e , H u n t e r , K r e i d e r | 4

    Table of Contents

    INTRODUCTION ...................................................................................................................................................... 5

    REACHING FINAL DESIGN.................................................................................................................................... 6

    BUILD ......................................................................................................................................................................... 7

    LEDMATRIX ............................................................................................................................................................................ 7

    CASING....................................................................................................................................................................................... 8

    CIRCUIT DESIGN ..................................................................................................................................................... 9

    ARDUINO ................................................................................................................................................................................... 9

    MUSIC CHIP ............................................................................................................................................................................ 10

    SHIFT REGISTERS ..................................................................................................................................................................12

    GROUND TRANSISTORS ........................................................................................................................................................ 13

    TESTING .................................................................................................................................................................................. 14

    SOFTWARE ............................................................................................................................................................ 14

    DESIGN ISSUES ..................................................................................................................................................... 17

    FUTURE WORK .................................................................................................................................................... 18

    APPENDIX I: PROJECT PHOTOS...................................................................................................................... 21

    APPENDIX II: EXAMPLE LIGHTSHOW .......................................................................................................... 28

    APPENDIX III: EXAMPLE MUSIC SHOW ....................................................................................................... 36

  • 7/28/2019 A-V LED Cube Final Report

    5/42

    D a i g l e , H u n t e r , K r e i d e r | 5

    Introduction

    Light organs have been a popular Do-It-Yourself electrical engineering design ever since their

    implementation in the 1970s. In their most basic design, light organs consisted of three lights: one to

    show low frequencies, one to show midrange frequencies, and one to show high frequencies. As

    technologies have advanced, improvements in this basic design have been made such as displaying the

    frequencies over two-dimensional banners as well as being able to select a greater number of

    frequencies to display.

    This project takes the simple concepts of light organs and electronic banners and builds off of

    them to create an LED light organ in three dimensions. This audio-visual LED cube (3D LED light organ)

    consists of a 5x5x5 array of RGB LEDs that is able to display low-resolution images as well as interact

    with different frequencies of an audio input through the use of an audio-equalizer chip. The primary

    hardware design goal was to come up with a way to control all 125 LEDs (each with 4 leads that needed

    individual control) using the least amount of wires and components necessary but without sacrificing

    performance and controllability of the cube. The software design aspect of this project consisted of

    creating visually appealing light and music animations. Hypothetically, this project has no definitive

    endpoint. An endless number of animations can be created, and a cleaner user interface could also be

    continuously developed. The LED cube is a viable commercial product with limitless potential in design

    applications.

  • 7/28/2019 A-V LED Cube Final Report

    6/42

    D a i g l e , H u n t e r , K r e i d e r | 6

    Reaching Final Design

    The final project design was a 5x5x5 RGB LED cube. The size of this finished product was decided

    mostly due to cost of LEDs. To reach this final goal, incremental steps were first taken to gain familiarity

    with the design and coding. The first step of this project was to gain the basic tools and knowledge to

    build an RGB cube by first building a simpler size 3x3x3 single color LED cube. Although the 3x3x3 cube is

    more simplistic, there were many design similarities between it and larger cubes. Building this allowed

    us to foresee some problems with a larger-scale design and it also made coding simpler, which made the

    process of learning how to use the microcontroller easier and quicker. Figure 1 below shows the

    complete 3x3x3 single color cube connected to the microcontroller.

    Figure 1. Initial 3x3x3 Design

  • 7/28/2019 A-V LED Cube Final Report

    7/42

    D a i g l e , H u n t e r , K r e i d e r | 7

    Build

    Figure 2. Block Diagram of Project

    LED Matrix

    The LED matrix consists of 125-RGB LEDs, which are arranged in a 5x5x5 array. Each of the 5

    layers (or floors) is made from 25 LEDs. All of the LEDs in a layer share a common ground, which is

    connected using 1/16 copper rodding. The copper rods give the lattice its rigidity making the

    structure stronger and sturdier.

    A single vertical column of LEDs is connected with 3 sub-columns for the red, green, and blue

    anodes. The number of columns, therefore, totals to 75 (25 LED columns x 3 sub-columns = 75 total

    columns). The anodes for each respective color in a column of LEDs are connected using single strands

    of bare copper wire. You will also notice that 5 columns are connected using the 1/16 copper rods. This

    was done, again, to add strength to the lattice. A single LED is addressed by applying 5V to one of the 75

    columns and then grounding one of the 5 layers, which completes a circuit for only one LED so only one

    LED will be turned on (shown in Figure 3).

    At the bottom of the cube, you will see that magnet wire was used to connect the 75 columns to

    the circuitry inside of the wooden base. Magnet wire was chosen because it has a thin enamel coating

  • 7/28/2019 A-V LED Cube Final Report

    8/42

  • 7/28/2019 A-V LED Cube Final Report

    9/42

    D a i g l e , H u n t e r , K r e i d e r | 9

    On the back of the wooden base, there are 4 ports DC In, USB In, Audio In, and Audio Out. The

    audio input accepts audio from any device that uses a 3.5mm audio jack (i.e. computer, iPod, phone).

    The audio output also uses a 3.5mm audio jack, but should only be connected to speakers that have an

    independent power supply. Connecting headphones or speakers that are without an independent power

    supply will load down the audio circuit. This, in turn, affects the audio-visualization lightshow

    performance. The DC input supply powers the Arduino microcontroller. The Arduino itselfpowers the

    LEDs in the cube. A 2.1mm, center-positive, 12 V, 1A rated AC adapter is the minimum current rating

    that should be used due to the current necessary to drive the electronics. The USB input can also be

    used to power the microcontroller when an AC adapter is not available. Although the USB can be used

    to power the microcontroller the USB port is normally used just to upload the lightshow sketches to the

    microcontroller from a computer using the Arduino application.

    In order to protect the cube a plexiglass case was constructed to cover the lattice. This was done

    purely for the protection of the fragile cube of LEDs andother cases could also be made from different

    types of glass or plexiglass that might give off different lighting effects from the light emanating from

    the cube.

    All pictures relating to the build process as well as how the cube was tested are provided in

    Appendix 1.

    Circuit DesignArduino

    The Arduino UNO is the microcontroller board that is used to control the input of information to

    the shift registers, music chip, and ground transistor array. In total, 11 of the digital input/output pins

    are used as well as 1 of the 6 analog input pins. Along with these pins the Arduino UNO has a 16MHz

  • 7/28/2019 A-V LED Cube Final Report

    10/42

    D a i g l e , H u n t e r , K r e i d e r | 10

    crystal oscillator, USB jack, power jack, ICSP header, and a reset button. The USB jack is used to upload

    programs written on a computer to the Arduino and will also provide power to the board. If the user

    plans on using just one sketch, that sketch can be uploaded to the board and only the power jack is then

    necessary to power the LED cube.

    For this project the Arduino UNO is the heart of the LED Cube. Light shows are programmed

    using C coding and uploaded to the board to be sent out serially to the shift registers. The Arduino can

    also read in the analog data processed from the MSGEQ7 chip, which can then be manipulated in a

    lightshow sketch. This process is used to create the real-time audio-visual lightshows.

    The final circuit design for the LED cube can be split in to three significant portions (shown in

    Figure 4): the music chip to allow for audio analysis (1), the serial-in, parallel-out shift registers to

    control each column of LEDs (2), and the transistor circuit used to ground each individual layer (3).

    Music Chip

    The MSGEQ7 is a seven-band graphic equalizer integrated circuit that divides an audio signal

    into frequency bands. These seven bands are split over the range of audible frequencies and are located

    at 63Hz, 160Hz, 400Hz, 1kHz, 2.5kHz, 6.25kHz, and 16kHz. Since one face of the cube has a 5x5

    2

    3

    1

    Figure 4. Three Major Circuit Elements in Cube

  • 7/28/2019 A-V LED Cube Final Report

    11/42

    D a i g l e , H u n t e r , K r e i d e r | 11

    resolution, five of the seven frequencies were used, excluding the 1kHz and 16kHz frequency bands, for

    most of the audio-visual programming. These two frequencies were omitted since they tended not to be

    very predominant in most of the songs that were chosen. The MSGEQ7 serially samples one frequency

    at a time, and returns the amplitude of the sampled frequency to the Arduino. An amplitude range of 0

    to 400 was consistently returned to the Arduino, which was then scaled down by 80 to result in values

    between 0 and 5, as the bar-height at each frequency would only range from 0 to 5 LEDs. The frequency

    bands were displayed on the front face of the cube where a vertical column of LEDs represented one of

    the five frequencies, and the height of the column represented the amplitude of a frequency. The pin

    diagram of the MSGEQ7 setup is shown below in Figure 5.

    Figure 5. Pin Diagram for MSGEQ7

  • 7/28/2019 A-V LED Cube Final Report

    12/42

    D a i g l e , H u n t e r , K r e i d e r | 12

    Shift Registers

    The 74HC595 8-bit serial-in, parallel-out shift registers were ultimately used as the way to

    address the LED matrix from the Arduino microcontroller. The setup for these shift registers is based on

    the 75 columns discussed earlier. Each of the 75 columns is connected to the output pin of a shift

    register, and each shift register has 8 output pins, therefore 10 shift registers are needed in total

    (leaving 5 pins disconnected). All bits are sent from the Arduino to the shift registers using a sendOut()

    command which serially sends out 8 bits at a time; repeating this action 9 more times will result in the

    shift registers being completely filled with the necessary information for a single layer of an image (an

    image being comprised of the 5 layers of the cube). The registers latch pins are then turned on, which

    sends out the information in the shift registers in parallel to each column and turns on the

    corresponding LEDs.

    The shift registers are organized in sections of 25 columns: first the necessary blue LED bits are

    sent in, then the 25 green LED bits are sent, and finally the 25 red LED bits are sent before the latch pins

    are triggered. This design minimizes the number of output pins needed by the microcontroller, as all of

    the information sent to the LED matrix is output through just one pin on the Arduino. If this design was

    utilized there would not have been enough pins on the Arduino to control all 75 columns of the LED

    matrix. The functional diagram for the 74HC595 is shown below in Figure 6.

    Q0 Q7 are the parallel outputs that are connected to the LED matrix, Q7 is the serial output to

    allow for multiple shift registers to be cascaded together (which is how all ten shift registers are written

    using only one output pin on the Arduino), DS is the serial data input read from the Arduino, SHCP is the

    shift register clock input (serial input shift clock), STCP is the storage register clock input (parallel output

    latch) which controls when the bits are sent out, MR (master reset) clears the shift registers, and OE

    (output enable) is always set to on as an active LOW.

  • 7/28/2019 A-V LED Cube Final Report

    13/42

    D a i g l e , H u n t e r , K r e i d e r | 13

    Figure 6. Functional Diagram for 74HC595

    Ground Transistors

    The third and final aspect of the circuit board is the most basic, and consists of five transistors

    acting as switches to allow each layer to be individually connected to ground. For the transistors the

    LM3046 Transistor Array IC was used as it consists of five matched transistors in one IC, which keeps the

    current consistent for all layers (maintaining even luminosity for each layer). Five output pins from the

    Arduino are used to turn on the individual transistors. Providing a 5V signal to the base of one of the five

    transistors turns on the switch which connects the respective layer to ground (shown in Figure 7). The

    five layers are shifted through one at a time to allow for multiplexing on the cube as the shift registers

    can only hold the information for one layer at a time.

  • 7/28/2019 A-V LED Cube Final Report

    14/42

  • 7/28/2019 A-V LED Cube Final Report

    15/42

    D a i g l e , H u n t e r , K r e i d e r | 15

    each layer has a common ground, LEDs in two different columns and two different layers cannot be lit

    up without additional, unwanted LEDs also lighting. Figure 8 displays the ideal case versus what happens

    in reality when two columns and two layers are turned on at the same time. To avoid this issue, all layers

    need to be multiplexed through at a frequency greater than or equal to 60Hz. Therefore, each ground

    layer can be lit for up to of 3.33 milliseconds before the next layer must turn on. At this rate, persistence

    of vision keeps the human eye from noticing any flicker that occurs from the layers turning on and off.

    Figure 8. Ideal vs. Real interpretation of Cube Without Multiplexing

    Multiplexing is also necessary to display colors other than red, green, or blue. For example,

    switching between red and blue will display purple from the LED. Different shades of purple can also be

    made depending on the ratio of how long one color is on relative to the other. Any combination of the

    three basic colors, red, green, and blue, can be used to create another color. As mentioned before, the

  • 7/28/2019 A-V LED Cube Final Report

    16/42

    D a i g l e , H u n t e r , K r e i d e r | 16

    switching between the two or three basic colors must be at a rate faster than the 60Hz so that flickering

    is not noticeable.

    This concept of creating color with multiplexing is combined with the concept of multiplexing

    ground layers to create an image. Each color has to be split into a total interval of less than 3.33

    milliseconds. To make the color more cohesive, the two separate colors should be flashed twice within

    this time. So to create purple, the red should be turned on for 750 microseconds, then blue for 750

    microseconds, and then repeat that process one more time. The registers and other components also

    have delays of their own, so the actual time each color can be turned on for is further reduced. Since the

    colors are being multiplexed so quickly, the brightness of the LED is dependent on how long a color stays

    on before being turned off. Although multiplexing faster disperses the colors more evenly within the

    LED, it also reduces how bright the mixed color is, which is not ideal.

    When creating a lightshow, a certain amount of artistic creativity is necessary, and you must

    also be able to apply the concepts of multiplexing the layers and multiplexing the colors to realize the

    image accurately and efficiently. Combing the two is not without its difficulties. To simplify the process,

    it is better to program the basic animation in a single color first, and then add color to the design once

    the animation is in working order.

    Audio-visualization lightshows were programmed in the same manner that a regular animation

    was programmed along with the use of the MSGEQ7 seven-band graphic equalizer chip. The amplitudes

    of the frequency bands of an audio input are sent to the Arduino microcontroller, which were then

    manipulated within the lightshow program. Audio-visualization lightshows are, therefore, frequency and

    amplitude dependent.

  • 7/28/2019 A-V LED Cube Final Report

    17/42

    D a i g l e , H u n t e r , K r e i d e r | 17

    Design Issues

    Difficulty, time, budget, and experience were all contributing factors to the design issues.

    Throughout the course of the project there were some aspects of design that did not end up working

    out as effectively or as efficiently as our initial design had intended, but more efficient ways of building

    and programming were discovered as more knowledge of the cube was gained.

    Even though there were many minor changes implemented over the course of the project, there

    were really only three significant design issues that arose. The first issue was a matter of design

    simplification. The initial design for the A/V LED cube involved the Arduino using 2-to-4 decoders in

    order to communicate with the LED matrix. Initially, the largest Arduino (Mega 2560) had enough output

    pins to run the cube using 2-to-4 decoders, but with the implementation of the music functionality this

    ended up no longer being the case. This issue was resolved by using 8-bit SIPO shift registers (10 of

    them) that could read in data from serially through one output pin on the Arduino. The final design

    ended up using a total of 12 output pins on the Arduino, which allowed the cube to be built with a

    smaller and less expensive microcontroller the Arduino Uno.

    The second design issue occurred when the audio visualization was first tested on the final cube.

    When speakers or headphones were plugged into the circuit for audio output, it ended up loading down

    the audio circuit so that the amplitudes of the frequencies being sampled were read as being half of

    what they actually were. This was due to the fact that the speakers acted as a voltage divider and

    reduced the voltage of the audio signal that was being fed into the MSGEQ7s input pin. Initially, buffer

    circuits and simple audio amplifiers were created to try to fix the problem, however the quality of the

    audio being output through the speakers was significantly deteriorated. Eventually the cube was tested

    using speakers that were powered with an independent power supply. This kept the speakers from

    drawing any power from the cubes audio circuit and completely solved the issue of the speakers

  • 7/28/2019 A-V LED Cube Final Report

    18/42

    D a i g l e , H u n t e r , K r e i d e r | 18

    loading down the visual effects on the cube. It also helped to simplify the final circuit design as no

    amplifiers or buffers were needed.

    The last major change in the final design was implemented mostly to save time and to simplify

    the wiring and soldering of the final circuit. Initially, the thin copper wires connecting the columns were

    to be fed through the top of the wooden box, soldered to 22 AWG insulated wire, and then cut to length

    and soldered to the perforated board. This would have been a very time consuming and tedious process.

    And not only that, but the joints between the copper wire and the insulated wire would have been very

    weak and frail. Through some research, magnet wire was decided to be the best viable option. Magnet

    wire is a thin wire (28 AWG was used in the project) with a very thin enamel coating that burns off when

    soldered. Using such thin wire also reduced the amount of space needed inside the box to hold all of the

    wire. 22 AWG wire along with its plastic insulation is considerably thicker than 28 AWG wire, and took

    up most of the available space inside the wooden box. The enameled wire was soldered directly to the

    bottom layer of the cube, fed through the box, and then fed through the perforated board. Once all of

    the wires were through the circuit board, they could then be pulled tight, soldered to the board, and

    finally trimmed.

    Future Work

    This project focused primarily on the most efficient way to build an LED cube and to also

    interface music with the cube. The cube was designed with simplicity in mind, so there is a lot room for

    development of both the hardware and the software. This section outlines a few of the possibilities for

    work on this as well as future LED cube projects.

    In terms of hardware, this cube was built to simply function as a 5x5x5 matrix of LEDs. While this

    build was stationary, rotational effects could be implemented using motors and more loose fitted LEDs

  • 7/28/2019 A-V LED Cube Final Report

    19/42

    D a i g l e , H u n t e r , K r e i d e r | 19

    (in terms of wiring). Accelerometers could also be utilized in such applications. Also, the only visual

    effects being generated by this LED cube are from the LEDs themselves. Things such as one-way mirrors,

    lasers, light bulbs, smoke machines, and even dry ice have all been suggested over the course of this

    year. With most of the budgeted time going into research, most of these ideas could not be realized in

    this project, however a future project that already has the design specifications implemented in this

    build could develop this project even further.

    Improvement in software design is really where a lot of future work could be spent. While this

    team focused purely on creating light shows for display and the ability to detect and play an audio signal

    in real time, these are not the only possible ways in which to use the LED cube. One aspect the team

    started to touch on near the end of the project was user interactivity. Through the use of a serial

    monitor built in to the Arduino software, the microcontroller can serially read in inputs from the

    keyboard and use these inputs to execute specific code already uploaded to the Arduino. This was used

    to switch between the animations and audio-visualization shows during the URC presentation, but the

    idea can be expanded in other ways.

    One application that the group started to explore was programming user-interactive games. The

    low resolution of the cube has its limitations, but games such as 3D Snake or 3D Pong would greatly

    expand the current functionality of the LED cube into something more than just a light organ.

    The cube could also be used to simulate 3D models such as earthquakes, fluids, or cellular

    automation. Again, however, the low resolution of the cube would not allow for models that are

    extremely detailed and complex, so a larger single colored cube would most likely be a better build if

    such applications were to be implemented.

    Improvements could also be made on how the animations are coded and that also expand on

    the idea of user interactivity. Simply put, this teams method for coding the cube may not have been the

  • 7/28/2019 A-V LED Cube Final Report

    20/42

    D a i g l e , H u n t e r , K r e i d e r | 20

    most efficient or easiest way to achieve the light and music shows. While explicitly writing the binary

    values into an array for each color was very intuitive and straightforward, it required a lot of abstract

    thinking to properly turn on and off each LED for each desired image.

    The most interesting solution to this problem, and a solution that opens up coding the cube to

    everyone and not just programmers, is to create a graphic user interface, or GUI, to visually program the

    cube. By having a model of the cube on a computer, the user would be able to choose a color and then

    click the LEDs that they wanted to turn on with that color and then save the image for use in the actual

    visual display. The user would then move on to programming the next image until eventually they have

    a complete light show finished in a fraction of the time it would take to program it individually. While it

    would take a very long time to actually program the GUI to be streamlined and bug free, it would save a

    lot of time in the long run. This type of interface would also eliminate the need for the common user to

    have a substantial knowledge of programming. The GUI would reduce programming the cube down to

    simply creating an animation visually, which would again add to the cubes commercial viability.

  • 7/28/2019 A-V LED Cube Final Report

    21/42

    D a i g l e , H u n t e r , K r e i d e r | 21

    Appendix I: Project Photos

  • 7/28/2019 A-V LED Cube Final Report

    22/42

    D a i g l e , H u n t e r , K r e i d e r | 22

  • 7/28/2019 A-V LED Cube Final Report

    23/42

    D a i g l e , H u n t e r , K r e i d e r | 23

  • 7/28/2019 A-V LED Cube Final Report

    24/42

    D a i g l e , H u n t e r , K r e i d e r | 24

  • 7/28/2019 A-V LED Cube Final Report

    25/42

    D a i g l e , H u n t e r , K r e i d e r | 25

  • 7/28/2019 A-V LED Cube Final Report

    26/42

    D a i g l e , H u n t e r , K r e i d e r | 26

  • 7/28/2019 A-V LED Cube Final Report

    27/42

    D a i g l e , H u n t e r , K r e i d e r | 27

  • 7/28/2019 A-V LED Cube Final Report

    28/42

    D a i g l e , H u n t e r , K r e i d e r | 28

    Appendix II: Example Lightshow//Diagonals

    //pattern starts at lower corner

    //and travels up to opposite diagonal corner

    //pattern fades from blue on bottom layer to pink on top layer

    //code was edited to randomly select the starting corner

    //code was edited to randomly select whether pattern travels up or down

    //initializing variables for ground & register connects to arduino

    int dataPin = 13; //Serial Data Input

    int latchPin = 12; //Parallel Output Clock

    int clockPin = 11; //Shifting Clock

    int regResetPin = 10; //Shift Register Clear

    int ground[] = {

    9, 8, 7, 6, 5}; //5 Ground Layers

    //variables used to implement design

    int count=0;

    int totalDelay=0;

    int delayT=300; //delay

    int corner=1; //random variable that picks corner

    int upDown=1; //variable determines if design is traveling up or downint numLED=1; //number of LEDs in diagonal

    int incLED=1; //variable that determines if diagonal size is increasing or decreasing

    int colorNum=1;

    byte data;

    byte dataArray[10];

    int zeros[25] = {

    0,0,0,0,0,

    0,0,0,0,0,

    0,0,0,0,0,

    0,0,0,0,0,

    0,0,0,0,0

    };

    int ones[25] = {

    1,1,1,1,1,1,1,1,1,1,

    1,1,1,1,1,

    1,1,1,1,1,

    1,1,1,1,1

    };

    int layer0[25] = {

    0,0,0,0,0,

    0,0,0,0,0,

    0,0,0,0,0,

    0,0,0,0,0,

    0,0,0,0,0

    };

    int layer1[25] = {0,0,0,0,0,

    0,0,0,0,0,

    0,0,0,0,0,

    0,0,0,0,0,

    0,0,0,0,0

    };

    int layer2[25] = {

    0,0,0,0,0,

    0,0,0,0,0,

  • 7/28/2019 A-V LED Cube Final Report

    29/42

    D a i g l e , H u n t e r , K r e i d e r | 29

    0,0,0,0,0,

    0,0,0,0,0,

    0,0,0,0,0

    };

    int layer3[25] = {

    0,0,0,0,0,

    0,0,0,0,0,

    0,0,0,0,0,

    0,0,0,0,0,

    0,0,0,0,0

    };

    int layer4[25] = {

    0,0,0,0,0,

    0,0,0,0,0,

    0,0,0,0,0,

    0,0,0,0,0,

    0,0,0,0,0

    };

    //setup- tells Arduino which pins are outputs, etc

    void setup() {

    pinMode(latchPin, OUTPUT);

    pinMode(clockPin, OUTPUT);

    pinMode(dataPin, OUTPUT);

    pinMode(regResetPin, OUTPUT);

    pinMode(ground[0], OUTPUT);

    pinMode(ground[1], OUTPUT);

    pinMode(ground[2], OUTPUT);

    pinMode(ground[3], OUTPUT);

    pinMode(ground[4], OUTPUT);

    analogReference(DEFAULT);

    digitalWrite(regResetPin, 0); //Clear the shift registers

    digitalWrite(regResetPin, 1);

    Serial.begin(1500000);

    turnOffLEDs(5);

    }//End setup

    void loop() {

    corner=random(1,5); //choose random corner from 1-4

    upDown=random(2); //choose if design travels up or down, 0 or 1

    while(count

  • 7/28/2019 A-V LED Cube Final Report

    30/42

    D a i g l e , H u n t e r , K r e i d e r | 30

    else if (i==3){

    colorIt(layer3,colorNum+3,delayT,i);

    }

    else if (i==4){

    colorIt(layer4,colorNum+4,delayT,i);

    }

    totalDelay=totalDelay+1;

    }

    }

    count++; //count pattern increment

    if(numLED==5){

    incLED=0;

    }

    if (incLED){

    numLED++;

    }

    else {

    numLED--;

    }

    totalDelay=0;

    }

    count=0;

    incLED=1;

    numLED=1;

    }//End loop

    //////////////////////////////// FUNCTIONS //////////////////////////////////

    /* This function places the 1x25 binary array into a 1x80

    (10 registers x 8 pins = 80 bits) binary array. These 80 binary values

    are then converted into a 1x10 byte array of HEX values */

    void convert(int tempArray[25], char color, byte byteArray[10]) {

    int eightyArray[80];

    /* Place the 1x25 binary array into the 1x80 binary array. The location of

    the 25 values in the 1x80 array is determined by what color the arrayis. First 25 values are reserved for blue, second 25 for green, third

    25 for red, and the last 5 values are don't cares. Only one color will

    be on at a time. */

    //Blue

    if(color == 'b') {

    for(int i = 0; i < 25; i++) {

    eightyArray[i] = tempArray[i];

    }

    for(int j = 25; j < 80; j++) {

    eightyArray[j] = 0;

    }

    }

    //Green

    else if(color == 'g') {

    for(int i = 0; i < 25; i++) {eightyArray[i] = 0;

    }

    for(int j = 25; j < 50; j++) {

    eightyArray[j] = tempArray[j - 25];

    }

    for(int k = 50; k < 80; k++) {

    eightyArray[k] = 0;

    }

    }

    //Red

  • 7/28/2019 A-V LED Cube Final Report

    31/42

    D a i g l e , H u n t e r , K r e i d e r | 31

    else if(color == 'r') {

    for(int i = 0; i < 50; i++) {

    eightyArray[i] = 0;

    }

    for(int j = 50; j < 75; j++) {

    eightyArray[j] = tempArray[j - 50];

    }

    for(int k = 75; k < 80; k++) {

    eightyArray[k] = 0;

    }

    } //Red

    /* Now convert the 80 bits into 10 bytes and store them in byteArray,

    which points to dataArray */

    int LSB = 0; //Represents least significant bit of the 8 bits being converted

    int MSB = 7; //Represents most significant bit of the 8 bits being converted

    int conversionArray[8]; //Array used to store the 8 bits being converted

    int byteIndex = 0; //Used to index the byteArray

    int indexA = 0;

    while(MSB < 80) {

    indexA = 0;

    for(int i = LSB; i

  • 7/28/2019 A-V LED Cube Final Report

    32/42

    D a i g l e , H u n t e r , K r e i d e r | 32

    if(binary[7] == 1) {

    sum = sum + 0x01;

    }

    return sum;

    }//End binaryToByte

    ///////////////////////////////////////////////////////////////////////////////////

    //This function writes the array values to the registers and sends them to the cube

    void sendOut() {

    digitalWrite(latchPin, 0); //Ground latch pin until done shifting in all data

    for(int i = 0; i < 10; i++) {

    data = dataArray[i];

    shiftOut(dataPin, clockPin, MSBFIRST, data); //Shift in the data one byte at a

    time

    }

    digitalWrite(latchPin, 1); //Send out the data from the registers

    }//End sendOut

    ///////////////////////////////////////////////////////////////////////////////////

    void turnOffLEDs(int reset) {

    if (reset==5){ //turn all five grounds off

    for(int k = 0; k < 5; k++) {

    digitalWrite(ground[k], 0);

    }

    }

    else if (reset>=0 && reset

  • 7/28/2019 A-V LED Cube Final Report

    33/42

    D a i g l e , H u n t e r , K r e i d e r | 33

    int adrs=0;

    if(crner==1){

    adrs=a1[cnt];

    for(int j=0;j

  • 7/28/2019 A-V LED Cube Final Report

    34/42

    D a i g l e , H u n t e r , K r e i d e r | 34

    adrs=adrs+6;

    }

    }

    else if(crner==4){

    adrs=a4[cnt];

    for(int j=0;j

  • 7/28/2019 A-V LED Cube Final Report

    35/42

    D a i g l e , H u n t e r , K r e i d e r | 35

    dRed=delayTime*50/100;

    dGreen=delayTime*50/100;

    dBlue=0;

    }

    else if(colorNum==10){//30red-70green

    dRed=delayTime*30/100;

    dGreen=delayTime*70/100;

    dBlue=0;

    }

    else if(colorNum==11){//green

    dGreen=delayTime;

    dBlue=0;

    dRed=0;

    }

    else if(colorNum==12){//80green-20blue

    dGreen=delayTime*80/100;

    dBlue=delayTime*20/100;

    dRed=0;

    }

    else if(colorNum==13){//50green-50blue (cyan)

    dGreen=delayTime*50/100;

    dBlue=delayTime*50/100;

    dRed=0;

    }

    else if(colorNum==14){//20green-80blue

    dGreen=delayTime*20/100;

    dBlue=delayTime*80/100;

    dRed=0;

    }

    else{

    dBlue=delayTime;

    dRed=0;

    dGreen=0;

    }

    if(dBlue!=0){

    convert(pattern, 'b', dataArray); //Convert the binary array into bytes

    sendOut(); //Send the frame to the cube (5 frames makes one image)digitalWrite(ground[gg], 1);

    delayMicroseconds(dBlue); //time blue is on

    turnOffLEDs(gg);

    }

    if(dRed!=0){

    convert(pattern, 'r', dataArray); //Convert the binary array into bytes

    sendOut(); //Send the frame to the cube (5 frames makes one image)

    digitalWrite(ground[gg], 1);

    delayMicroseconds(dRed); //time red is on

    turnOffLEDs(gg);

    }

    if(dGreen!=0){

    convert(pattern, 'g', dataArray); //Convert the binary array into bytes

    sendOut(); //Send the frame to the cube (5 frames makes one image)

    digitalWrite(ground[gg], 1);delayMicroseconds(dGreen); //time green is on

    turnOffLEDs(gg);

    }

    }//End colorIt

  • 7/28/2019 A-V LED Cube Final Report

    36/42

    D a i g l e , H u n t e r , K r e i d e r | 36

    Appendix III: Example Music Show//Front Face Audio

    //Basic music program lights only the front face

    //Each of the five columns is a different frequency

    //the leftmost column displays bass and freqeuncy gets higher traveling right

    //the audio signal is sampled and filtered into frequency ranges//the corresponding freqeuncy column lights up with an amplitude of 0-5 LEDs

    //depending on audio sample

    //program sets base for other music programs

    int dataPin = 13; //Serial Data Input

    int latchPin = 12; //Parallel Output Clock

    int clockPin = 11; //Shifting Clock

    int regResetPin = 10; //Shift Register Clear

    int ground[] = {

    9, 8, 7, 6, 5}; //5 Ground Layers

    int analogPin = A0; //Specrtum Analyzer Analog Output (frequency's amplitude)

    int strobePin = 4; //Specrtum Analyzer Strobe (read next frequency value)

    int msgResetPin = 3; //Specrtum Analyzer Clear

    int spectrum[7]; // Spectrum analyzer read values will be kept here

    //intialize variables

    int blue[25];

    int green[25];

    int red[25];

    byte data; //Holds one byte at a time for writing to the dataArray

    byte dataArray[10]; //Holds the 10 bytes to write to the registers

    int t = 250; //Delay time constant (in microseconds)

    int i;

    int eightyArray[80];

    void setup() {

    pinMode(latchPin, OUTPUT);

    pinMode(clockPin, OUTPUT);

    pinMode(dataPin, OUTPUT);

    pinMode(regResetPin, OUTPUT);pinMode(ground[0], OUTPUT);

    pinMode(ground[1], OUTPUT);

    pinMode(ground[2], OUTPUT);

    pinMode(ground[3], OUTPUT);

    pinMode(ground[4], OUTPUT);

    pinMode(analogPin, INPUT);

    pinMode(strobePin, OUTPUT);

    pinMode(msgResetPin, OUTPUT);

    analogReference(DEFAULT);

    Serial.begin(115200);

    digitalWrite(msgResetPin, 0); //Initialize the spectrum analyzer

    delay(1);

    digitalWrite(strobePin, 1);

    delay(1);

    turnOffLEDs();

    }//End setup

    void loop() {

    displaySpectrum(); //Display the spectrum

    }//End loop

    //////////////////////////////// FUNCTIONS //////////////////////////////////

  • 7/28/2019 A-V LED Cube Final Report

    37/42

    D a i g l e , H u n t e r , K r e i d e r | 37

    //Read the 7-band equalizer

    void readSpectrumValues() {

    digitalWrite(msgResetPin, 1);

    digitalWrite(msgResetPin, 0);

    //Band 0 = 63Hz

    //Band 1 = 160Hz

    //Band 2 = 400Hz

    //Band 3 = 1kHz

    //Band 4 = 2.5kHz

    //Band 5 = 6.25kHz

    //Band 6 = 16kHz

    for (int band = 0; band < 7; band++) {

    digitalWrite(strobePin, 0);

    //Read twice, take the average

    spectrum[band] = (analogRead(analogPin) + analogRead(analogPin)) / 2;

    digitalWrite(strobePin, 1);

    }

    }//End redSpectrumValues

    /////////////////////////////////////////////////////////////////////////////

    void displaySpectrum()

    {

    readSpectrumValues(); //Read in the spectrum values

    int scalar = 80;

    int adjustmentTimer = 0;

    int barHeightA;

    int barHeightB;

    int barHeightC;

    int barHeightD;

    int barHeightE;

    int maxHeight = 0;

    for(int band = 0; band < 7; band++) {

    //Will only be using 5 bands//Bands are read in as values from 0 - 1023, scale them down to be 0 - 5

    barHeightA = spectrum[0] / scalar;

    barHeightB = spectrum[1] / scalar;

    barHeightC = spectrum[2] / scalar;

    barHeightD = spectrum[4] / scalar;

    barHeightE = spectrum[5] / scalar;

    if(barHeightA > maxHeight) //Check if this value is the largest so far

    maxHeight = barHeightA;

    if(barHeightB > maxHeight)

    maxHeight = barHeightB;

    if(barHeightC > maxHeight)

    maxHeight = barHeightC;

    if(barHeightD > maxHeight)

    maxHeight = barHeightD;if(barHeightE > maxHeight)

    maxHeight = barHeightE;

    ///////////////// FIRST LAYER //////////////////

    turnOffLEDs();

    if(barHeightA >= 1){

    green[20] = 1;

    }

  • 7/28/2019 A-V LED Cube Final Report

    38/42

    D a i g l e , H u n t e r , K r e i d e r | 38

    if(barHeightB >= 1){

    green[21] = 1;

    }

    if(barHeightC >= 1){

    green[22] = 1;

    }

    if(barHeightD >= 1){

    green[23] = 1;

    }

    if(barHeightE >= 1){

    green[24] = 1;

    }

    convert(green, 'g', dataArray); //Convert the binary array into bytes

    sendOut(); //Send the frame to the cube

    digitalWrite(ground[0], 1);

    delayMicroseconds(t);

    ///////////////// SECOND LAYER //////////////////

    turnOffLEDs();

    if(barHeightA >= 2){

    green[20] = 1;

    }

    if(barHeightB >= 2){

    green[21] = 1;

    }

    if(barHeightC >= 2){

    green[22] = 1;

    }

    if(barHeightD >= 2){

    green[23] = 1;

    }

    if(barHeightE >= 2){

    green[24] = 1;

    }

    convert(green, 'g', dataArray); //Convert the binary array into bytes

    sendOut(); //Send the frame to the cube

    digitalWrite(ground[1], 1);

    delayMicroseconds(t);

    ///////////////// THIRD LAYER //////////////////

    turnOffLEDs();

    if(barHeightA >= 3){

    green[20] = 1;

    }

    if(barHeightB >= 3){

    green[21] = 1;

    }

    if(barHeightC >= 3){green[22] = 1;

    }

    if(barHeightD >= 3){

    green[23] = 1;

    }

    if(barHeightE >= 3){

    green[24] = 1;

    }

    convert(green, 'g', dataArray); //Convert the binary array into bytes

  • 7/28/2019 A-V LED Cube Final Report

    39/42

    D a i g l e , H u n t e r , K r e i d e r | 39

    sendOut(); //Send the frame to the cube

    digitalWrite(ground[2], 1);

    delayMicroseconds(t);

    ///////////////// FOURTH LAYER //////////////////

    turnOffLEDs();

    if(barHeightA >= 4){

    green[20] = 1;

    }

    if(barHeightB >= 4){

    green[21] = 1;

    }

    if(barHeightC >= 4){

    green[22] = 1;

    }

    if(barHeightD >= 4){

    green[23] = 1;

    }

    if(barHeightE >= 4){

    green[24] = 1;

    }

    convert(green, 'g', dataArray); //Convert the binary array into bytes

    sendOut(); //Send the frame to the cube

    digitalWrite(ground[3], 1);

    delayMicroseconds(t);

    ///////////////// FIFTH LAYER //////////////////

    turnOffLEDs();

    if(barHeightA >= 5){

    green[20] = 1;

    }

    if(barHeightB >= 5){

    green[21] = 1;

    }if(barHeightC >= 5){

    green[22] = 1;

    }

    if(barHeightD >= 5){

    green[23] = 1;

    }

    if(barHeightE >= 5){

    green[24] = 1;

    }

    convert(green, 'g', dataArray); //Convert the binary array into bytes

    sendOut(); //Send the frame to the cube

    digitalWrite(ground[4], 1);

    delayMicroseconds(t);

    }

    //Stabilization section

    //Adjust the scalar if levels are too high/low

    //If below 4 happens 20 times, then decrease the divisor

    if (maxHeight >= 5) {

    scalar++;

    adjustmentTimer = 0;

    }

    else if(maxHeight < 5) {

  • 7/28/2019 A-V LED Cube Final Report

    40/42

    D a i g l e , H u n t e r , K r e i d e r | 40

    if(scalar > 65)

    if(adjustmentTimer++ > 20) {

    scalar--;

    adjustmentTimer = 0;

    }

    }

    else {

    adjustmentTimer = 0;

    }

    }//End displaySpectrum

    /////////////////////////////////////////////////////////////////////////////

    /* This function places the 1x25 binary array into a 1x80

    (10 registers x 8 pins = 80 bits) binary array. These 80 binary values

    are then converted into a 1x10 byte array of HEX values */

    void convert(int tempArray[25], char color, byte byteArray[10]) {

    int LSB = 0; //Represents least significant bit of the 8 bits being converted

    int MSB = 7; //Represents most significant bit of the 8 bits being converted

    int conversionArray[8]; //Array used to store the 8 bits being converted

    int byteIndex = 0; //Used to index the byteArray

    int indexA = 0;

    /* Place the 1x25 binary array into the 1x80 binary array. The location of

    the 25 values in the 1x80 array is determined by what color the array

    is. First 25 values are reserved for blue, second 25 for green, third

    25 for red, and the last 5 values are don't cares. Only one color will

    be on at a time. */

    //Blue

    if(color == 'b') {

    for(int i = 0; i < 25; i++) {

    eightyArray[i] = tempArray[i];

    }

    }

    //Green

    else if(color == 'g') {for(int j = 25; j < 50; j++) {

    eightyArray[j] = tempArray[j - 25];

    }

    }

    //Red

    else if(color == 'r') {

    for(int j = 50; j < 75; j++) {

    eightyArray[j] = tempArray[j - 50];

    }

    } //Red

    /* Now convert the 80 bits into 10 bytes and store them in byteArray,

    which points to dataArray */

    while(MSB < 80) {

    indexA = 0;for(int i = LSB; i

  • 7/28/2019 A-V LED Cube Final Report

    41/42

    D a i g l e , H u n t e r , K r e i d e r | 41

    }

    }//End convert

    /////////////////////////////////////////////////////////////////////////////

    //This function converts the string of 80 binary values into 10 bytes in HEX

    byte binaryToByte(int binary[8]) {

    byte sum = 0x00;

    //Converts the 8-bit binary number into a HEX byte, which is held by sum

    if(binary[0] == 1) {

    sum = sum + 0x80;

    }

    if(binary[1] == 1) {

    sum = sum + 0x40;

    }

    if(binary[2] == 1) {

    sum = sum + 0x20;

    }

    if(binary[3] == 1) {

    sum = sum + 0x10;

    }

    if(binary[4] == 1) {

    sum = sum + 0x08;

    }

    if(binary[5] == 1) {

    sum = sum + 0x04;

    }

    if(binary[6] == 1) {

    sum = sum + 0x02;

    }

    if(binary[7] == 1) {

    sum = sum + 0x01;

    }

    return sum;

    }//End binaryToByte

    /////////////////////////////////////////////////////////////////////////////

    //This function writes the array values to the registers and sends them to the cube

    void sendOut() {

    digitalWrite(latchPin, 0); //Ground latch pin until done shifting in all data

    for(int i = 0; i < 10; i++) {

    data = dataArray[i];

    shiftOut(dataPin, clockPin, MSBFIRST, data); //Shift in the data one byte at a

    time

    }

    digitalWrite(latchPin, 1); //Send out the data from the registers

    }//End sendOut

    /////////////////////////////////////////////////////////////////////////////

    void turnOffLEDs() {

    for(int i = 0; i < 25; i++) {

    green[i] = 0;

    red[i] = 0;

    blue[i] = 0;

    }

    for(int i = 0; i < 5; i++) {

    digitalWrite(ground[i], 0);

  • 7/28/2019 A-V LED Cube Final Report

    42/42

    D a i g l e , H u n t e r , K r e i d e r | 42

    }

    for(int i = 0; i < 80; i++) {

    eightyArray[i] = 0; //Initializes the eightyArray

    }

    digitalWrite(regResetPin, 0);

    digitalWrite(regResetPin, 1);

    }//End turnOffLEDs


Recommended