Spookoo Clock

Video:  https://youtu.be/ukvsB9rwcKE

 

Our group’s ideas ranged far and wide for this one, but after considerable debate we realized we wanted to create a project with at least the following characteristics:

  1. Halloween themed, with a
  2. Nontraditional door, and which
  3. Respects the cuckoo-clock MO

With these parameters in mind our project became clear to all of us all at once: an egg that hatches a skeleton cuckoo bird through an egg shell door.

We started with a cardboard model, which we then measured and recreated in Fusion 360. For our hinge and door mechanism we decided to employ a “living hinge” design that we laser cut from plywood. We actuated the door with a gear and crank glued to the inside of the box, and added a second gear to drive a rack at the base of our bird design. As the gears turn the bird is propelled upwards and the lid opens.

We had some ideas about how to give the bird some personality, too, by having it “peep” when it reached the top of its stroke. We were able to do this on a timer, and had plans to incorporate a microphone so that a loud noise would startle the bird out of its shell. While we did include the mic in our schematic, a little more work is needed on the code to get that particular functionality set up.

Materials:

Plywood, 1/8″

Small servo motor

Wires

Arduino Uno

Wood glue

Machine screws

SparkFun Mic

Breadboard

Piezo Speaker

 

Code:

/* Sweep
by BARRAGAN <http://barraganstudio.com>
This example code is in the public domain.

modified 8 Nov 2013
by Scott Fitzgerald
http://www.arduino.cc/en/Tutorial/Sweep
*/

#include <Servo.h>

Servo myservo; // create servo object to control a servo
// twelve servo objects can be created on most boards

int pos = 0; // variable to store the servo position
const int sampleWindow = 250; //250 MS sample width
unsigned int loudNoise;
int speakerPin = 7;
int val = 0;
int orig = 0;
int potPin = 0;
void setup()
{
pinMode(speakerPin, OUTPUT);
Serial.begin(9600);
Serial.println(“ready”);
myservo.attach(9); // attaches the servo on pin 9 to the servo object
}

void loop() {
unsigned long start= millis(); // start of sample window
unsigned int peakToPeak = 0; // peak-to-peak level
unsigned int signalMax = 0;
unsigned int signalMin = 1024;
Serial.print(“loudNoise”);
Serial.print(loudNoise);
Serial.println();

while (millis() – start < sampleWindow) // collecting data for 250 MS (can be changed)
{
loudNoise = analogRead(0);
if (loudNoise < 1024) //
{
if (loudNoise > signalMax) // if there’s a loud noise, save the loud value
{
signalMax = loudNoise;
}
else if (loudNoise < signalMin) // if there’s not a loud noise, don’t save the loud value
{
signalMin = loudNoise;
}
}
}

peakToPeak = signalMax – signalMin; // max – min = peak-peak amplitude
double volts = (peakToPeak * 3.3) / 1024; // convert to volts
Serial.println(volts); // to know if the mic is working

// digitalWrite(speakerPin, LOW);
//myservo.write(180);

//val = analogRead(potPin); // read value from the sensor
//val = val*30; // process the value a little
//val = val/2; // process the value a little

if (volts >=1.0){
for( int i=0; i<50; i++ ) { // play it for 50 cycles
for(pos = 180; pos>=0; pos-=9) // goes from 180 degrees to 0 degrees
{
myservo.write(pos); // tell servo to go to position in variable ‘pos’
delay(15); // waits 15ms for the servo to reach the position

};
delay(6000);
for(pos = 0; pos <= 180; pos += 3) // goes from 0 degrees to 180 degrees
{ // in steps of 1 degree
myservo.write(pos); // tell servo to go to position in variable ‘pos’
delay(80); // waits 15ms for the servo to reach the position
};
delay(500);
for(int j=0; j<50; j++){

digitalWrite(speakerPin, HIGH);
delayMicroseconds(800);
digitalWrite(speakerPin, LOW);
delayMicroseconds(800);
};

};
}
//if (volts >=1.0) {

// delay(2000); // for a certain amount of time (though this could be modified for more expressive behavior)
// Serial.println(“YELLING AT US”);
// }
// else {
// digitalWrite(12, LOW);
// digitalWrite(2, LOW); //not yetlling at us
// };
else {
myservo.write(0);
delay(1000);
}
};

 

