Vikram and I set out to create a set of wind chimes that could be used by apartment dwellers. Our goals were simple: to create a set of wind chimes that could function like traditional analog wind chimes, creating sound by a striker striking chimes - but we wanted a set that would be silent outdoors.
I love wind chimes. They make me think of spending the summers near the ocean in Maine while I was growing up. A few years ago my friend Cate gave me a set of chimes that came off her parents' house in Lanesville, NY. I wanted to hang them out on my fire escape, but they are too loud considering how many neighbors share the alley my window looks out on.
We wanted a set of chimes that would be silent outside, but that one could listen to inside, in his or her own home.
We created two versions, one that can hang from a fire escape or terrace, and a second that can sit on a windowsill in the case that someone has no outdoor space. The signals are transmitted wirelessly via XBee radio to a computer inside the apartment, where the volume can be as low or as high as one would like.
Below is a video of the window sill version of the Chim-era:
And the hanging version of the Chim-era:
posted by Amanda @ 7:53 PM,
,
Rock Paper Scissors
For this project we used two Arduinos, two XBees, two FTDI USB to Serial adapters for software serial, and 8 switches.
The idea was for each player to have a reset switch and one switch each for rock, paper and scissors. It took a lot longer for us to get this project running than we had anticipated, primarily because we didn't initially use software serial and couldn't decipher exactly how, or even if the XBees were communicating.


Code:
//Project: Paper Rock Scissor
//Stella Kim and Amanda Bernsohn
//Class: Sociable Obects
#define winLedPin 5 // pin that indicated winning
#define resetLedPin 6 // LED that indicates a reset
#define buttonReset 9 // Button to reset the game
#define buttonR 10 // Rock Button
#define buttonP 11 // Paper Button
#define buttonS 12 // Scissors Button
#define txLed 2 // LED to indicate outgoing data
#define rxLed 3 // LED to indicate incoming data
char inByte=0;
boolean outcome=false;
boolean reset = false;
void setup(){
// set pinModes for everything
pinMode(buttonR, INPUT);
pinMode(buttonP, INPUT);
pinMode(buttonS, INPUT);
pinMode(buttonReset, INPUT);
pinMode(winLedPin, OUTPUT);
pinMode(resetLedPin, OUTPUT);
pinMode(txLed, OUTPUT);
pinMode(rxLed, OUTPUT);
Serial.begin(9600);
setDestination();
blink(10);
}
void setDestination() {
// put the radio in command mode:
Serial.print("+++");
// wait for the radio to respond with "OK\r"
char thisByte = 0;
while (thisByte != '\r') {
if (Serial.available() > 0) {
thisByte = Serial.read();
}
}
//code from Glow the LED lab
// set the destination address, using 16-bit addressing.
// if you're using two radios, one radio's destination
// should be the other radio's MY address, and vice versa:
Serial.print("ATDH0, DL1234\r");
// set my address using 16-bit addressing:
Serial.print("ATMY5678\r");
// set the PAN ID. If you're working in a place where many people
// are using XBees, you should set your own PAN ID distinct
// from other projects.
Serial.print("ATID1111\r");
// put the radio in data mode:
Serial.print("ATCN\r");
}
void loop(){
//check button state
if (buttonReset==HIGH){
reset=true;
}
else{
reset=false;
}
player();
}
void player(){
char myChoice, herChoice;
if(buttonR==HIGH){
myChoice='R';
}
if(buttonP==HIGH){
myChoice='P';
}
if(buttonS==HIGH){
myChoice='S';
}
//send answer to serial buffer for opponents choice
Serial.print(myChoice);
handleSerial();
//keep lisetning if opponenets value not yet received
while(inByte != 'R' && inByte !='P' && inByte != 'S')
handleSerial();
//store opponents value
herChoice=inByte;
if((herChoice=='P') && (myChoice=='S')){
outcome=true;
digitalWrite(winLedPin,HIGH);
}
if((herChoice=='P') && (myChoice=='R')){
outcome=false;
digitalWrite(winLedPin,LOW);
}
else if((herChoice=='R') && (myChoice=='S')){
outcome=false;
digitalWrite(winLedPin,LOW);
}
else if((herChoice=='R') && (myChoice=='P')){
outcome=true;
digitalWrite(winLedPin,HIGH);
}
else if((herChoice=='S') && (myChoice=='P')){
outcome=false;
digitalWrite(winLedPin,LOW);
}
else if((herChoice=='S') && (myChoice=='R')){
outcome=true;
digitalWrite(winLedPin,HIGH);
}
else if(herChoice==myChoice){
outcome=false;
blink(5);
//reset game
if(reset==true){
digitalWrite(resetLedPin,HIGH);
delay(20);
digitalWrite(resetLedPin,LOW);
delay(20);
digitalWrite(resetLedPin,HIGH);
delay(20);
digitalWrite(resetLedPin,LOW);
delay(20);
}
}
}
void handleSerial(){
if (Serial.available() > 0 ) {
// read a byte
inByte = Serial.read();
}
}
// Blink the tx LED:
void blink(int howManyTimes) {
for (int i=0; i< howManyTimes; i++) {
digitalWrite(winLedPin, HIGH);
delay(250);
digitalWrite(winLedPin, LOW);
delay(250);
}
}
posted by Amanda @ 3:53 AM,
,
Glow the Led
Sunday, June 1, 2008
This week's assignment was to set up boards and mount our XBees to their breakout boards in order to make leds glow wirelessly. We ran into a couple of small problems, but ultimately were able to get it working fairly quickly. We used Tom's code from Making Things Talk -- shown below.
After setting up our boards Steven and I both ran into snags. Steven's Arduino wouldn't accept uploaded code - this was easily fixed by removing the TX and RX wires during uploaded, and then plugging them in again. My XBee didn't respond properly to the code in the sense that the status leds were not operating as planned. It turned out that the ground pin on my breakout board wasn't soldered properly. Thanks Rob!


