Team members: Kiran Vodrahalli, Collin Stedman, Raymond Zhong, Dale Markowitz
02/19/2013
We created an Internet-enabled companion cube for your computer, which displays different kinds of information by glowing red or green. Depending on its orientation, and which labeled face is oriented upwards, our companion cube displays either stock readings of the NASDAQ or the outside temperature in Princeton. As the temperature or stock index changes, the Arduino inside the cube fetches updated data from the host computer it is connected to, and modulates the brightness of red and green LED arrays inside. We thought it would be a perfect match for the topic of the first lab, LED diffusors, and that it also makes a useful and elegant desktop accent.
Ideation and Design
We started by thinking about LED diffusers, and found that the most interesting applications for us related to using them to display or convey information. We then considered a number of physical interfaces, including a tree, a panel, and various geometric shapes. We settled on a cube because we expected users to want multiple sources of information from the cube, and we thought rotating the cube was a better interface than configuring it by computer, since it would make use of the different sides of the cube. Since we have some Arduino experience, adding Internet connectivity so the Arduino and computer could talk to each other followed rather naturally.
Construction
We found that there was scrap foam in many different places we looked – the upper levels of the E-Quad, the Architecture building, and Frist among others. We went with that, instead of making our cube out of paper, because foam seemed like an excellent prototyping material. It was easy to cut, already pre-formed into sheets, and most importantly fit together like a jigsaw puzzle, allowing us to assemble the foam simply by pushing metal leads into the joints. Eventually we would want to use a laser-cut enclosure for this kind of box.
Concerns and Conclusions
We would have preferred a better spectrum of colors from our cube, but we did not have enough tricolored LEDs to produce enough light to be visible through our cube. We ran into a number of problems because of the differences in brightness and voltage between red vs. green LEDs and indicator vs. lighting LEDs, but we managed to circumvent most of those because foam was such a great diffusing material and blocked little light. Finally, we observed that the Cube is sometimes slow to respond as we scrape data from the web, because of latency. So, we’d like to make it faster if possible.
We think our companion cube is pretty and works well. If we had developed the cube further, it would have more applications — possibly one for each side of the cube, including email notifications, facebook notifications, etc. — and it would use an orientation sensor rather than photoresistors on each side to figure out its orientation.
Design Sketches
Tetrahedron, Prism, some ideas for functionality
Initial Designs: The Tree of Tweets
Perhaps a rotating cube? With a base?
More Designs for the Cube
Initial Design for LEDs inside the Cube
LED inside the Cube
Rice paper in the middle, cardboard outside
Parts of the Cube
More detailed description of how the cube fits together
Dimensions of the Cube Side
Arduino and Breadboard inside the Cube
Circuit Design:
Arduino Circuit for Port 5: The Red LED array
Circuit for Arduino Port 3, the Green LED
The photocell input circuit
The Final Product! :
The stock market is going down today 🙁
The weather is warmish! (At least, more than 33 degrees F! Winter at Princeton.)
4 Red LEDs, 1 White LED, Green marker, Arduino Board, USB Cable, MacBook Air, Wires, 5.6 KOhm resistor, 560 Ohm resistor, photosensor, glue, styrofoam, breadboard
Tools we used: Wire strippers, Multimeter, Scissors, Razor
We also used some Python libraries, as documented in the code.
How to make your very own Wondrous Weather Cube:
You’ll need the parts given above, as well as the code given on the GitHub repo listed below. Assemble the circuit given in the circuit diagram included above. Hopefully the product should look similar to the picture of the completed circuit provided above. Then, build the cube by cutting the Styrofoam squares as shown in the design pictures. Glue the sides of the foam together. You may have to cut a small hole for the USB cable. Then, put the Arduino into the cube, and connect to a computer. First run the arduino code (weather_nasdaqCube.ino), then run the Python code (cube_handler.py). Flip the cube over to test modes. Voila! You now have your own working Wondrous Weather Cube!
Here are some ideas for the third part of the lab. Finding a way to make the diffuser useful was difficult.
Click on the picture for a better view.
I decided to build the first idea, a device to improve the reaction times of people who drag race. Three LED’s, red, yellow, and green were used to simulate the “tree” of lights that is used to signal the beginning of a race. Several pieces of cellophane tape were used as a diffuser for the LED’s although napkins and a water bottle were also considered. The red light illuminates, the yellow flashes three times, and then the green light comes on. When this happens the person using the device pushes and holds the switch button supplied in the kit as they would the accelerator pedal if they were racing. If they false start, only the red light illuminates while a clean start lights all three lights. After a few seconds, the sequence begins again. The system was reasonably fun to play with, and I consider it a success. Some improvements would be adding additional yellow LED’s to allow them to stay lit for the countdown (more realistic), using a switch that mounts to the breadboard or one that has a form factor like a clutch pedal, and using the computer to report reaction times to track improvements.
Here are some videos of the system in action and a few pictures of its layout.
Connect pins 11, 10, and 9 through independent 330 ohm resistors and red, green and yellow LED’s respectively to ground. Also connect the switch between 5V and Pin 2. A 10 k pull-down resistor connected to ground was used on Pin 2. Clip leads should be used, as the switch does not make good contact with the breadboard. The code below was used to control everything.
// This code is inspired by the Blink example included with the Arduino.
// Also some inspiration is taken from the Button tuturial available at
// http://www.arduino.cc/en/Tutorial/Button
int red = 11;
int green = 10;
int yellow = 9;
const int buttonPin = 2; // the number of the pushbutton pin
int buttonState = 0;
void setup() {
// put your setup code here, to run once:
pinMode(red, OUTPUT); // sets the pin as output
pinMode(green, OUTPUT); // sets the pin as output
pinMode(yellow, OUTPUT); // sets the pin as output
pinMode(buttonPin, INPUT);
}
void loop() {
// put your main code here, to run repeatedly:
for (int i = yellow; i <= red; i++) {
digitalWrite(i, LOW);
}
delay(5000);
digitalWrite(red, HIGH);
delay(500);
for (int i = 0; i < 3; i++) {
digitalWrite(yellow, HIGH);
delay(150);
digitalWrite(yellow, LOW);
delay(350) ;
}
buttonState = digitalRead(buttonPin);
if (buttonState == HIGH) {
delay(4000);
}
else if (buttonState == LOW) {
digitalWrite(green, HIGH);
digitalWrite(yellow, HIGH);
delay(3000);
}
}
Group Members: Matthew Drabick, Adam Suczewski, Andrew Callahan, Peter Grabowski
High Level Description:
For part 3 of the lab, our group decided to build a “Simon” game. Our game setup uses 3 buttons and 4 LEDs. Each button corresponds to one LED and the 4th LED is used to indicate an error. The game starts with the arduino flashing one of the 3 lights, chosen randomly. The user must then press the button corresponding to that light. If the user’s input is correct, the arduino extends the pattern by one and the user must then match that extended pattern. If the user’s input is incorrect, the error light goes off and the user loses the game. This process repeats until the pattern reaches length 7, in which case the user wins the game.
Our game is mounted a paper plate for support and uses origami balloons to diffuse light from the leds.
Here is a video of the game in action:
High Level Design Process:
We began with brainstorming. Our initial ideas included interactive and non-interactive designs. These ideas included pre-set light display patterns (Morse code or musical patterns), diffusers using various translucent paper and plastic covers, and a binary counter.
We decided to first make the binary counter, as we thought it would be both technically and visually interesting. We also would have the opportunity to use our origami balloon/lantern diffusers which we thought were pretty cool.
The binary counter consisted of two buttons (an increment and a decrement) as well four LEDs to display a 4 bit number. With those four LEDs, we could count from 0 to fifteen, and display a fun pattern on overflow or underflow.
We began by sketching our design and drawing the circuitry. Here are our initial brainstorming sketches:
Drawing of the binary counter interface.
Diagram of the binary counter circuitry.
We then assembled our circuit and wrote the code to power our binary counter (technical details given below). In the end we built this:
After completing the binary counter though, we considered our design choices and thought about what we could do to make our circuit better. After making modifications and iterating through different design choices, we decided that what our circuit was lacking was an interesting method of interacting with the counter. We liked how the binary counter was interactive; however, it was limited to single presses doing the same thing every time. With this in mind, we considered various ways of expanding on our counter, such as using the counter to select and play one of 16 different pre-set light patterns (which could be Morse code messages or other interesting displays) or to play a game. In the end we decided to create the Simon game described above.
An initial drawing of the simon interface
Initial design decisions for Simon included how to organize the user interface and how many lights and buttons to include. We decided to use a paper plate as the body of our game as it was easy to manipulate but also gave sufficient support. We initially planned to make the game with 4 lights and 4 buttons, but reduced those numbers to 3 as we continued in the design process and faced limitations due to the availability of resources and bulkiness of alligator clips.
A look at the alligator clips connecting the leds and buttons to the bread board
Once the basic layout of the game was implemented, we made gameplay decisions like how long to wait between flashes of light and how long the pattern should be for the user to win. We made these decisions by playing the game ourselves, and by having other people play our game. We also had to work out bugs such as a single button press being registered twice. After trying our game with different parameters, we arrived at our final design.
There were 2 main circuit components that we used to power our game: LEDs and buttons (these were used with resistors, as needed). In the first 2 parts of the lab, we became familiar with using LEDs. Helpful information about using LEDs with arduinos is found at http://arduino.cc/en/Tutorial/blink.
LEDs are implemented by creating a connection between an Arduion pin and ground. (Image from arduino.cc/en/tutorial/blink)
We then looked up how to use buttons with arduino at http://arduino.cc/en/tutorial/button. To use a button, we needed to provide a path from ground to 5v (with a resistor) as well as a path to an input pin to sense when the button is closed.
Buttons are implemented by creating a path between ground, 5v, and an input pin. (Image from arduino.cc/en/tutorial/button)
With an understanding of buttons and LEDs, we were able to get started with the technical side of the design process.
We started by drawing the circuitry for our game. There are four LED’s and three buttons in the final implementation but only 3 leds in the diagram below. The fourth LED is an indicator light for when you incorrectly input a sequence.
An initial drawing of simon circuitry
With these design sketches, we were then able to implement our design on the breadboard and mount the buttons and lights on the plate. Though the organization of wires in our pictures looks complicated, it is essentially 4 leds/resistors connected to a digital input pin and ground, and 3 button/resistors connected to a digital input pin, ground, and 5v.
We did not reach our final design immediately though. Our initial design had the LED’s on the inside; we eventually decided to move them to the outside of paper plate for the final prototype. This allowed the diffusers to fit better and also made room for our center failure indication LED. We also attempted to incorporate a 4th LED/button pair but found we were limited on resources.
With the circuitry in place, we then focused on the physical construction. For the led diffusers, we chose to uses the origami ballons/lanterns that we had used previously for the binary counter. We used these origami instructions to make four balloons out of dum-dum wrappers.
A single origami balloon used to diffuse light.
For the base of the game, we took a paper plate and poked four holes for each button (one for each leg) and a single hole for each LED. We then could insert the switches and LEDs and attach alligator clips to the bottom to make the circuits displayed in the tutorials and our diagrams. By following those design diagrams, we constructed what you see in the picture below.
Wiring of simon interface to arduino
As you can see, we have supported the plate with three stationary clamps (“helping hands”). This allows the alligator clips to hang down, making the circuits easy to connect and prevent them from touching accidentally. This also allowed us easy access during debugging. After some cleaning up of our wires we finished our simon design. Here is a walkthrough of the finished project:
How to:
1) After reading over the blink tutorial, connect LEDs to your bread board so they connect to digital input pins 9, 10, 11, and 12, a resistor, and ground.
2) After reading over the button tutorial, connect your buttons to your bread board so they connect to digital input pins 2, 3, and 4, ground and 5v.
Our simon breadboard.
3) Run some test code on you Arduino. Start by running blink on each led to check that you leds and connections are working. Then, try the button code to test that each button is working. Finally, upload the code below to check that the simon game works.
4) Construct the base of the game using a paper plate or similar material. Arrange the buttons/leds in the manner shown below with the electrical contacts sticking through the plate.
5) Construct 4 origami balloons to act as diffusers.
6) Move the 4 leds and 3 buttons on your breadboard over to the plate setup one by one by running aligator clips from the plate setup to the breadboard.
7) Repeat set 3.
8) Cover each led with an origami balloon diffuser. Hot glue to balloons to the plate for support.
Hot gluing origami balloon diffusers to leds
9) You’re done!
The Code:
Our code starts by initializing a random array, with length equal to the number of button presses needed to win. It flashes the first color in the sequence, and then falls into the main loop, continually checking for button presses. When a button is pressed, the Arduino checks if it corresponds to the next color in the sequence. If it is the expected color, it advances the position in the sequence by 1. Otherwise, it flashes the sad face led and resets. When the user has reentered the sequence correctly, the next element is added to the sequence, and the game repeats until the user has succeeded on the maximum level.
The most significant problem we had was single button presses being recognized as double presses. We had trouble eliminating this behavior completely, but found some success by introducing a delay of about 250 milliseconds after handling each press.
Here is the code we used for the project:
const int numButtons = 3;
const int buttonPins[] = {2,3,4}; // arduino input pins
const int ledPins[] = {9,10,11}; // arduino output pins
const int errorLed = 12;
const int maxLength = 5;
int randSeq[maxLength]; // contains randomly gen'd game seq
int level; // current level
int numCorrect; // how many pins you've pressed correctly so far
// always less than level
int lastStates[numButtons]; // to check button input
void setup() {
victory();
delay(250);
resetState();
randomSeed(analogRead(0));
}
//initialize randSeq with random values between 0 and numButtons
int makeArray(void) {
int i;
for (i = 0; i < maxLength; i++) {
randSeq[i] = random(numButtons);
}
}
// flash a given led
void flashLed (int ledNum) {
analogWrite(ledNum, 0);
delay(50);
analogWrite(ledNum, 255);
delay(200);
analogWrite(ledNum, 0);
delay(50);
}
// handle input
void checkInput(int i) {
// wrong button was pressed
if (randSeq[numCorrect] != i) {
flashLed(errorLed);
flashLed(errorLed);
flashLed(errorLed);
delay(250);
resetState();
return;
}
// correct button was pressed
else {
numCorrect++;
// check for last button in level
if (numCorrect == level) {
// check for last level in game
if (level == maxLength) {
victory();
delay(250);
resetState();
}
// not last level in game
else {
delay(500);
numCorrect = 0;
level++;
flashSeq();
}
}
// not last button in level
else {
delay(100);
}
}
}
// determine which button was pressed
void checkButtons () {
int i;
for (i = 0; i < numButtons; i++) {
int state = digitalRead(buttonPins[i]);
if (state != lastStates[i]) {
if (state == HIGH) {
checkInput(i);
delay(100);
}
lastStates[i] = state;
}
}
}
// flash the sequence of leds up to current level
void flashSeq(){
int i;
for (i = 0; i < level; i++){
flashLed(ledPins[randSeq[i]]);
delay(250);
}
}
// turn all leds off
void setAllOff() {
analogWrite(ledPins[0], 0);
analogWrite(ledPins[1], 0);
analogWrite(ledPins[2], 0);
}
// turn all leds on
void setAllOn() {
analogWrite(ledPins[0], 255);
analogWrite(ledPins[1], 255);
analogWrite(ledPins[2], 255);
}
// flash all leds
void flashLeds(){
setAllOff();
delay(100);
setAllOn();
delay(100);
setAllOff();
}
// flash the leds in a circle
void circle() {
setAllOff();
delay(100);
analogWrite(ledPins[0], 255);
delay(100);
analogWrite(ledPins[0], 0);
analogWrite(ledPins[1], 255);
delay(100);
analogWrite(ledPins[1], 0);
analogWrite(ledPins[2], 255);
delay(100);
analogWrite(ledPins[2], 0);
delay(100);
}
// special victory flash sequence
void victory() {
flashLeds();
flashLeds();
flashLeds();
circle();
circle();
circle();
flashLeds();
flashLeds();
flashLeds();
}
// reset for a new game
void resetState() {
makeArray();
level = 1;
numCorrect = 0;
// delay(500);
flashSeq();
}
// main loop
void loop() {
checkButtons();
}
Group name: %eiip (everything in its place) Bonnie Eisenman (bmeisenm), Valya Barboy (vbarboy), Erica Portnoy (eportnoy), Mario Alvarez (mmcgil)
Brainstorming list
Paper that can erase itself, keep track of changes
Paper with real-life version control, you can revert it to a previous state, and it includes backups
Real life version control for room, clothes, etc. organization
Cheap projector for when you can’t alter your surfaces (for decoration)
A bookshelf that keeps track of the books on it by using smart book covers or stickers in the books
Sketch of smart bookshelf
Self-adjusting exoskeleton for people who have to stand up for long periods of time (for under your clothes)
A screen position optimized for a person laying down in bed
A real-time translator that strips your speech of mean comments and makes them nice
Clothing or gloves embedded with sound sensors to facilitate echolocation
Sketch of echolocation clothing
Material-free umbrella that repels water using air blowing, possibly.
Clothing that generates electricity from movement and recharges batteries
Hackable clothing that converts energy from motion into changing designs (for fashion options)
A machine that helps you duplicate (scan and print) books licensed under creative commons (or public domain)
Sleep cycle alarm but not based on phone being in your bed; preferably attached to your body
Sketch of sleep cycle alarm
Conductive clothing that generates electricity for keeping you warm
Sketch of conductive warming clothing
Real-time autotuning for vocal cords
EZ-pass for real life: getting into dining halls, or even concerts, etc: a system that scans your ID automagically and also photographs people whose IDs aren’t working
Sketch of EZ-pass for people
Rigorous rock band vocals where it tells you if you do something wrong, and helps out when you’re doing it wrong (for vocal training)
Theatre lighting board user interface; automating; virtual stage
Hair cutting machine like in chitty chitty bang bang
Pockets or bags that keep track of what’s in them
Sketch of smart bag
3D printing for clothing
Smart binder that scans and keeps track of the papers in it, or automatically digitizes them → integrate web and paper → e-ink on binders (you could display the syllabus and everything else)
Sketch of smart binder
Hoods with heaters so you don’t look like a criminal while keeping warm in the winter, or other invisible heated clothing (for face)
Prox or other chip required to open laundry door in order to prevent theft.
Robots that automatically declog the hair from your drain.
Plant that notifies you when the soil is dry
Litterbox that alerts you when it needs to be cleaned
A way to alert you when you’re grinding your teeth — a cover for your molar that vibrates etc when you grind your teeth?
Portable gas chromatographer–mass spectrometer for detecting allergens in air and food
Flex sensors in gloves to determine how often you’re clenching fists / are stressed, and tell your doctor
Ping pong balls that record their speeds
Smart ping pong table that tells you if it’s in bounds
Chessboards that highlight good next possible moves for teaching
Cheap nighttime illumination: sticker with light sensor and LED for dark glow
Convert human body language to text or visual information that can be sent during electronic remote conversation
Force human hand muscle contraction or flex sensors and motors in a glove to teach sign language
Force human hand muscle contraction or flex sensors and motors in a glove to teach kids to write
Portable self-inflicted electroshock conditioning for improving learning speed
A gestural interface for manipulation of 3D models.
3-D mouse for manipulating 3-D models, etc. → possibly using a cube with viscous liquid, or a device with an accelerometer, or hacking an optical mouse (preferably that also works in 3D)
Curtains / blinds that open and close based on incoming light and normal use patterns (like the Nest does for temperature – save on lighting, help temperature like Icahn)
Sketch of automatic blinds
Throwing teacher: sensor on object being thrown, calculate what to fix, and inform the thrower. Like frisbee, football.
Smart clothes that inform you when they don’t match
RemberRings – small (wearable!) rings that you can use to record to-dos; press a button to record an idea or play back the recording
GPS + FLORA: embed a GPS in your doggie sweater, so you can keep track of your dog via GPS instead of implanting a microchip, since that freaks some people out. Or, you know, secretly put one in your kid’s jacket.
Auto-sensing LifeAlert: like LifeAlert, a necklace you wear, but this one measures your pulse, and alerts your doctor and / or family if your heart stops?
Wearable GPS: tracks your location, points or nudges you in correct direction for your destination. Could be a bracelet, ring, etc.
Universal car remote to start car and turn on heat
Bike lock that sabotages bike if you dont unlock it (less bulky than a normal lock, hopefully)
Wine bottle reusable cork that determines if wine has gone bad (oxygenation sensor?)
“Windshield wipers” for automatically and quickly erasing chalkboards/whiteboards during a lecture
A programmable teapot that has the hot water ready for you, based on the time you’ve set your alarm for in the morning.
A camera that gets facial expressions of kids in classrooms and somehow alerts teacher when class is confused, bored, etc, so that they can adjust speed
Project choice: Biblio-File
To choose our idea, we each picked two ideas from the list, compiled them into a short list, and we cast three votes (indicated by *) each amongst these top 8 ideas (bookshelf****, echolocation***, automatic blinds*, smart binder *, smart bags *, real life EZ pass*, sleep cycle alarm, self-warming clothing*). We chose to implement a bookshelf that keeps track of the books in it. It is an example of embedded computing as it is based around physical books and the shelves they are on, although we may choose to incorporate an application in addition. It addresses a real-world problem, as it addresses the problem of locating, organizing, and keeping track of books, although the problem really extends to physical objects in general. As elucidated below, it has a specific target group of users. We feel that we can create a prototype between now and May, on a relatively limited budget. Many of our other ideas were too large in scope, did not address a problem that we felt actually existed, or simply did not excite us as much.
Target user group
Our target user is a person who owns a lot of books and ideally has some disposable income. Let’s call our target user Jane. She in a sixty-year-old professional with a large book collection, somewhere between 20 and 500 books, and a voracious reader. She has a bit of arthritis and hates searching for books on her bookshelf. She needs to find books quickly, and doesn’t want to waste time micromanaging and organizing her book collection. She also hates “losing” books that she already owns because she can’t be bothered to search through all of her books. We are not really concerned with libraries, which have specific and perhaps idiosyncratic needs, or book collectors, who may be unwilling to modify their books.
Jane, an elderly voracious reader
Problem description and context
Imagine a person with lots of books. It could be a college student, a professor, a senior citizen, and/or a bibliophile. When the user goes to look for a specific book, it might be time-consuming and very difficult to find. The user might have to bend over, look in the same place multiple times, or even fail to find it. He might not remember whether he put this particular book on his bookshelf at home or in his office. Maybe he lent this book to a friend, and doesn’t even currently have it. The consumer does not really have the time to reorganize his books, and cannot remember where he put what. Our bookshelf would solve these problems by remembering the books that are in it, as well as where on the bookshelf they are, and allowing the user to search for a book in a given shelf. As far as we know, based on Googling the problem, no related or complementary solutions exist already.
Professor Dave, our absentminded user
Justification of the technology platform
We’ve chosen to use the Arduino microcontroller platform to implement this project. We believe the Arduino is the most appropriate because of its low cost, its ability to interface with low-level electronics (such as our indicator LEDs), and its compatibility with a wide array of sensors. This last is important because we are not yet exactly sure how we will implement sensing the locations of books, and we don’t want to limit our options. Add-ons for the Arduino enable it to have network connectivity (such as this one), which will be needed for the system to look up books based on their ISBN bar-codes. Additionally we need to create an interface for users to input information about the books they’re trying to find, so the system can help them find it. This could be a web app, a mobile app, or even a screen/keyboard built into the bookshelf unit.
by Farhan Abrol (fabrol), Kuni Nagakura (nagakura@), Yaared-Al-Mehairi (kyal@) and Joe Turchiano (jturchia)
Concept:
For our diffuser, we designed an authentic tri-color Bedside Floral Lamp. The lamp was constructed from tree branch (spine of lamp), CD casing (base of lamp), six single-colored LED lights (red, green, and yellow), several wires, 6 short-size rolling papers, strips of aluminum foil, and a hot glue gun. Three potentiometers control the LED lights on the lamp (one for red, one for green, and one for yellow). When users wish to turn the lamp on, they simply twist the potentiometers to increase the brightness of the potentiometer’s corresponding color. With the LED lights on, the rolling papers, i.e. ‘light shades’, act as effective diffusers, which combined with the reflective strips of aluminum foil create visually attractive light patterns. Users can modify the lamps color and brightness with the potentiometers to set the appropriate mood. When users wish to turn the lamp off, they simply must reset the potentiometers, which turns all the lights off.
We decided to build a tri-color Bedside Floral Lamp because we wanted to create an aesthetically pleasing light source that users could tune to their mood. Conceptually, the LED lights represent the seeds of the flower and the aluminum strips the petals. Collectively, we are pleased with the result of our design. We especially like the addition of aluminum strips, which enhances the light diffusion process and therefore creates even more optically enjoyable effects.
One problem with our design though is that the aluminum strips are not rigid enough, and so tend to keep falling down, thereby failing to reflect the LED lights. An improvement that could be made would be to add some kind of support to the aluminum strips to keep them in place, and therefore acting as effective reflectors.
At first, we tried to build a Bedside CD Lamp because we thought CDs would be effective diffractors of light. It turned out that due to the limited power of our LED lights, CDs would only create a rather underwhelming light diffusion effect.
Design:
Through our design process, we considered 3 prototypes. Of these sketches, we actually conceived 2 of our prototypes and ultimately decided on our final design.
We began with the idea of the lamp and considered various ways to diffuse the light. Our first two prototypes used CDs to diffuse the light and our final prototype makes use of rolling papers and aluminum foil.
Initial rough sketch for our first prototype
This initial model was discarded because of structural issues. The 8 CDs would not stay together without adding additional structural supports. Our second prototype, which incorporates 3 CDs instead of 8 simplifies the structure of our lamp.
Sketch of our second prototype
Sketch of our circuitry
Straight view of second prototype
Aerial view of second prototype
We finished building our second prototype; however upon testing in various lighting conditions, we decided that the CDs were not adequate diffusers for our LED lights. Thus, for our final prototype, we chose to use different materials for our diffuser, and our final design incorporates rolling papers that wrap around the LED light and aluminum strips that surround the lights. A potentiometer that corresponds to the 3 sets of LED lights (red, green, yellow) give the user control over the mood and color of the lamp.
Sketch of prototype 3
Final design sketch
3 Potentiometer for each color (red, green, yellow)
The Finished Prototype
Close-up of the diffuser
Yellow LED’s
Red LED’s
Green LED’s
Demo:
Parts List:
6 LED’s (20mA, 2V) – 2 red, 2 yellow, 2 green
Green and Brown insulated copper wire
3 Compact discs
1 Flex sensor
Pack of short-size rolling papers
1 roll Aluminium foil
3 rotary potentiometers
1 Tree branch for support
CD-holder base (or similar rigid base)
1 Soldering iron
3 Alligator clips
1 Glue gun
1 Arduino board
Instructions:
Start by gluing the wires that will connect the led’s from the top of the branch to the Arduino. Glue the brown wires first. Run the wire along the side of the support leaving about 3″ at the top and about 6″ at the bottom extra for making electrical connections. Then wrap the green wire around these wires and glue it, again leaving extra wire at the ends for connections.
Cut a hole in the center of the CD-holder base and run all the wires through it. Make the support stand upright on the base and glue the bottom to fix it in position.
For each pair of LED’s of the same color, solder the negative of one to the positive of the other. These pair’s will act as the building blocks for the LED pattern at the top of the support. Strip the ends of all the wires at the top of the support. For each pair of LED’s, connect the positive end to one of the brown wires and the negative end to the green wire (which acts as ground). Make a note of which brown wire connects to which color.
Connect the other end of the wires to the Arduino pins through a 330 ohm resistor in series with each, in the following manner –
Red LED’s – Pin 9
Green LED’s – Pin 10
Yellow LED’s – Pin 11.
Make conical light shades using the rolling papers and cover each LED with one conical shade.
Cut out 6 – 5″ X 1″ strips of aluminium foil and layer them to make each strip stiffer. Then, attach each of the strips around the support in a floral pattern, with the bottom end taped below the LED’s and the upper ends hanging loose.
Attach the leftmost pin of each potentiometer to ground, and the rightmost pin of each to 5V. Attach the middle pins to A0, A1 and A2 for yellow, green and red led’s respectively.
Source Code:
/* Radiate
* Group: Yaared Al-Mehairi, Kuni Nagakura, Farhan Abrol, Joe Turchiano
* ------------------
* The circuit:
* LED's (red, green, and yellow) are attached from digital pins 8, 9,
* and 10 to ground. We connect potentiometers to analog in pins 9,10,11.
*/
// These constants won't change. They're used to give names
// to the pins used:
const int analogInPinY = A0; // Analog input pin that the potentiometer is attached to
const int analogInPinG = A1; // Analog input pin that the potentiometer is attached to
const int analogInPinR = A2; // Analog input pin that the potentiometer is attached to
const int analogOutPinY = 9; // Analog output pin that the LED is attached to
const int analogOutPinG = 10; // Analog output pin that the LED is attached to
const int analogOutPinR = 11; // Analog output pin that the LED is attached to
int sensorValueY = 0; // value read from the pot
int sensorValueG = 0; // value read from the pot
int sensorValueR = 0; // value read from the pot
int outputValueY = 0; // value output to the PWM (analog out)
int outputValueG = 0; // value output to the PWM (analog out)
int outputValueR = 0; // value output to the PWM (analog out)
void setup() {
// initialize serial communications at 9600 bps:
Serial.begin(9600);
}
void loop() {
// read the analog in value:
sensorValueY = analogRead(analogInPinY);
sensorValueG = analogRead(analogInPinG);
sensorValueR = analogRead(analogInPinR);
// map it to the range of the analog out:
outputValueY = map(sensorValueY, 0, 1023, 0, 255);
outputValueG = map(sensorValueG, 0, 1023, 0, 255);
outputValueR = map(sensorValueR, 0, 1023, 0, 255);
// change the analog out value:
analogWrite(analogOutPinY, outputValueY);
analogWrite(analogOutPinG, outputValueG);
analogWrite(analogOutPinR, outputValueR);
// wait 2 milliseconds before the next loop
// for the analog-to-digital converter to settle
// after the last reading:
delay(2);
}
Group Members: Sam Payne, Prerna Ramachandra, Dillon Reisman, Abbi Ward
Early idea sketches:
1) Gummi-Bear RGB color-mixer!
Sliding your finger on a slide-sensor transfers light between three R-G-B gummi bears!
3) The “Waker-Upper”
A device that detects when your head leans, indicating that you fell asleep. Triggers LEDs in glasses to wake you up
Idea actually implemented:
We built a color matching game. The computer will generate a random color, then the user must use a touch sensitive slide control to try and match that color. When the user thinks that they have matched the color they press a button to accept. A blue LED will flash if the colors match and a red LED will flash if they do not match. The game then resets and repeats. There is no score, or meta-game these can be added to later models if desired. The difficulty of the game can be adjusted to change how closely the colors must match. This first model of the game was built with a sensor which was not ideal for the task – the resistance characteristic is exponential rather than linear depending where the user presses on it. The controls were adjusted to correct for this, but the next model should be built with a sensor with a linear characteristic to improve the feel of the user’s controls.
Graph showing linear mixing of colors as finger slides across the sensor.
Player attempts to match right diffuser to left diffuser.
Diffuser shows off vibrant light in the dark
Parts:
Parts List
2 RGB LEDs
1 blue LED
1 red LED
8 330-Ohm Resistors
1 1-kOhm Resistor
1 10-kOhm Resistor (for the switch)
1 slider sensor
1 button switch
2 square sheets of paper for the diffusers
1 paper napkin
Instructions to recreate:
Follow the given schematic(below) to construct the circuit. The diffusers are built using small square pieces of paper (~3×3 inches) that are folded into origami paper ballons (see: http://www.youtube.com/watch?v=tSMLk_zGzf4). Cut a hole in the bottom of the balloon so that the LED can fit. Also, inside the balloon place a small sheet of 1-ply paper napkin to help diffuse the light. Finally, program the Arduino with the following code.
Schematic view of Color game
Close-up of diffuser
Code used for Arduino:
/*
* Names: Sam Payne, Abbi Ward, Dillon Reisman, Prerna Ramachandra
* Date: 2/10/13
* Class: COS 469, L0
*
* Description: Color Game -- player
*
* Hardware:
* 2 RGB LEDs, 1 red LED, 1 green LED
* 1 slider sensor
* 1 button switch
*
*/
//pin assignments
//user LED
int redUser = 11;
int greenUser = 10;
int blueUser = 9;
//NPC LED
int redNPC = 6;
int greenNPC = 5;
int blueNPC = 3;
//victory indicators
int redLED = 13;
int greenLED = 12;
//analog in's
int sensorPin = A0;
//colors assigned user and computer
int targetRed;
int targetGreen;
int targetBlue;
int selRed;
int selGreen;
int selBlue;
int buttonPin = 2;
int buttonState = HIGH;
int sensorValue = 0;
int tolerance = 64; //this can be adjusted for difficulty (lower = more difficult)
int victory = 0;
void setup() {
pinMode(buttonPin, INPUT);
}
void loop() {
//generate random color
targetRed = random(0,255);
targetGreen = random(0,255);
targetBlue = random(0,255);
//ensure that color can be selected by slider
if((targetRed <= targetGreen) && (targetRed <= targetBlue))
targetRed = 0;
else if((targetGreen < targetRed) && (targetGreen < targetBlue))
targetGreen = 0;
else
targetBlue = 0;
//ensure that color can be selected by slider
if((targetRed >= targetGreen) && (targetRed >= targetBlue))
targetRed = 255;
else if((targetGreen > targetRed) && (targetGreen > targetBlue))
targetGreen = 255;
else
targetBlue = 255;
analogWrite(redNPC, targetRed);
analogWrite(greenNPC, targetGreen);
analogWrite(blueNPC, targetBlue);
selRed = 0;
selGreen = 0;
selBlue = 0;
//adjust user input
while(1) {
//read user input color
sensorValue = analogRead(sensorPin);
//set display colors based on slider
setColors_slider(sensorValue);
//display user color
analogWrite(redUser, selRed);
analogWrite(greenUser, selGreen);
analogWrite(blueUser, selBlue);
//when user presses accept, save color
buttonState = digitalRead(buttonPin);
if(buttonState == LOW) {
break;
}
}
victory = 1;
//determine if we are within tolerance
if(selRed > (targetRed + tolerance)) victory = 0;
if(selRed < (targetRed - tolerance)) victory = 0;
if(selGreen > (targetGreen + tolerance)) victory = 0;
if(selGreen < (targetGreen - tolerance)) victory = 0;
if(selBlue > (targetBlue + tolerance)) victory = 0;
if(selBlue < (targetBlue - tolerance)) victory = 0;
//if user color is in tolerance, flash green LED
if(victory == 1) {
for(int i = 0; i < 5; i++) {
digitalWrite(greenLED, HIGH);
delay(100);
digitalWrite(greenLED, LOW);
delay(100);
}
} else {
//else flash red LED
for(int i = 0; i < 5; i++) {
digitalWrite(redLED, HIGH);
delay(100);
digitalWrite(redLED, LOW);
delay(100);
}
}
}
// reads in the value from the slider and sets the RGB LED
/* This function maps from 1D on the slider to 3D (R, G, B)
At any time, one of the 3 dimensions is 0, and another is 255.
The last scales linearly within particular ranges of color.
*/
void setColors_slider(int readValA) {
int readVal = map(readValA, 100, 550, 160, 256);
/* linear scale
int R = 160;
int Y = 176;
int G = 192;
int GB = 208;
int B = 224;
int P = 240;
int RH = 256;
*/
// exponential scale - wrong way
/*
int R = 160;
int Y = 193;
int G = 215;
int GB = 230;
int B = 239;
int P = 248;
int RH = 256;
*/
// exponential scale - right way
// 33, 22, 15, 9, 9, 8
int R = 160;
int Y = 168;
int G = 177;
int GB = 186;
int B = 201;
int P = 223;
int RH = 256;
//set Red
if(readVal <= Y)
selRed = 255;
else if(readVal > Y && readVal <= G)
selRed = (255 - ((readVal - Y) * 255/(G-Y)));
else if(readVal > B && readVal <= P)
selRed = ((readVal - B) * 255/(P-B));
else if((readVal > P && readVal <= RH) || readVal > RH)
selRed = 255;
else
selRed = 0;
//set green
if(readVal > Y && readVal <= GB)
selGreen = 255;
else if(readVal <= Y && readVal > R)
selGreen = ((readVal - R) * 255/(Y-R))-1;
else if(readVal > GB && readVal <= B)
selGreen = (255 - ((readVal - GB) * 255/(B-GB)));
else
selGreen = 0;
//set blue
if(readVal > G && readVal <= GB)
selBlue = ((readVal - G) * 255/(GB-G));
else if(readVal > GB && readVal <= P)
selBlue = 255;
else if(readVal > P && readVal <= RH)
selBlue = (255 - ((readVal - B) * 255/(RH-P)));
else
selBlue = 0;
}
Group members: Alan Thorne, Dylan Bowman, Harvest Zhang, Tae Jun Ham
Sketches:
Three sketches. The first, (and the one we built,) a police siren complete with flashing lights and wailing speaker, with no input other than a button (used like a switch) to turn it on or off. The second idea was a whack-a-LED game, where we use light sensors along with LEDs poking out of a grid; to play, you cover up the grid hole where the LED is lit, and the light sensor placed there detects that and gives you points. The final idea is a traffic light that responds to a walk signal, but is otherwise a normal traffic light that is programmed to hold the same durations for red and green every cycle.
The Blues and Tunes Police Siren:
The Blues and Tunes police siren has an LED light bar, a single auxiliary LED flasher, and a speaker in order to flag down speeding Arduinos. It executes two types of flashing and wailing — one in the style of American police vehicles and the other more European (the European siren mode was added primarily because we ran out of blue and red LEDs, and used two yellow ones, which do show up in some European police vehicles but almost never in US vehicles). It has a pushbutton that starts and stops the siren.
Visible here is the large breadboard, containing the main LED light bar as well as the auxiliary one, mounted on the plastic blister packaging that also serves as a crude sort of resonator for the piezo speaker underneath.
Visible here: the red breadboard containing the on/off button, the Arduino, and the main breadboard.
Here we see the lights in action. This particular implementation features two separate light and sound patterns.
For the most part, it works pretty well; the siren isn’t particularly loud, but it is annoying enough to earn looks from other lab groups if left on. The diffusers are acceptable but not very nice. A better light bar with a bunch of fresnel lenses would be ideal, but no one had miniature police light bar diffusers lying around. We could have also programmed the pushbutton to cycle through various types of sirens, but in this implementation we just hardcoded two alternating patterns.
(1) Blister packaging strip covered in scotch tape for the main light bar
Make one yourself:
Arrange all but the RGB LED in a visually pleasing manner on the large breadboard in the style of a police light bar.
Add one 330 Ohm resistor between each LED and the Arduino. Connect the yellow RGBs to the same I/O pin and the red RGBs to the same I/O pin. Give the blue one its own pin. These are all digital I/O pins.
Place the RGB LED in a prominent location on the large breadboard. We will be using only the red and blue pins (not the green one) from the RGB LED. Connect those (through resistors) to two I/O pins.
Mount the pushbutton on the small breadboard and wire it up to the 5V pin. (You could also put it on the large breadboard with everything else, but there’s a lot of stuff on that one already.)
Wire up the piezo speaker to an I/O pin.
Make an appropriately light-bar-styled diffuser out of something translucent, and make another one for the RGB LED. Put them over the LEDs.
The piezo speaker also gets much louder if you give it something larger to vibrate, so tape the piezo onto a blister package or something similar to make it sound more like a siren and less like a singing holiday card.
Write up the code, and play the siren!
The code:
// ENUMS
int OFF = 0;
int ON = 1;
int TRANSITION = 2;
// Names for things
int button = 2;
int y = 3;
int r = 5;
int b = 6;
int tri_r = 9;
int tri_b = 10;
int speaker = 11;
int state = ON;
int current_state = ON;
// the setup routine runs once when you press reset:
void setup() {
pinMode(button, INPUT);
}
// the loop routine runs over and over again forever:
void loop() {
button_mode();
if (current_state == ON) {
for (int j = 0; j < 4; j++) {
for (int i = 0; i <= 255; i++) {
digitalWrite(speaker, HIGH);
delayMicroseconds(300 - i);
digitalWrite(speaker, LOW);
delayMicroseconds(300 - i);
analogWrite(speaker, 255);
analogWrite(y, i);
analogWrite(r, 255-i);
analogWrite(b, i);
analogWrite(tri_r, i);
analogWrite(tri_b, 255-i);
button_mode();
delay(1);
}
for (int i = 0; i <= 255; i++) {
digitalWrite(speaker, HIGH);
delayMicroseconds(i + 45);
digitalWrite(speaker, LOW);
delayMicroseconds(i + 45);
analogWrite(speaker, 255);
analogWrite(y, 255-i);
analogWrite(r, i);
analogWrite(b, 255-i);
analogWrite(tri_r, 255-i);
analogWrite(tri_b, i);
button_mode();
delay(1);
}
}
for (int j = 0; j < 4; j++) {
button_mode();
for (int i = 0; i <= 200; i++) {
digitalWrite(speaker, HIGH);
delayMicroseconds(100);
digitalWrite(speaker, LOW);
delayMicroseconds(100);
analogWrite(speaker, 255);
button_mode();
delay(1);
}
analogWrite(y, 0);
analogWrite(r, 255);
analogWrite(b, 0);
analogWrite(tri_r, 255);
analogWrite(tri_b, 0);
for (int i = 0; i <= 1802; i++) {
digitalWrite(speaker, HIGH);
delayMicroseconds(300);
digitalWrite(speaker, LOW);
delayMicroseconds(300);
analogWrite(speaker, 255);
button_mode();
delay(1);
}
analogWrite(y, 255);
analogWrite(r, 0);
analogWrite(b, 255);
analogWrite(tri_r, 0);
analogWrite(tri_b, 255);
}
}
else {
analogWrite(tri_b, 0);
analogWrite(tri_r, 0);
analogWrite(y, 0);
analogWrite(r, 0);
analogWrite(b, 0);
}
}
void button_mode() {
if (digitalRead(button) == HIGH) {
state = TRANSITION;
} else {
if (state == TRANSITION) {
if (current_state == OFF) {
current_state = ON;
} else if (current_state == ON) {
current_state = OFF;
}
state = OFF;
}
}
}
Now all you need to do is add wheels and a motor and some more sensors and and a body and you’ll have an Arduino-based police car!
Colleen Caroll, Angela Dai, Connie Wan, Edward Zhang
The Color Wheel is a game that challenges players to create a specified color using LEDs and colored filters. It is a fun and easy way for children to learn about the primary colors and the secondary colors that they create! The system is great because it is simple to use and understand. A color appears on the computer screen (e.g. “purple”), one colored led lights up on the board (e.g. red lights up), and then the user only has to turn the color wheel so that the color on the wheel mixes with the light to create the desired color (e.g. player turns the wheel to blue, thus making purple). It was, however, difficult to get a medium that would diffuse the LED properly so that color of the light and the filter would mix properly to the desired color. The LED is so focused that it was a challenge to get it to blend well with a material. We tried saran wrap, copy paper, toilet paper, and finally–thin sketch paper with watercolor to increase the translucence slightly. We put a lot of effort into finding the most effective and aesthetically pleasing diffuser, as it an integral part of the function of our game. Our game works well (we have played several successful games) but would be even better with a more diffuse light (or another filter) that blended better.
Diagrams:
This schematic shows the rotating diffusing filter (mounted on a potentiometer) atop the LEDs, with the “Submit” push button on the side.
Images of Final System:
The electronics. Turn the paper filter (which is connected to a potentiometer) so that the blended color with the displayed LED light becomes a prompted color. Push the button to submit your guess.
For a prompted color of purple and a blue LED light, we turn the paper filter to red so that a purple color is seen.
We used processing to display a prompt color to achieve (in this case green) using the displayed LED color and the filter paper.
Parts List:
Electronics:
Red, Yellow, and Blue LED (or a tricolor LED + yellow LED)
3x 330Ω Resistors
1x 10kΩ Resistor
Linear Potentiometer
12mm button
Breadboard
Arduino Uno
Other:
Straw
Paper
Red, yellow, and blue markers
Duct Tape
Instructions:
Connect each of the LEDs to ground through a 330Ω resistor. Connect the positive side of the red LED to digital port 9, the yellow LED to digital port 10, and the blue LED to digital port 11.
Connect the middle pin of the potentiometer to A0 (analog input 0) on the Arduino, and the outer pins to ground and 5V power,
Connect one pin of the button to 5V power, another to digital pin 2, and another to ground through a 10kΩ resistor.
Tape the end of the straw to the potentiometer, so that the straw sticks straight out of the knob. The tape should be strong enough such that turning the tape turns the knob of the potentiometer and the straw.
Cut the other end of the straw lengthwise such that it splits into four strips. Flatten out the strips so they are perpendicular to the rest of the straw.
Using the markers, color a square of paper (approx. 10cm x 10cm) so that approximately a third is red, a third yellow, and a third blue. The paper and markers should result in something that, when the LEDs shine through it, the colors blend into the primary combinations (green, purple, orange).
Attach this paper to the straw strips using tape. The potentiometer-straw diffuser should be positioned such that the LEDs are underneath the paper to one side, and turning the potentiometer places each of the different colored paper regions over the LEDs.
Source Code:
Arduino Code
/**
* arduino
**/
/*
Radiate, L0
*/
int val = 0; // variable to store the value coming from the sensor
int leds[] = {9, 10, 11}; // LED pins
int NUM_LEDS = 3; // number of LEDs
const int buttonPin = 2;
int buttonState = 0;
enum COLOR {
RED,
YELLOW,
BLUE,
ORANGE,
GREEN,
PURPLE,
NUM_PROMPTS
};
const int NUM_QUESTIONS = 9;
int question_leds[] = {RED, RED, RED, YELLOW, YELLOW, YELLOW, BLUE, BLUE, BLUE};
int question_prompts[] = {RED, ORANGE, PURPLE, YELLOW, ORANGE, GREEN, BLUE, PURPLE, GREEN};
int solutions[] = {RED, YELLOW, BLUE, YELLOW, RED, BLUE, BLUE, RED, YELLOW};
int index = 0; // index of question
int filterindex = 0;
void setup_question()
{
// turn on/off corresponding leds
for (int i = 0; i < NUM_LEDS; i++) {
if (i == question_leds[index]) {
digitalWrite(leds[i], HIGH);
}
else
digitalWrite(leds[i], LOW);
}
Serial.println(question_prompts[index]);
}
void setup()
{
// initialize the serial communication:
Serial.begin(9600);
// initialize pushbutton as input
pinMode(buttonPin, INPUT);
// initialize led outputs:
for (int i = 0; i < NUM_LEDS; i++)
pinMode(leds[i], OUTPUT);
// pick question
index = random(NUM_QUESTIONS);
setup_question();
}
void loop() {
// read state of pushbutton
buttonState = digitalRead(buttonPin);
// if pressed check solution
if (buttonState == HIGH) {
val = analogRead(A0); // read value from pot
delay(10);
filterindex = (int) (val / 1023.0 * 3 + 0.5);
if (filterindex == 3) filterindex = 0; // two red so that pot can be circular
/* Serial.print(val);
Serial.print(" ");
Serial.print(filterindex);
Serial.print(" ");
Serial.println(solutions[index]); */
if (filterindex == solutions[index]) {
// correct! new question
index = random(NUM_QUESTIONS);
setup_question();
}
}
}
Processing Code:
/**
processing -- displays colour prompts
**/
import processing.serial.*;
Serial port;
PFont f; // font to display messages
int xp = 100; // position of text
int yp = 70;
void setup() {
size(256, 150);
println("Available serial ports:");
println(Serial.list());
port = new Serial(this, Serial.list()[4], 9600);
// If you know the name of the port used by the Arduino board, you
// can specify it directly like this.
//port = new Serial(this, "COM1", 9600);
background(255, 255, 255);
f = createFont("Arial", 16, true); // Arial, 16 point, anti-aliasing on
fill(0);
//text("BEGIN", xp, yp);
}
void draw() {
}
void serialEvent(Serial myPort) {
// get ascii string
String instring = myPort.readStringUntil('\n');
if (instring != null) {
// trim off whitespace
instring = trim(instring);
int prompt = int(instring);
drawbackground(prompt);
}
}
void drawbackground(int prompt) {
switch (prompt) {
case 0:
background(255, 0, 0);
text("RED", xp, yp);
break;
case 1:
background(255, 255, 0);
text("YELLOW", xp, yp);
break;
case 2:
background(0, 0, 255);
text("BLUE", xp, yp);
break;
case 3:
background(255, 127, 80);
text("ORANGE", xp, yp);
break;
case 4:
background(0, 255, 0);
text("GREEN", xp, yp);
break;
case 5:
background(255, 0, 255);
text("PURPLE", xp, yp);
break;
default:
background(0, 0, 0); // error
fill(255);
text("ERROR " + prompt, xp, yp);
fill(0);
break;
}
}
Other Ideas:
1. Chalk Dust Diffuser – Fill up a room with smoke (or chalk dust if a smoke machine is not readily available) and have multicolored LEDs changing color in sync to music. Awesome ambient lighting for a dance floor. This was a “diffuser-focused” idea.
2. Simon Says – Using a set of buttons and colored LEDs, this game presents the user with sequences of colored lights of increasing length. They have to press the buttons corresponding to the appropriate lights in the correct order to advance. Unfortunately, while interactive, this didn’t really use the idea of a diffuser effectively.
3. Color matching game – This was an interactive game that had a diffuser as an integral part of the system. Create colors by moving the appropriately colored filter above the lit LED.
Green Choi (ghchoi@)
Peter Yu (keunwooy@)
Vivian Qu (equ@)
Jae Lee (jyltwo@)
Rainbow Tower:
We used five single-color LED lights positioned in a circle around a tri-color LED light. All the lights can be controlled by a dial (potentiometer) and a button. The LEDs were covered with colored straws to make a visually comforting diffuser. The button switched between modes: DIAL and STROBE modes. When the mode is DIAL, the user can one-by-one turn on each of the single-color LED lights while the tri-color LED light changes to the corresponding single-color LED light that was just turned on. When the mode is STROBE, the single-color LED lights flash every 0.5 seconds. The main tri-color LED stays on and changes to a random color every 0.5 seconds.
We were inspired by the many different types of night lights or children’s toys which change colors. We wanted to also build an interactive, colorful set of lights that could be changed to fit the user’s color preferences. Plus, it makes us really happy to play with the multiple lights!
The device responds very well to the user inputs. But in the future, we would like to make the setup more stable by attaching the base of straws to foam core or cardboard. We wanted to use a 7-segment display to show the current mode, but we didn’t have enough digital I/O ports available. So if we could use more arduinos, more functionalities (like displaying the current mode) would be possible. There is also a lot of potential for design expansion if there were more LEDs and arduinos available, so the lights and straws could be added to create a bigger Rainbow Tower!
Photos + Videos:
Rainbow Tower
Display Wiring
Final Setup
Setup — no straws
Wiring
More Wiring
Straws
Circuit design
DIAL mode
STROBE mode
Possible straw configurations
Lollipop Design
Bop-It Design
Parts Used:
Arduino UNO R3 (1)
SoftPot (1)
Button (1)
Basic LED (5)
Tri-Color LED (1)
Colored Straws (6)
330 Ohm Resistors (9)
Breadboard (3)
Wires
Instructions for Recreating:
Position the 5 one-color LED lights in a circle configuration on the breadboard. Place the tri-color LED in the center. Make sure there is enough space to cover each LED with a straw. Wire the one-color LEDs — connect the positive end through a resistor to the arduino’s digital I/O ports (we used ports 9, 10, 11, 12, 13) and the other end to ground, using a second breadboard to hold all the resistors if necessary. Wire the tri-color LED by connecting three legs to digital I/O ports (we used ports 3, 5, 6) and the longer leg to ground.
Cover all 6 LEDs with appropriate colored straws. Cut the straws to varying size, if desired.
Use another breadboard to set up the button and the potentiometer. For the button, connect one leg to a digital I/O port (we used port 8). Connect the same leg on the opposite side through a resistor to ground. Finally, connect the opposite leg to 5V.
For the potentiometer, connect the rightmost leg to ground. Connect the leftmost leg to 5V. The middle leg is connected to analog input (we used port A2).
Upload the code, and test it out!
Code:
/*
The Rainbow Tower -- awesome diffuser with straws
*/
// Set the I/O pin numbers.
const int blueLed = 13;
const int yellowLed = 12;
const int redLed = 11;
const int greenLed = 10;
const int purpleLed = 9;
const int multiRLed = 6;
const int multiGLed = 5;
const int multiBLed = 3;
const int potPin = 2;
const int buttonPin = 8;
// Colors for tri-color LED
// Red
const byte r1 = 255;
const byte g1 = 0;
const byte b1 = 0;
// Orange
const byte r2 = 255;
const byte g2 = 128;
const byte b2 = 0;
// Yellow
const byte r3 = 255;
const byte g3 = 255;
const byte b3 = 0;
// Green
const byte r4 = 128;
const byte g4 = 255;
const byte b4 = 0;
// Blue
const byte r5 = 0;
const byte g5 = 0;
const byte b5 = 255;
// Purple
const byte r6 = 128;
const byte g6 = 0;
const byte b6 = 255;
boolean changed = false;
int buttonMode = 0;
int buttonVal = 0; // Button
int potVal = 0; // Potentiometer
int bulbVal = 0;
long interval = 500; // Blink time (0.5 s)
long previousMillis = 0;
int flickerState = LOW;
void setup() {
// Set the digital pins as output:
pinMode(blueLed, OUTPUT);
pinMode(yellowLed, OUTPUT);
pinMode(redLed, OUTPUT);
pinMode(greenLed, OUTPUT);
pinMode(purpleLed, OUTPUT);
pinMode(multiRLed, OUTPUT);
pinMode(multiGLed, OUTPUT);
pinMode(multiBLed, OUTPUT);
}
void loop()
{
// Tri-color LED is always lit.
unsigned long currentMillis = millis();
// Read the mode.
buttonVal = digitalRead(buttonPin);
if (buttonVal == HIGH) {
changed = true;
}
if (changed && buttonVal == LOW) {
buttonMode++;
buttonMode %= 2;
changed = false;
}
// DIAL mode
if (buttonMode == 0) {
for (int i = 9; i <= 13; ++i) {
digitalWrite(i, LOW);
}
potVal = analogRead(potPin);
bulbVal = map(potVal, 0, 1023, 9, 17);
for (int i = 13; i >= bulbVal; --i) {
digitalWrite(i, HIGH);
}
if (bulbVal == 9) {
analogWrite(multiRLed, r6);
analogWrite(multiGLed, g6);
analogWrite(multiBLed, b6);
}
if (bulbVal == 10) {
analogWrite(multiRLed, r5);
analogWrite(multiGLed, g5);
analogWrite(multiBLed, b5);
}
if (bulbVal == 11) {
analogWrite(multiRLed, r4);
analogWrite(multiGLed, g4);
analogWrite(multiBLed, b4);
}
if (bulbVal == 12) {
analogWrite(multiRLed, r3);
analogWrite(multiGLed, g3);
analogWrite(multiBLed, b3);
}
if (bulbVal == 13) {
analogWrite(multiRLed, r2);
analogWrite(multiGLed, g2);
analogWrite(multiBLed, b2);
}
if (bulbVal == 14) {
analogWrite(multiRLed, r1);
analogWrite(multiGLed, g1);
analogWrite(multiBLed, b1);
}
if (bulbVal == 15) {
analogWrite(multiRLed, 0);
analogWrite(multiGLed, 0);
analogWrite(multiBLed, 0);
}
}
// STROBE mode
else {
if (currentMillis - previousMillis > interval) {
previousMillis = currentMillis;
if (flickerState == LOW)
flickerState = HIGH;
else
flickerState = LOW;
for (int i = 9; i <= 13; ++i) {
digitalWrite(i, flickerState);
}
analogWrite(multiRLed, 30);
analogWrite(multiGLed, 30);
analogWrite(multiBLed, 30);
}
}
}
Osman Khwaja
Alejandro Van Zandt-Escobar
Gabriel Chen
Avneesh Sarwate
Prakhar Agarwal
Description
We built a glass world that reacts to light using a photosensor and behaves according to the state it is in. There are three states governed by a button: the idle state, the build state, and the drop state. Before the button is enabled, the world is in a calibration state, used to expose the photoresistor to the range of possible light inputs and thus, resistances. The idle state consists of a tricolor LED, fitted with a straw. The tricolor LED oscillates between all ranges of colors according to three sin functions. The other LEDs do nothing. The build state is to be initiated by the press of the button when the song “Harlem Shake” is played (in light of the recent trend). The tricolor LED begins to change colors erratically, and the remaining LEDs alternate slowly between reds and blues, arranged diagonally from each other. The behavior matches the tempo of the song. The drop state is to be initiated at the beat drop of the song. The tricolor LED continues its erratic behavior, but the remaining LEDs now act based on the light sensor. This can be used to induce extremely erratic behavior all LEDs, in accordance with Harlem Shake tradition. Thus, we felt that our design successfully produced the desired behavior. The different states of the design are a good representation of different stages in the song, and the use of a button allows for ease of state transition. Additionally, the straw and ice cube trays were excellent diffusers, and really emphasized the output of the LEDs. One limitation of our design was the sensitivity of the photoresistor. It was placed under a thick layer of glass, which may have diffused light entering the circuit. Although this made the design more aesthetic, the functionality was slightly impaired. Overall, we were happy with the Harlem Shake video we were able to produce using our design, and we hope that it goes viral!
Photos of Sketches
Follow the finger: Slide sensor controls the brightness of the lights. Lights closest to finger are brightest. Move finger to control the light.
Perfect Pushup: Use a diffuser and flex sensor to determine whether pushup form is correct or not.
A schematic of our final design.
A design diagram of our project.
Video
Parts
Arduino Uno
Button
Photoelectric Sensor
Ice Cube Tray
Glass Box/Flower Vase
1 Straw
Wires
2 10k Ohm Resistor
7 330 Ohm Resistors
2 Blue LEDs
2 Red LEDs
1 Tricolor LED
2 Alligator Clips
Tape
Instructions
Connect the TriColor LED to the three analog pins 11, 10, 9 through 330 Ohm resistors.
Connect 4 LEDs in a general box shape just below the TriColor to the pins 7,6,5,4 with a 330 Ohm Resistor for each.
Attach a photoelectric sensor to the top of the glass box using the alligator clips. Ensure that the sensor is facing outwards.
Connect the button to the breadboard with the 10k Resistor, pulling 5 Volts from Arduino. Connect the output to pin 3.
Connect the photosensor with a 10k Resistor to pin A0 on the Arduino.
Cover the 4 LEDs with the ice cube tray, the tricolor with a straw, and all of them with the glass case.
When powering up the system, make sure to calibrate the photosensor by covering and uncovering the sensor. The Blue LED will light up during this time.
Here is what the final setup should look like.
Source Code
// ----------------------
// Harlem Shake v. 436
// ----------------------
// COS 436, Lab 0
// February 18, 2013
// ----------------------
// Prakhar Agarwal
// Gabriel Chen
// Osman Khwaja
// Avneesh Sarwate
// Alejandro Van Zandt-Escobar
// ----------------------
// The "beacon" (multicolor LED) is connected to three analog outputs
const int beaconRed = 11;
const int beaconGreen = 10;
const int beaconBlue = 9;
// The four other LEDs are connected to four digital outputs
const int ledYellow = 8;
const int ledRed = 7;
const int ledBlue = 6;
const int ledGreen = 5;
// Sensor 1: Photocell
const int sensorPin = A0;
int sensorValue = 0;
int sensorMin = 1023; // minimum sensor value
int sensorMax = 0; // maximum sensor value
int threshold = 127;
// Button
const int buttonPin = 3;
int buttonState = 0; // HIGH or LOW
int buttonCounter = 0; // Number of clicks determines the program's current state.
int lastButtonState = 0; // HIGH or LOW
// Setup Routine
void setup() {
// For debugging:
Serial.begin(9600);
// Set up I/O.
pinMode(beaconRed, OUTPUT);
pinMode(beaconGreen, OUTPUT);
pinMode(beaconBlue, OUTPUT);
pinMode(ledGreen, OUTPUT);
pinMode(ledBlue, OUTPUT);
pinMode(ledRed, OUTPUT);
pinMode(ledYellow, OUTPUT);
pinMode(buttonPin, INPUT);
// Calibrate photocell during the first five seconds.
while (millis() < 5000) { // Light up LED at the beginning of calibration phase. digitalWrite(ledBlue, HIGH); // Read in value from photocell sensorValue = analogRead(sensorPin); // Record the maximum sensor value if (sensorValue > sensorMax) {
sensorMax = sensorValue;
}
// Record the minimum sensor value
if (sensorValue < sensorMin) {
sensorMin = sensorValue;
}
// Turn off LED at end of calibration phase
digitalWrite(ledBlue, LOW);
}
}
// Variables for timing and rhythm
double time = 0;
double t = 0; // Used for sin wave patterns
int beat = 430; // Duration of a beat (in ms)
int downBeatBeacon;
int downBeatCubes;
void loop() {
// *** Process Photocell Input ***
// Read photocell sensor
sensorValue = analogRead(sensorPin);
// Apply calibration
sensorValue = map(sensorValue, sensorMin, sensorMax, 0, 255);
// Map sensor value to desired range
sensorValue = constrain(sensorValue, 0, 255);
// *** Process Button Input ***
// Read state of pushbotton
buttonState = digitalRead(buttonPin);
// Compare the buttonState to its previous state
if (buttonState != lastButtonState) {
// State changes when button is pressed down (from off to on)
// If state has changed then increment counter
if (buttonState == HIGH) {
// If the current state is HIGH then button went from off to on
if (buttonCounter == 2)
buttonCounter = 0;
else
buttonCounter++;
// For debugging:
// Serial.println("on");
// Serial.print("number of button pushes: ");
// Serial.println(buttonCounter);
}
else {
// If the current state is LOW then the button went from on to off
Serial.println("off");
}
}
// save the current state as the last state, for next time through the loop
lastButtonState = buttonState;
// *** Main Program Loop ***
// *** Idle State ***
if (buttonCounter == 0) {
// Tri-color LED has an intersecting sinusoidal pattern
analogWrite(beaconRed, (int) (127 + 127 * sin(t)));
analogWrite(beaconBlue, (int) (127 + 127 * sin(t + 3.14/3)));
analogWrite(beaconGreen, (int) (127 + 127 * sin(t + 6.28/3)));
// Turn all other LEDs off
digitalWrite(ledBlue, LOW);
digitalWrite(ledGreen, LOW);
digitalWrite(ledRed, LOW);
digitalWrite(ledYellow, LOW);
// Progression of sinusoidal pattern
t += 0.1;
delay(20);
}
// *** Build State ***
else if (buttonCounter == 1) {
// Beacon's activity is determined by eighth notes
downBeatBeacon = ((int) (time / (beat / 2)));
// Cube's activity is determined by half notes
downBeatCubes = ((int) (time / (beat * 2))) % 2;
// The beacon plays an accelerated sinusoiodal pattern
// Erratically matched to the rhythm of eighth notes
analogWrite(beaconRed, (int) (127 + 127 * sin(downBeatBeacon + .9)));
analogWrite(beaconBlue, (int) (127 + 127 * sin(9 * downBeatBeacon + .2)));
analogWrite(beaconGreen, (int) (127 + 127 * sin(7 *downBeatBeacon)));
// The four LEDs in the icecube alternate diagonally, on every half beat.
// On beat 1:
if (downBeatCubes == 0) {
digitalWrite(ledBlue, HIGH);
digitalWrite(ledGreen, LOW);
digitalWrite(ledRed, LOW);
digitalWrite(ledYellow, HIGH);
}
// On beat 2:
else if (downBeatCubes == 1) {
digitalWrite(ledBlue, LOW);
digitalWrite(ledGreen, HIGH);
digitalWrite(ledRed, HIGH);
digitalWrite(ledYellow, LOW);
}
// Update every eighth note
delay(beat / 2);
time += beat / 2;
}
// *** Drop State ***
else {
// Beacon's activity is determined by eighth notes
downBeatBeacon = ((int) (time / (beat / 2)));
// The beacon plays an accelerated sinusoiodal pattern
// Erratically matched to the rhythm of eighth notes
analogWrite(beaconRed, (int) (127 + 127 * sin(downBeatBeacon + .9))); // turn the LED on (HIGH is the voltage level)
analogWrite(beaconBlue, (int) (127 + 127 * sin(9 * downBeatBeacon + .2))); // turn the LED on (HIGH is the voltage level)
analogWrite(beaconGreen, (int) (127 + 127 * sin(7 *downBeatBeacon)));
// The cube LEDs play the same pattern, but switch according
// to input from the photocell.
if (sensorValue < threshold) {
digitalWrite(ledBlue, HIGH);
digitalWrite(ledGreen, LOW);
digitalWrite(ledRed, LOW);
digitalWrite(ledYellow, HIGH);
}
else {
digitalWrite(ledBlue, LOW);
digitalWrite(ledGreen, HIGH);
digitalWrite(ledRed, HIGH);
digitalWrite(ledYellow, LOW);
}
// Update every eighth note
delay(beat / 2);
time += beat / 2;
}
}