Popping Balloons: Affordances and Obviation

If the history of media coincides with the history of the externalization of knowledge from the body–writing freeing the body from memory; robots from labor; AI from calculation; I found myself wondering what virtual reality frees the body from. And not in the neo-luddite-esque curmudgeonly way of “wondering what we’ll lose as a culture” with the digitization of experience, but just wondering what kinds of discourses are created and what kinds are obviated with the adoption of this new technology. To take the most obvious example, in my (admittedly short) virtual experience on the Vive, I found my visual senses extended insofar as I could see things no one else could, but at the same time I found them deeply impaired–and to my own peril! The techniques of navigation I have depended on for all my life no longer quite applied, and any efforts I made at walking (though Valve has done their best to integrate movement into the system) constantly compelled the question: “are you going to run into something?” limiting my movement around the room. Maybe we could call this a kind of “externalization of mobility,” which would pose a lot of interesting questions, not the least of which is: what does civilization look like without mobility?

I think one of the other fears people have about virtual reality is that it will make humans less prone to meaningful connection. I didn’t find, to this point, that the experience was “anti-social,” despite the lack of living creatures in the apps I tried, because I spent most of the time talking to the other people in the room. But maybe this would change if I were wearing Vive-brand headphones, or whatever comes with the device.

Two experiences in the Vive to which I had the strongest reactions: inflating balloons, and looking at the dog. The balloon inflating surprised me for how real the experience felt. When I blew them up, they floated in the air in front of me; when I knocked them forward with my hand, they made the exact sound balloons make when you knock them with your hand, and (this could be my memory deceiving me) I felt as though I had even probably experienced the impact–maybe through haptics, or maybe just through the power of suggestion–I can’t remember, but that fact testifies to the quality of the experience.

The second experience I had that I found moving was realizing that I was smiling IRL at the  virtual robotic dog running around me, just as I would smile at a “real” dog running around me. I don’t know if all humans are as gullible as I am, but it’s now my suspicion that my brain would have no qualms about forming a bond with a virtual pet, provided the AI were good enough to avoid breaking the illusion.

3D-Printed Crawler

Video: https://www.youtube.com/watch?v=Pf1nZoAFWvA&feature=youtu.be

 

For this assignment I happened to have a 3D-printed arm in a box in my room (what?), so I set about programming it to crawl forward in a straight line. The arm is made from 3D-printed finger joints, metal wire, a plastic housing, and some zip-ties and a laser-cut servo protector. It wasn’t originally designed to crawl forward along carpeted surfaces, but with a little bit of retrofitting it does the job nicely.

 

Materials:

  1. Servo Motor
  2. 3D-printed lobster tail
  3. Arduino Uno
  4. Lead wires
  5. 4 AA batteries
  6. Battery holder
  7. Steel cable
  8. Hot glue
  9. Zip ties

Code:

 

/* Sweep

by BARRAGAN <http://barraganstudio.com>
This example code is in the public domain.

modified 10/19/2016
by Adam Hutz
http://www.arduino.cc/en/Tutorial/Sweep
*/

#include <Servo.h>

Servo myservo; // create servo object to control a servo
// twelve servo objects can be created on most boards

int pos = 0; // variable to store the servo position

void setup()
{
myservo.attach(9); // attaches the servo on pin 9 to the servo object
}

void loop()
{
for(pos = 0; pos <= 110; pos += 1) // goes from 0 degrees to 180 degrees
{ // in steps of 1 degree
myservo.write(pos); // tell servo to go to position in variable ‘pos’
delay(8); // waits 15ms for the servo to reach the position
}
for(pos = 110; pos>=0; pos-=1) // goes from 180 degrees to 0 degrees
{
myservo.write(pos); // tell servo to go to position in variable ‘pos’
delay(8); // waits 15ms for the servo to reach the position
}
}

 

 

Resistor! A difficult interaction