+
+++++++++++++++++++++++++++++
/*
XBee terminal
language: processing
This program is a basic serial terminal program.
It replaces newline characters from the keyboard
with return characters. It's designed for use with
Linux, Unix, and OSX and XBee radios, because the XBees
don't send newline characters back.
created 2 Feb. 2007
modified 24 Mar. 2007
by Tom Igoe
*/
import processing.serial.*;
Serial myPort; // the serial port you're using
String portnum; // name of the serial port
String outString = ""; // the string being sent out the serial port
String inString = ""; // the string coming in from the serial port
int receivedLines = 0; // how many lines have been received in the serial port
int bufferedLines = 10; // number of incoming lines to keep
void setup() {
size(400, 300); // window size
// create a font with the second font available to the system:
PFont myFont = createFont(PFont.list()[2], 14);
textFont(myFont);
// list all the serial ports:
println(Serial.list());
// based on the list of serial ports printed from the
//previous command, change the 0 to your port's number:
portnum = Serial.list()[2];
// initialize the serial port:
myPort = new Serial(this, portnum, 9600);
}
void draw() {
// clear the screen:
background(0);
// print the name of the serial port:
text("Serial port: " + portnum, 10, 20);
// Print out what you get:
text("typed: " + outString, 10, 40);
text("received:n" + inString, 10, 80);
}
// This method responds to key presses when the
// program window is active:
void keyPressed() {
switch (key) {
// in OSX, if the user types return,
// a linefeed is returned. But to
// communicate with the Xbee, you want a carriage return:
case 'n':
myPort.write(outString + "r");
outString = "";
break;
case 8: // backspace
// delete the last character in the string:
outString = outString.substring(0, outString.length() -1);
break;
case '+': // we have to send the + signs even without a return:
myPort.write(key);
// add the key to the end of the string:
outString += key;
break;
case 65535: // If the user types the shift key, don't type anything:
break;
// any other key typed, add it to outString:
default:
// add the key to the end of the string:
outString += key;
break;
}
}
// this method runs when bytes show up in the serial port:
void serialEvent(Serial myPort) {
// read the next byte from the serial port:
int inByte = myPort.read();
// add it to inString:
inString += char(inByte);
if (inByte == 'r') {
// if the byte is a carriage return, print
// a newline and carriage return:
inString += 'n';
// count the number of newlines:
receivedLines++;
// if there are more than 10 lines, delete the first one:
if (receivedLines > bufferedLines) {
deleteFirstLine();
}
}
}
// deletes the top line of inString so that it all fits on the screen:
void deleteFirstLine() {
// find the first newline:
int firstChar = inString.indexOf('n');
// delete it:
inString= inString.substring(firstChar+1);
}
posted by Amanda @ 10:59 PM,
,
The Clif Bar Detector
For our find and fix assignment I had the idea of making something that would allow someone walking through the floor to know if and where there is food being sold out of any of the lockers. Since, typically, it's energy bars or other packaged food that's available, it was relatively easy to calibrate an FSR to show whether or not there is food in the locker - as well as how many items are inside (as long as the items are the same).
The biggest challenge that I faced was setting up my FSR - even though it's entirely straightforward, and there are only two leads off the sensor (which are not polar).. I couldn't get the readings to be in any way accurate or stable. It took me the good part of the day to realize that, in fact, nothing was being read (during the course of that day I tried every resistor I could get my hands on). With Chris Cerrito's help via phone I realized that I wasn't powering the sensor properly and that it hadn't been functioning at all.
After that was all sorted out and everything was running, I measure 1, 2, 3 ad 4 Clif Bars to see how I could use the FSR as a scale of sorts. In the end, though it isn't entirely accurate, the setup functions generally and measures whether there are any bars in the locker and if so, how many. Among the comments I received in class was a suggestion to have an LED lit the entire time to show that the system is functioning, and making it battery powered. In class Rob showed us how to check using continuity readings off the multimeter to see which wire is power and which is ground on the battery adapter.

