Difference between revisions of "PartyBox"
Lydia.reader (talk | contribs) |
Lydia.reader (talk | contribs) |
||
Line 156: | Line 156: | ||
==Results== | ==Results== | ||
===Final Product=== | ===Final Product=== | ||
+ | [[File:PartyBox_Final_Design.JPG|The front face of the final PartyBox design|400px|center]] | ||
+ | <center> | ||
+ | <gallery> | ||
+ | File:Microphone_hole.JPG|A small hole on the top of PartyBox for the microphone | ||
+ | File:LED_hole.JPG|A hole on the top of PartyBox for the LED wires to feed through to connect to the Arduino | ||
+ | File:Power_hole.jpg|A small opening on the back of PartyBox for the wiring for power to run through | ||
+ | </gallery> | ||
+ | </center> | ||
[[File:PartyBox_Final.MOV]] | [[File:PartyBox_Final.MOV]] | ||
− | |||
− | |||
Take note in the video that the standby pattern is displayed before music starts playing and after it stops. | Take note in the video that the standby pattern is displayed before music starts playing and after it stops. | ||
Revision as of 23:04, 1 May 2017
Creators: Sarah Chen, Lydia Reader, Graham Rubin, Nathan Schmetter (TA)
Contents
Overview
PartyBox is an easily portable three dimensional cube of LEDs that creates a visual display in time to live music, so you can have a fun party anytime or anywhere. It's the perfect size for any tabletop, approximately 4.5" in each direction. The LEDs are dynamic and change color to provide an aesthetically pleasing light show that follows along to the rhythm and pitch of the music. The pattern of the LED light show can be changed with the push of a button. A library of different patterns will be created and the user can cycle through these patterns by pushing a small button on the cube. There is an additional standby mode in which the LEDs will provide a slow gradient change of color in the absence of music.
PartyBox will be made up of 3m of an addressable RGB LED strip with a total 180 LEDs. The LEDs will be on the outside of the five surfaces of the cube (not including the bottom surface). A small microphone will be built into the box that will read the analog sound signal. A spectrum shield will be attached to an Arduino to process the sound signal. The Arduino will detect the occurrences of bass frequencies to clock the tempo of the music. The lights will be in an animated display in which the coloring of the LEDs is directed by the measured tempo and pitch. A collection of light patterns will be pre-made, and the user will be able to go to a new pattern by pressing a push button. Additionally, if the Arduino does not detect volume and rhythm for a pre-determined amount of time, it will automatically go into standby mode -- a simple, slow-changing color gradient.
Objectives
- Lighting of LEDs in time with music
- Varied library of complex visual displays rather than just flashing LEDs
- Functioning standby mode and transition between standby and music
- Ability to change the pattern of the light through the push of a button
Challenges
- Getting Arduino to discern rhythm and volume of live music.
- Creating a substantial enough library of animations to keep users' interest in the cube
- Using a push button as an input
- Avoiding overheating of LEDs and the subsequent safety hazard while being able to light all LEDs at once.
- Avoiding frying the Arduino by drawing too much power to the LEDs
- Making the Arduino able to tell the difference between background noise and music
- Learning how to use addressable LED strips
- Getting microphone to work with the spectrum shield
- Processing the data from the spectrum shield
- Making sure all LEDs are bright and have enough power
- Detecting tempo of music
Budget
Item | Quantity | Price | Shipping | Link | Notes |
Arduino | 1 | 0 | 0 | Provided by lab | |
RGB LED Strip 1m | 3 | 15.95 | 9.71 | link | |
20 Gauge Wire | Provided by lab | ||||
SparkFun MEMS Microphone Breakout Board | 1 | 11.95 | 0 | link | |
Plastic Super Glue | 2 | 2.99 | 0 | link | Purchased at Dick Blick (update link) |
Arduino push button | 1 | Included in Arduino Development Kit, provided by lab | |||
100 Ohm resistors | 4 | Included in Arduino Development Kit, provided by lab | |||
Arduino Spectrum Shield | 1 | 24.95 | 2.99 | link | |
Arduino Shield Stacking Headers | 1 | 1.95 | 0 | link | Shipped with spectrum shield |
Power Source: Wall to barrel adapter | 1 | Provided by lab | |||
Power Source: DC Power Source for strips | 1 | Provided by lab | |||
Total: | $110.67 |
Gantt Chart
Designs & Solutions
Physical Design
With our objectives in place and an initial idea of what the we wanted the end result of PartyBox to look like, we began to design.
First Attempt: 3D LED Matrix
Our first design was an array of individual arrays, that had LEDs suspended on the inside and outside of the cube. We did not even attempt this before looking into addressable LED strips for several reasons, most notably that it would take a very long time to individually wire and solder 180 (our estimate for the initial size) LEDs. In addition, for this model to work, we would have to solder each LED to a decade counter, which would add even more time and work. Furthermore, we could not design a proper model that did not block the visibility of some internal LEDs.
LED Strip Cube
For our budget, we estimated we could purchase three of the addressable LED strips, which would allow for us to have 6 stripes of 6 LEDs on each face. Because the addressable LEDs came in strips of 60 and our design called for the LEDs in bits of 6, we would need to break the strip and reconnect the LEDs with solder. This process was initially very difficult, especially because the copper connection points between LEDs was so delicate, but once we figured out a method to solder, it was simple to repeat. The second design was a cube with stripes of LED strips running across each face. Each face would have 6 wells for each bit of 6 LEDs from the addressable strip to sit in.
From Fig. 1-1, you can see the the slots for the strips of the LED strip to sit in. From Fig. 1-2, we would have the wires that connected the strips slide in through the slit at the top of each face.
The problem with the second design was that it did not leave enough room for the delicate solder joints between the strip and the wall of cube, so it was extremely difficult to slide the LED strip with soldered connections through the cube. Also it would require bending the strips at the solder joints, which was basically impossible without damaging the strip. As we tried to wire one face of the cube, we discovered how delicate the solder was, as it was very likely to break either itself or the copper connection.
Larger Cube
The third design expanded the dimensions of the cube so that there was a designated space to support the solder joints, and as such, the strip could be folded on the connection wires, not on the strip joints, which is what was so fragile about the previous design. We believed that this would stabilizing the joints enough so that they would not break. During the learning process of soldering the LEDs together, we broke two of the LEDs. To make the best use out of this, we used the location that those LEDs would have gone to make room for the microphone and button.
Figure 2-1: As you can see in comparison with the second design, we expanded the length of the slots for each strip with a narrower portion on both top and bottom of the face to give length for the connections to sit to prevent bending the soldered area through the face. Figure 2-2: In addition to lengthening the sides, we also added a defined wall for the Arduino to sit in so it would not move. We also included a location for the microphone and button, the holes in the bottom left.
However, this design still had problems. Ultimately, it was the delicacy of the soldered LED connection joints. Though we have confidence in our solder, when moving the LED strips through the cube to place them on a face, several copper connection points became loose and broke away from their LED. Because all of the LEDs for all faces were soldered into one strip (with appropriate connection lengths) [INSERT IMAGE?], damage from one LED had an effect on all of the LEDs in connection. We discovered one broken connection when we first attempted to connect the LEDs to a face, and this one break resulted in short circuited lights. By the end of the our attempt at assembling the cube, there were so many LEDs broken that we were only confident that the remaining strip we had not touched with solder was still functional.
Final Design
In our fourth and final design, we realized we needed to avoid soldering the LED strip at all. Therefore, we decided in a cylindrical model that could allow the LED strip to be wrapped around it continuously. This deviated from our original design of a cube, but the decision was necessary to preserve the LEDs.
Figure 3-1: The final design of our PartyBox. The LEDs wrap around the cylinder and the Arduino and other physical components will be stored inside the box embossed with the PartyBox label. Figure 3-2: This is the diffuser that goes over the LEDs on the cylinder. However, we did not get to print this because of the time constraints. Figure 3-3: The bottom plate of the box. This includes a defined spot for the Arduino. However, we did not get to print this either due to time constraints.
Controlling the LED Strips
We chose to use addressable LED strips for easy control of our lighting. The specific strips we chose are equipped with APA102 chips because we had seen excellent reviews of these strips. To control them, we used the FastLED library, which we wrote a tutorial for here. We took advantage of the color math that this library enables to be able to create patterns.
Powering the LED Strips
One challenge we faced was powering the strips without destroying our Arduino. The Arduino could not provide enough power to the strips without overheating, so an external power supply was used instead. It was important also to make sure that the power supply did not give too much current and break the strip. To do this, we tested the power source to determine the maximum current value our strips needed to run our code. The voltage was set to 5V and the current was set initially to a very small amount, 100 mA. The strip was wired to this source, and it was seen that 100 mA was not enough current for the strip to behave normally. The current was then set to increasingly higher amounts in increments of 100 mA, until it was enough to power the strip. It was found that with our code, 1.0 A at 5V was enough power for the strips to behave normally. During the demo, we set the power supply to these values and wired the ground and +5V wires to this power supply through an external breadboard.
The Spectrum Shield
One of the biggest challenges in our proposed project is being able to discern the pitch of music. Pitch is physically given by the frequency of a sound wave. Since one song can have multiple pitches, there will be multiple frequencies present in the sound wave. Separating these frequencies with code would require some very complex processing, involving things such as Fourier Transforms. It would be likely that an Arduino would not be able to handle this intense of computation. To solve the issue of detecting pitch, we chose to go with the hardware solution rather than tackling the problem with code. The MSGEQ7 is a seven band graphic equalizer integrated circuit chip, which is capable of taking in a signal and splitting it into seven different frequency bands. We purchased this chip integrated onto a shield compatible with an Arduino UNO. The shield also featured inputs for an aux cable and a microphone, so that it was easy to input audio into our Arduino. We purchased the recommended microphone from the spectrum shield’s hookup guide to ensure compatibility. We also chose to use a microphone rather than an aux input to ensure that PartyBox could work with any audio source. The shield has connections for a left and right microphone, but we chose to only use a single microphone connected to the right input, and this did not noticeably affect the quality of our product.
Put something here about using the shield and link it to the tutorial that Graham is writing
Switching between Patterns: Button
We designed three patterns for the sound reactive portion of the LED. In order to switch between the three patterns, we used a button. In addition, because we wanted to prevent as much loss of data as we could, we used an interrupt to detect if the button had been pushed, so that there was not a detection algorithm that was constantly running.
We used a combination of the interrupt tutorial on this Wiki written by another project, Writing an Arduino Interrupt, as well as the interrupt tutorial from the Arduino website to understand how interrupts work. In addition to interrupt, we also used a debouncing method to prevent the Arduino from detecting multiple button presses with one button press. We found an example tutorial on Sparkfun here that we took inspiration from, as well as from the Arduino debounce tutorial here,
If the Arduino detects a button press, it will increase the value of the ‘counter’ variable by one. Then in the main loop of the code, we would check if counter % the number of modes == 0, 1, or 2, which corresponded to each pattern.
All of the code will be on our Github [INSERT LINK STILL], but here is a simplified version of our button code, to be generalized for any use.
#define interruptPin 2 // the pin that will be interrupted, in this case, the button pin
volatile int counter = 0; // volatile because this number will change with the interrupt
const int modes = 3; // the number of 'modes' or patterns we want to alternate between
void setup() {
pinMode(interruptPin, INPUT_PULLUP); // declare the interrupt pin as a button
attachInterrupt(digitalPinToInterrupt(interruptPin), interrupted, CHANGE); //declare how to handle the interrupt
}
void loop() {
if (counter % modes == 0) { // then it is mode 3
Random_Dots(); // display the Random_Dots() pattern
}
else if (counter % modes == 1) { // then it is mode 1
Stripes(); // display the Stripes() pattern
}
else { // it is mode 2
Ring_Dots(); // display the Ring_Dots() pattern
}
FastLED.show();
}
}
void interrupted() { // if an interrupt has been detected,
static unsigned long last_interrupt_time = 0;
unsigned long interrupt_time = millis();
// if the interrupt comes faster than 200 ms, assume it is a bounce and ignore
if (interrupt_time - last_interrupt_time > 100) {
counting();
}
last_interrupt_time = interrupt_time;
}
int lastButtonState = 1;
void counting() {
int reading = digitalRead(interruptPin);
if (reading != lastButtonState) { // if the reading at the time of the interrupt is not the same as the previous state of the button
counter++; // let it be a button press and increment the counter variable.
}
}
Results
Final Product
Take note in the video that the standby pattern is displayed before music starts playing and after it stops.
Comparison to Objectives
Our final product largely fulfilled all of our objectives, though it did have some shortcomings. For example, physical percussion on PartyBox near the position of the microphone could trick it into thinking that music was playing when it was not. However, it was mostly accurate during normal use in which no one was actually tapping it. During some songs with prolonged quiet sections, it would switch out of music mode, but it would switch back in when the song picked back up. Also, though a large majority of the time it was able to tell when music was not playing, there were a few people, such as Nathan, who had voices that were able to trick it into thinking music was playing more often than others. This is because their voices were relatively loud and within the frequency bands that we used to decide music was playing. For our other objectives, we were successful in creating three patterns that were able to be changed by pressing the button. The lighting also did clearly respond to the music.
How it could have Gone Better
We severely underestimated how fragile the copper connections were between LEDs on the LED strip. We knew it was possible to cut the strip and solder them together, however this was not at all practical for our purposes as any movement or adjusting of the strip tended to tear the copper pieces and create short circuits and damage LEDs. We saw how fragile these copper pieces were early on to our soldering, however we held out hope that once we had the LEDs stabilized onto our 3D model, this would no longer be a problem. We were wrong and we discovered this much too late, just a few days before the demo. It would have been a good idea to try connecting the LEDs to the cube earlier, rather than waiting until we had a lot soldered together, so that we could have given up on this design much sooner. Continuing with our plan meant that we wasted a lot of very valuable time soldering. We also should have aimed to have the 3D design completed much earlier, rather than at the end of the process. Because of these mistakes, we had to pivot and change our 3D design very late in the game. We adjusted our 3D design to be a cylinder instead of a cube to avoid soldering in the middle of the strips altogether. Since the 3D design was changed, the patterns also had to be radically adjusted to fit the new design. A lot of valuable time for debugging and improving was instead spent on changing the previously done work to fit the new design. We would have been able to make the patterns more complex and the tempo detection and music detection more accurate if we had made it a priority to finish the physical assembly earlier.