Like last week, my goal for this assignment was to create an affective robot–in this case, one that would challenge you when you try to work on it, put it away, or turn it off. Originally I hoped to enclose the whole assembly in a wire-frame ball, so that once turned on it would roll around and be tedious or difficult to turn off. Instead, I created a little bot that just protects itself with a spinning wire. It is afraid of the dark, and so if one tries to cover it with a lid, it will spin wildly, but calm down once again in the light of day.

Materials:

1 photoresistor

1 resistor (330 Ohms)

1 resistor (1k Ohms)

wires

two AA battery holders, one x4 and one x2

1 Arduino uno

1 DC motor

1 diode

1 transistor

soldering iron and solder

1 machine screw

welder…

 

Code:

/*
* one pot fades one motor
* modified version of AnalogInput
* by DojoDave <http://www.0j0.org>
* http://www.arduino.cc/en/Tutorial/AnalogInput
* Modified again by dave
*/

const int numReadings = 5;

int readings[numReadings]; // the readings from the analog input
int readIndex = 0; // the index of the current reading
int total = 0; // the running total
int average = 0; // the average
int inputPin = A0;
int motorPin = 9; // select the pin for the Motor
int val = 0; // variable to store the value coming from the sensor
void setup() {
Serial.begin(9600);
for (int thisReading = 0; thisReading < numReadings; thisReading++) {
readings[thisReading] = 0;
};
}

void loop() {
// subtract the last reading:
total = total – readings[readIndex];
// read from the sensor:
readings[readIndex] = analogRead(inputPin);
// add the reading to the total:
total = total + readings[readIndex];
// advance to the next position in the array:
readIndex = readIndex + 1;

// if we’re at the end of the array…
if (readIndex >= numReadings) {
// …wrap around to the beginning:
readIndex = 0;
}

// calculate the average:
average = total / numReadings;
// send it to the computer as ASCII digits
Serial.println(250-average*2.8);
analogWrite(motorPin, abs(255-average*2.8)); // analogWrite can be between 0-255
delay(5); // delay in between reads for stability
}

Video:

https://youtu.be/p5WXQyZC0DY

Party Box

Is it true that Arduinos were designed to fit inside Altoids cans? I may have just remembered that, or I may have just made it up, but how perfectly they fit! To celebrate how well they fit I’ve designed a party box: when the Altoids can is opened, the party ensues; when it is closed, the party ceases.

 

Materials:

Altoids can

Arduino Uno

3 LED lights

1 320 Ohm resistor

1 10k Ohm resistor

Wires

Tape

Piezo buzzer

 

Code:

/* Theremin
* ——–
*
*
* Created 24 October 2006
* copyleft 2006 Tod E. Kurt &lt;tod@todbot.com
* http://todbot.com/
*/

int potPin = 0; // select the input pin for the potentiometer
int speakerPin = 7;

int val = 0;

int redPin = 9; // Red LED, connected to digital pin 9
int grnPin = 10; // Green LED, connected to digital pin 10
int bluPin = 11; // Blue LED, connected to digital pin 11

int redVal = 0; // Variables to store the values to send to the pins
int grnVal = 0;
int bluVal = 0;

int ramdred = 0;
int ramdblu = 0;
int ramdgrn = 0;

void setup() {
pinMode(speakerPin, OUTPUT);
pinMode(redPin, OUTPUT); // sets the pins as output
pinMode(grnPin, OUTPUT);
pinMode(bluPin, OUTPUT);
Serial.begin(9600);
Serial.println(“ready”);
}

void loop() {
digitalWrite(speakerPin, LOW);

val = analogRead(potPin); // read value from the sensor
val = val*2; // process the value a little
//val = val/2; // process the value a little
ramdred = random(0, 250);
ramdblu = random(0, 250);
ramdgrn = random(0, 250);

if (val > 0){
for( int i=0; i<50; i++ ) { // play it for 50 cycles
analogWrite(redPin, ramdred);
analogWrite(grnPin, ramdblu);
analogWrite(bluPin, ramdgrn);
digitalWrite(speakerPin, HIGH);
delayMicroseconds(val);
digitalWrite(speakerPin, LOW);
delayMicroseconds(val);
};
}
else {
analogWrite(redPin, 0);
analogWrite(grnPin, 0);
analogWrite(bluPin, 0);
delay(10);
};
Serial.print(val);
Serial.println();
};