Here's the Arduino code:
++++++++++++++++++++++++++
int finderPin = 1; // Analog input from rangefinder
int finderValue = 0; // value read from the finder
int redLedPin = 2;
int yellowLedPin = 4;
int blueLedPin = 5;
int whiteLedPin = 6;
void setup() {
// initialize serial communications at 9600 bps:
Serial.begin(9600);
pinMode(finderPin, INPUT);
pinMode(redLedPin, OUTPUT);
pinMode(yellowLedPin, OUTPUT);
pinMode(blueLedPin, OUTPUT);
pinMode(whiteLedPin, OUTPUT);
}
void loop() {
// read the rangefinder value
finderValue = analogRead(finderPin)/4;
// new line
delay(500); // Wait half a second
// print finder value back to the debugger pane
Serial.println(finderValue);
//no bars
if(finderValue <= 5) {
digitalWrite(redLedPin, LOW);
digitalWrite(yellowLedPin, LOW);
digitalWrite(blueLedPin, LOW);
digitalWrite(whiteLedPin, LOW);
}
//one bar
if (finderValue > 5 && finderValue <= 18) {
digitalWrite(redLedPin, HIGH);
digitalWrite(yellowLedPin, LOW);
digitalWrite(blueLedPin, LOW);
digitalWrite(whiteLedPin, LOW);
}
//two bars
if (finderValue > 18 && finderValue < 37) {
digitalWrite(yellowLedPin, HIGH);
digitalWrite(redLedPin, LOW);
digitalWrite(blueLedPin, LOW);
digitalWrite(whiteLedPin, LOW);
}
//three bars
if (finderValue >= 38 && finderValue <=60) {
digitalWrite(blueLedPin, HIGH);
digitalWrite(redLedPin, LOW);
digitalWrite(yellowLedPin, LOW);
digitalWrite(whiteLedPin, LOW);
}
//four bars
if (finderValue >= 61 && finderValue <=85) {
digitalWrite(yellowLedPin, LOW);
digitalWrite(redLedPin, LOW);
digitalWrite(blueLedPin, LOW);
digitalWrite(whiteLedPin, HIGH);
}
}
/*
4 bars - 61-85
3 bars - 38-60
2 bars - 18-37 (30 ideal)
1 bars - 9-18 (11 ideal)
*/
posted by Amanda @ 10:32 PM,
,
testing
posted by Amanda @ 12:01 PM,
,