Video:

https://youtu.be/ZeF2XRpKqaw

 

Mood Jar with FSR

For “Mood Jar with FSR” I took the frosted cup I was working on last lab and added two FSRs. I positioned one of the FSRs to be a “picking up mug” pressure sensor, and prepared it to sit, for example, beneath a cardboard hot sleeve. The other FSR I added to the surface of the mug, for reasons. I then programmed the former to react to specific sensitivities, and the latter to be a mere “on/off” switch. The video will show what I mean.

I had a considerable amount of trouble getting processing to run using the serial outputs from the arduino environment, and will need to consult with someone who has experience with the program to debug what I’m sure is a profoundly simple problem…

The final image is of the results of my processing experiments.

Materials:

1 Jar

1 Arduino Micro

Wires

Solder/Soldering Iron

2 Potentiometers

3 Resistors (220 Ohms)

3 LEDs

Hot glue gun/hot glue

Frosted Glass spray paint

2 FSRs

2 Resistors (10k Ohms)

 

Video:

https://youtu.be/uz6HTCObOHg

 

Arduino code:

int fsrOne = A0;
int fsrTwo = A1;
int potPinColor = A4; // Potentiometer output connected to analog pin 3
int potPinBlink = A5; // Second potentiometer controlling blink speed
int potValColor = 0; // Variable to store the input from the potentiometer
int potValBlink = 0; // Variable to store the input from the second potentiometer (controlling blink)
int photoCellValOne = 0;
int photoCellValTwo = 0;

// OUTPUT: Use digital pins 9-11, the Pulse-width Modulation (PWM) pins
// LED’s cathodes should be connected to digital GND
int redPin = 9; // Red LED, connected to digital pin 9
int grnPin = 10; // Green LED, connected to digital pin 10
int bluPin = 11; // Blue LED, connected to digital pin 11

// Program variables
int redVal = 0; // Variables to store the values to send to the pins
int grnVal = 0;
int bluVal = 0;

void setup()
{
pinMode(redPin, OUTPUT); // sets the pins as output
pinMode(grnPin, OUTPUT);
pinMode(bluPin, OUTPUT);
Serial.begin(9600);
}

// Main program
void loop()
{
potValColor = analogRead(potPinColor); // read the potentiometer value at the input pin
potValBlink = analogRead(potPinBlink);
photoCellValOne = analogRead(fsrOne);
photoCellValTwo = analogRead(fsrTwo);

if (photoCellValOne > 50)
{
analogWrite(redPin, photoCellValOne/4); // Write values to LED pins
analogWrite(grnPin, photoCellValOne/4);
analogWrite(bluPin, photoCellValOne/4);
}

else if (photoCellValTwo > 200)
{
analogWrite(redPin, 0);
analogWrite(grnPin, 0);
analogWrite(bluPin, 0);
}

else {

if (potValColor < 341) // Lowest third of the potentiometer’s range (0-340)
{
potValColor = (potValColor * 3) / 4; // Normalize to 0-255

redVal = 256 – potValColor;
grnVal = potValColor; // Green from off to full
bluVal = 1; // Blue off
}
else if (potValColor < 682) // Middle third of potentiometer’s range (341-681)
{
potValColor = ( (potValColor-341) * 3) / 4; // Normalize to 0-255

redVal = 1;
grnVal = 256 – potValColor;
bluVal = potValColor; // Blue from off to full
}
else // Upper third of potentiometer”s range (682-1023)
{
potValColor = ( (potValColor-683) * 3) / 4; // Normalize to 0-255

redVal = potValColor; // Red from off to full
grnVal = 1; // Green off
bluVal = 256 – potValColor;
};
analogWrite(redPin, redVal); // Write values to LED pins
analogWrite(grnPin, grnVal);
analogWrite(bluPin, bluVal);
delay(potValBlink);
analogWrite(redPin, redVal*0); // Write values to LED pins
analogWrite(grnPin, grnVal*0);
analogWrite(bluPin, bluVal*0);
delay(potValBlink);
};
Serial.println(photoCellValOne);
}

 

Processing Code:

/* PROCESSING SKETCH
* Arduino Ball Paint
* (Arduino Ball, modified 2008)
* ———————-
*
* Draw a ball on the screen whose size is
* determined by serial input from Arduino.
*
* Created 21 September 2016
* Noura Howell
*/
import processing.serial.*;
// Change this to the portname your Arduino board
String portname = “COM11″; //”/dev/cu.usbmodem1421”; // or “COM5″
Serial port;
String buf=””;
int cr = 13; // ASCII return == 13
int lf = 10; // ASCII linefeed == 10

int serialVal = 0;

void setup() {
size(300,300);
frameRate(10);
smooth();
background(40,40,40);
noStroke();
port = new Serial(this, portname, 9600);
}

void draw() {
// erase the screen
background(40, 40, 40);

// draw the ball
fill(255, 255, 255);
ellipse(150,150,serialVal,serialVal);
}

// called whenever serial data arrives
void serialEvent(Serial p) {
int c = port.read();
if (c != lf &amp;&amp; c != cr) {   //syntax error:expecting RPAREN, found ‘;’
buf += char(c);
}
if (c == lf) {
serialVal = int(buf);
println(“val=”+serialVal);
buf = “”;
}
}

“Nearby Friends” and other Marauder’s Maps

In 2014, Facebook launched an app that, miserable failure though it seems to have been in terms of uptake, yet contained an interesting and problematic germ of an idea for ambient displays. The app, “Nearby Friends,” tracks the positions of people listed as a user’s “friends” on Facebook and notifies the owner of the app when a friend enters into a certain geographic range. Additionally, the app, when one clicks through a menu or two, is able to tell the owner the distance of other users from the owner’s position (in miles). And though I don’t believe you could watch friends’ progress on a map in real time, the app indeed provided the app’s owner with notifications of the proximity of other users near and far.

In the language of Pousman and Stasko’s “A Taxonomy of Ambient Information Systems,” Nearby Friends almost comprises an “Information Monitor Display” insofar as it is a “peripheral part of a user’s computer desktop” (an app that can be minimized), that “display[s] multiple sources of information,” and is “capable of notifying users in multiple ways about changes in the source data, including … interrupting, and even demanding user attention when necessary”).

What Nearby Friends lacks is a way of affecting “subtle awareness”: what if one were to develop a TUI that changed according to the proximity of friends and acquaintances? This seems to me among the most primal of “nuggets” of data a person can seek–a list of which might otherwise include weather conditions, information on food scarcity, sources of shelter, and, as in the case of Nearby Friends, the position of allies. Could a system be made that offers a user constant, slow, and subconscious data on the proximity of those around them?

 

 

Mood Jar

For “Mood Jar” I assembled a circuit that connected two potentiometers–one tall, one short–to three LEDs, and put the whole assembly into a jar sprayed with frosted glass spray paint. While I originally wanted to have rotating the lid of the jar activate one of the switches, and rotating the “cuff” of the lid activate the other, this proved difficult and so I did what felt like the right thing to do at the time: drilled holes.

The first potentiometer emerging from the first hole controls the color, which can be “any color” along the range of colors we produced last week with our inputs. The other dial controls blink speed. Overall I think it needs more frosting for diffusion, and given enough coats I think a solid diffusion could be accomplished.

 

Materials:

1 Jar

1 Arduino Micro

Wires

Solder/Soldering Iron

2 Potentiometers

3 Resistors (220 Ohms)

3 LEDs

Hot glue gun/hot glue

Frosted Glass spray paint

 

Code:

 * Modified version of: RGB Pot Mixer2
 * --------------
 *
 * Code for making one potentiometer control 3 LEDs, red, grn and blu, 
 * or one tri-color LED.
 *
 * Uses a purportedly correct algorithm for converting a hue number into RGB values
 * 
 * Code assumes you have the LEDs connected in a common-anode configuration,
 * with the LED's anode connected to +5V via a resistor and the cathode connected
 * to Arduino pins 9,10,11. 
 *
 * Tod E. Kurt <tod@todbot.com>, serial debug by Clay Shirky
 *
 */

// INPUT: Potentiometer should be connected to 5V and GND
int potPinColor = A4; // Potentiometer output connected to analog pin 3
int potPinBlink = A5; // Second potentiometer controlling blink speed
int potValColor = 0; // Variable to store the input from the potentiometer
int potValBlink = 0; // Variable to store the input from the second potentiometer (controlling blink)

// OUTPUT: Use digital pins 9-11, the Pulse-width Modulation (PWM) pins
// LED’s cathodes should be connected to digital GND
int redPin = 9; // Red LED, connected to digital pin 9
int grnPin = 10; // Green LED, connected to digital pin 10
int bluPin = 11; // Blue LED, connected to digital pin 11

// Program variables
int redVal = 0; // Variables to store the values to send to the pins
int grnVal = 0;
int bluVal = 0;

void setup()
{
pinMode(redPin, OUTPUT); // sets the pins as output
pinMode(grnPin, OUTPUT);
pinMode(bluPin, OUTPUT);
}

// Main program
void loop()
{
potValColor = analogRead(potPinColor); // read the potentiometer value at the input pin
potValBlink = analogRead(potPinBlink);

if (potValColor < 341) // Lowest third of the potentiometer’s range (0-340)
{
potValColor = (potValColor * 3) / 4; // Normalize to 0-255

redVal = 256 – potValColor; // Red from full to off
grnVal = potValColor; // Green from off to full
bluVal = 1; // Blue off
}
else if (potValColor < 682) // Middle third of potentiometer’s range (341-681)
{
potValColor = ( (potValColor-341) * 3) / 4; // Normalize to 0-255

redVal = 1; // Red off
grnVal = 256 – potValColor; // Green from full to off
bluVal = potValColor; // Blue from off to full
}
else // Upper third of potentiometer”s range (682-1023)
{
potValColor = ( (potValColor-683) * 3) / 4; // Normalize to 0-255

redVal = potValColor; // Red from off to full
grnVal = 1; // Green off
bluVal = 256 – potValColor; // Blue from full to off
}
analogWrite(redPin, redVal); // Write values to LED pins
analogWrite(grnPin, grnVal);
analogWrite(bluPin, bluVal);
delay(potValBlink);
analogWrite(redPin, redVal*0); // Write values to LED pins
analogWrite(grnPin, grnVal*0);
analogWrite(bluPin, bluVal*0);
delay(potValBlink);
}

https://youtu.be/UEiwWYq9T2I

https://youtu.be/zKnCbmoYxjU

 

Inputs without Outputs: What to do with them?

Fishkin’s taxonomy elevates one’s awareness of a question that’s rarely asked, but worth asking: what exactly comprises a TUI, and how can we systematically compare them to each other? That is, we know a TUI when we see one, and we can easily tell them apart, but Fishkin’s text shows us one way of doing so–and I confess that, while reading, I found myself jotting down new ideas provoked by the rubric. So I did find it productive and helpful, in short.

That said, I wonder about a corner not explicitly covered in the text. Fishkin remarks in the section “Calm Computing” on TUIs stripped of their human inputs: a flower’s petals respond to ambient temperature; or a self-shortening string that responds to bus wait times. These examples are “tangible,” I suppose, insofar as they have components that could conceivably be touched, but they don’t demand user input. Can we imagine, however, a device that would have user input and not produce an output? Can we properly categorize such a device as a TUI?

Take, for example, a button that says “press,” but which has no effect. This button would seem to fall into an unclear categorization in terms of embodiment: would it comprise “full” embodiment insofar as the pushing of the button is itself the user experience? Or would it engage the user as “nearby” or “distant” embodiment (depending on the user’s expectations) that never comes to fruition? What about metaphor: is the metaphorical relationship of the experience “none” because the pushing of the button lacks any kind of relationship with the outcome (where pushing buttons classically results in effects), or would the interaction be better described as “full”? Clearly the example is problematic, and we might think of any number of other examples: a light switch that a user flips while simultaneously knowing it connects to nothing; a television screen that a child touches as if it were touch-sensitive; a synthesizer that one plays while it is off. How would Fishkin’s taxonomy account for such examples—and if it cannot, what categories might we add to help it succeed in this way?

Experimenting with Capillary tubes

LED diffusion has in my minimal experience usually meant sanding: sanding acrylic surfaces in layers and sanding the LEDs too. This time I wanted to experiment with an object I’ve had in my possession for a few years for reasons unknown: a canister of capillary tubes. My goal was to put the LEDs at the bottom of the container to see what would happen with the light and how it would diffuse both sideways through the tubes and also up along them. Between the LEDs and the bottoms of the tubes I put some stuffing to help with the diffusion process, and carefully cut a plastic cup to fit inside for the tubes to stand on. 

 

I also had ambitions to make the code translate normal strings of text into different colored patterns, brightnesses, and fade lengths, but my shortcomings with C ended up forcing me to settle for the simpler interaction (increasing brightness with key presses). Still, it’s an interesting looking object both with the tubes bunched and unbunched, and does a great job of diffusing light.

 

Materials:

Arduino Uno

Arduino Mini

Wires

Capillary Tubes; container

3 LEDs, (R, G, B)

3 Resistors (220 ohm)

Soldering iron, solder

 

Code: 

/* 
* Serial RGB LED
* —————
* Serial commands control the brightness of R,G,B LEDs 
*
* Command structure is “<colorCode><colorVal>”, where “colorCode” is
* one of “r”,”g”,or “b” and “colorVal” is a number 0 to 255.
* E.g. “r0” turns the red LED off. 
* “g127” turns the green LED to half brightness
* “b64” turns the blue LED to 1/4 brightness
*
* Created 18 October 2006
* copyleft 2006 Tod E. Kurt <tod@todbot.com
* http://todbot.com/
*
*
* Special thanks to Neera, whose post I looked at in order to troubleshoot my own 🙂
*/

char serInString[100]; // array that will hold the different bytes of the string. 100=100characters;
// -> you must state how long the array will be else it won’t work properly
char colorCode;
int colorVal;

int redPin = 9; // Red LED, connected to digital pin 9
int greenPin = 10; // Green LED, connected to digital pin 10
int bluePin = 11; // Blue LED, connected to digital pin 11

int brightNess = 0;

int i = 0; // Loop counter 
int wait = 20; // 50ms (.05 second) delay; shorten for faster fades
int DEBUG = 0; // DEBUG counter; if set to 1, will write values back via serial

void setup() {
pinMode(redPin, OUTPUT); // sets the pins as output
pinMode(greenPin, OUTPUT); 
pinMode(bluePin, OUTPUT);
Serial.begin(9600);
analogWrite(redPin, 255); // set them all to v bright
analogWrite(greenPin, 255); 
analogWrite(bluePin, 255); 
Serial.println(“enter color command”); 
}

void loop () 
{
// clear the string
memset(serInString, 0, 100);
//read the serial port and create a string out of what you read
readSerialString(serInString);
brightNess = strlen(serInString);

colorCode = serInString[0];
if( colorCode == ‘r’ || colorCode == ‘g’ || colorCode == ‘b’) {
colorVal = int(brightNess * 10 * 2.55);
Serial.print(“setting color “);
Serial.print(colorCode);
Serial.print(” to “);
Serial.print(colorVal);
Serial.println();
serInString[0] = 0; // indicates we’ve used this string
if(colorCode == ‘r’) 
analogWrite(redPin, colorVal);
else if(colorCode == ‘g’)
analogWrite(greenPin, colorVal);
else if(colorCode == ‘b’)
analogWrite(bluePin, colorVal);

}

delay(wait); // Pause for ‘wait’ milliseconds before resuming the loop 
}

//read a string from the serial and store it in an array
//you must supply the array variable
void readSerialString (char *strArray) {
int j = 0;
if(!Serial.available()) {
return;
}
while (Serial.available()) {
strArray[j] = Serial.read();
j++;
}
}

 

Video:

https://www.youtube.com/watch?v=fxTJK_eC5Xw&feature=youtu.be