This was a game I designed for the final project of Parsons MFADT Physical Computing class. The goal of this game is to control and mix R/G/B color values to match the background color within 10 seconds each level. I used three photoresistors connected to arduino uno to sense the color value controlled by 1 to 3 players, and use openframeworks to build the user interface of this game.
Using a controller with 3 potentiometers – one to select the color, tab, and attribute – make your very own Uglydoll! This project was made using Arduino and Processing.
// TODO 1: copy these (3 lines):
import processing.serial.*;
Serial port; // The serial port object
boolean sending = false;
void setup() {
// TODO 2: copy these (2 lines):
// Using the first available port (might be different on your computer)
port = new Serial(this, Serial.list()[0], 9600);
// TODO 3: add this if statement (4 lines) to the end of your draw() function
// until we start sending, ask for values
if ( !sending ) {
port.write(65); // arbitrary character (the letter A)
}
}
// TODO 4: copy this whole function into your code (at the end)
// Called whenever there is something available to read
void serialEvent(Serial port) {
sending = true;
// Data from the Serial port is read in serialEvent() using the readStringUntil()
// function with * as the end character.
String input = port.readStringUntil(‘*’);
if (input != null) {
// Print message received
println( “Receiving:” + input);
// The data is split into an array of Strings with a comma or
// asterisk as a delimiter and converted into an array of integers.
int[] vals = int(splitTokens(input, “,*”));
// the num variable will hold the value we’ve read from the serial connection
selectColor = vals[0];
// TODO 5: If you are using more than one sensor, set the other values here. For example:
selectTab = vals[1];
selectAttribute = vals[2];
// etc.
// And just make sure these variables are declared up top (eg, “int otherNum;”)
}
// When finished ask for values again
port.write(65);
}
//Jessy Jo Gomez
//”communication”
int firstSensor = 0; // first analog sensor
int secondSensor = 0; // second analog sensor
int thirdSensor = 0; // third analog sensor
int inByte = 0; // incoming serial byte
void setup()
{
// start serial port at 9600 bps:
Serial.begin(9600);
}
void loop()
{
// if we get a valid byte, read analog ins:
if (Serial.available() > 0) {
// get incoming byte:
inByte = Serial.read();
// read first analog input, divide by 4 to make the range 0-255:
firstSensor = analogRead(3)/4;
// read second analog input, divide by 4 to make the range 0-255:
secondSensor = analogRead(4)/4;
// read third analog input, divide by 4 to make the range 0-255:
thirdSensor = analogRead(5)/4;
// delay 10ms to let the ADC recover:
delay(10);
// send sensor values:
// print each sensor value, then print a comma
Serial.print(firstSensor, DEC);
Serial.print(‘,’);
Serial.print(secondSensor, DEC);
Serial.print(‘,’);
Serial.print(thirdSensor, DEC);
// at the end, send a ‘*’ to end the message:
Serial.print(‘*’);
Contemporary, new kinds of technologies are changing people’s lives constantly. Sometimes we even can’t notice these changes are happening to us. However, technologies can’t really understand people’s emotion need. For instance, the mobile phones and the Internet make distance nothing but can’t make you feel really close to each other.
In this project, I design a sound piece to solve one emotional problem for roommates when they are dissatisfied with each other. You can also use this to give yourself some surprise.
It usually happens in my country that roommates don’t want talk to each other after quarreling and no one want to talk first. It kind of means you surrender if you talk first and really can make you lose face. We are reactive culture type. We never confront, usually react to others’ actions and must not lose face. But we need to solve problem after quarreling and talk to each other is the only efficient method. How can we make people feel more comfortable to be the first one to talk?
Then I design a sound piece as a bridge to connect people together, initiate conversation. When you are dissatisfied with your roommate, you can use this sound piece to record message to him/her.
Function
There are seven buttons on the wooden box. Because in China we always have six to seven roommates in dorm. Each roommate has one specific button for themselves. The big buttons and little stars combine together to make a letter “t”, which means “Talk to me”. The shape of the box is just like a tree truck and the shape of the edge is just like growth ring, which represents time.
Self-record mode: If you want to leave some message to yourself, you can just click on your button to record messages, then click on your button to save message. The machine can choose a random day from three days to one month. On that day, all the lights will be on and you click on your button to hear the one message from your self, just like a time capsule.
Contact mode: If you want to say something to your roommates but don’t want to knock on their doors or say something face by face, you can click on your button to record message, then click on your roommate’s button to save the message on his/her spot. All the lights will be on immediately to remind your roommates to listen to the message. Only the roommate who you leave message to can hear the message from you. Other roommates can only hear the message from themselves. Through this method, we can avoid the awkward of talking some dissatisfied things face by face and avoid the unpleasant feeling of talking first.
Structures and Pieces
I use 7 LED buttons, one NEO pixel ring, one microphone, one speaker with amplifier and one sound chip. It takes me a lot of time to put all these stuff into the wooden box.
Code
// include SPI, MP3 and SD libraries
#include <SPI.h>
#include <Adafruit_VS1053.h>
#include <SD.h>
#include <Adafruit_NeoPixel.h>
File recording; // the file we will save our recording to
#define RECBUFFSIZE 128 // 64 or 128 bytes.
uint8_t recording_buffer[RECBUFFSIZE];
int led=2;
void setup() {
Serial.begin(9600);
Serial.println(“Record_Play”);
strip.begin();
strip.show();
rainbow(20);
pinMode(led, OUTPUT);
// initialise the music player
if (!musicPlayer.begin()) {
Serial.println(“VS1053 not found”);
while (1); // don’t do anything more
}
musicPlayer.sineTest(0x44, 500); // Make a tone to indicate VS1053 is working
if (!SD.begin(CARDCS)) {
Serial.println(“SD failed, or not present”);
while (1); // don’t do anything more
}
Serial.println(“SD OK!”);
// Set volume for left, right channels. lower numbers == louder volume!
musicPlayer.setVolume(40,40);
// when the button is pressed, record!
pinMode(REC_BUTTON, INPUT);
digitalWrite(REC_BUTTON, HIGH);
pinMode(PLAY_BUTTON, INPUT);
digitalWrite(PLAY_BUTTON, HIGH);
// load plugin from SD card! We’ll use mono 44.1KHz, high quality
if (! musicPlayer.prepareRecordOgg(“v44k1q05.img”)) {
Serial.println(“Couldn’t load plugin!”);
while (1);
}
}
// Check if the file exists already
char filename[15];
strcpy(filename, “RECORD00.OGG”);
for (uint8_t i = 0; i < 100; i++) {
filename[6] = ‘0’ + i/10;
filename[7] = ‘0’ + i%10;
num=i;
// create if does not exist, do not open existing, write, sync after write
if (! SD.exists(filename)) {
break;
}
}
Serial.print(“Recording to “); Serial.println(filename);
recording = SD.open(filename, FILE_WRITE);
if (! recording) {
Serial.println(“Couldn’t open file to record!”);
while (1);
}
musicPlayer.startRecordOgg(true); // use microphone (for linein, pass in ‘false’)
}
if (isRecording)
saveRecordedData(isRecording);
if (isRecording && !digitalRead(REC_BUTTON)) {
Serial.println(“End recording”);
digitalWrite(led, LOW);
musicPlayer.stopRecordOgg();
isRecording = false;
// flush all the data!
saveRecordedData(isRecording);
// close it up
recording.close();
delay(100);
}
if(!isRecording && !digitalRead(PLAY_BUTTON)){
if (! musicPlayer.begin()) { // initialise the music player
Serial.println(F(“Couldn’t find VS1053, do you have the right pins defined?”));
while (1);
}
Serial.println(F(“VS1053 found”));
SD.begin(CARDCS); // initialise the SD card
// Set volume for left, right channels. lower numbers == louder volume!
musicPlayer.setVolume(40,40);
// Timer interrupts are not suggested, better to use DREQ interrupt!
//musicPlayer.useInterrupt(VS1053_FILEPLAYER_TIMER0_INT); // timer int
// If DREQ is on an interrupt pin (on uno, #2 or #3) we can do background
// audio playing
musicPlayer.useInterrupt(VS1053_FILEPLAYER_PIN_INT); // DREQ int
char filename[15];
strcpy(filename, “RECORD00.OGG”);
filename[6] = ‘0’ + num/10;
filename[7] = ‘0’ + num%10;
// Play one file, don’t return until complete
musicPlayer.playFullFile(filename);
// File is playing in the background
if (musicPlayer.stopped()) {
Serial.println(“Done playing music”);
}
delay(100);
}
}
uint16_t saveRecordedData(boolean isrecord) {
uint16_t written = 0;
// read how many words are waiting for us
uint16_t wordswaiting = musicPlayer.recordedWordsWaiting();
// try to process 256 words (512 bytes) at a time, for best speed
while (wordswaiting > 256) {
//Serial.print(“Waiting: “); Serial.println(wordswaiting);
// for example 128 bytes x 4 loops = 512 bytes
for (int x=0; x < 512/RECBUFFSIZE; x++) {
// fill the buffer!
for (uint16_t addr=0; addr < RECBUFFSIZE; addr+=2) {
uint16_t t = musicPlayer.recordedReadWord();
//Serial.println(t, HEX);
recording_buffer[addr] = t >> 8;
recording_buffer[addr+1] = t;
}
if (! recording.write(recording_buffer, RECBUFFSIZE)) {
Serial.print(“Couldn’t write “); Serial.println(RECBUFFSIZE);
while (1);
}
}
// flush 512 bytes at a time
recording.flush();
written += 256;
wordswaiting -= 256;
}
wordswaiting = musicPlayer.recordedWordsWaiting();
if (!isrecord) {
Serial.print(wordswaiting); Serial.println(” remaining”);
// wrapping up the recording!
uint16_t addr = 0;
for (int x=0; x < wordswaiting-1; x++) {
// fill the buffer!
uint16_t t = musicPlayer.recordedReadWord();
recording_buffer[addr] = t >> 8;
recording_buffer[addr+1] = t;
if (addr > RECBUFFSIZE) {
if (! recording.write(recording_buffer, RECBUFFSIZE)) {
Serial.println(“Couldn’t write!”);
while (1);
}
recording.flush();
addr = 0;
}
}
if (addr != 0) {
if (!recording.write(recording_buffer, addr)) {
Serial.println(“Couldn’t write!”); while (1);
}
written += addr;
}
musicPlayer.sciRead(VS1053_SCI_AICTRL3);
if (! (musicPlayer.sciRead(VS1053_SCI_AICTRL3) & _BV(2))) {
recording.write(musicPlayer.recordedReadWord() & 0xFF);
written++;
}
recording.flush();
}
//Theatre-style crawling lights.
void theaterChase(uint32_t c, uint8_t wait) {
for (int j=0; j<10; j++) { //do 10 cycles of chasing
for (int q=0; q < 3; q++) {
for (int i=0; i < strip.numPixels(); i=i+3) {
strip.setPixelColor(i+q, c); //turn every third pixel on
}
strip.show();
delay(wait);
for (int i=0; i < strip.numPixels(); i=i+3) {
strip.setPixelColor(i+q, 0); //turn every third pixel off
}
}
}
}
//Theatre-style crawling lights with rainbow effect
void theaterChaseRainbow(uint8_t wait) {
for (int j=0; j < 256; j++) { // cycle all 256 colors in the wheel
for (int q=0; q < 3; q++) {
for (int i=0; i < strip.numPixels(); i=i+3) {
strip.setPixelColor(i+q, Wheel( (i+j) % 255)); //turn every third pixel on
}
strip.show();
delay(wait);
for (int i=0; i < strip.numPixels(); i=i+3) {
strip.setPixelColor(i+q, 0); //turn every third pixel off
}
}
}
}
// Input a value 0 to 255 to get a color value.
// The colours are a transition r – g – b – back to r.
uint32_t Wheel(byte WheelPos) {
WheelPos = 255 – WheelPos;
if(WheelPos < 85) {
return strip.Color(255 – WheelPos * 3, 0, WheelPos * 3);
} else if(WheelPos < 170) {
WheelPos -= 85;
return strip.Color(0, WheelPos * 3, 255 – WheelPos * 3);
} else {
WheelPos -= 170;
return strip.Color(WheelPos * 3, 255 – WheelPos * 3, 0);
}
}
My new concept is making a device to express how noise affect our inner world. The container is divided into two parts. One stand for our inner wold while the other one means the outside world. Since people can hardly concentrate on both the inner world and the outside world, they have to struggle for more space. Once the outside part got more room, it means the inner part has lost some.
When people stay in a noisy environment, they can hardly focus on their thought. Instead of thinking in their mind, they will pay more attention what is happening around. So I try to make the two parts of room available, and could change with the volume of sound.
To get the volume I used a sound sensor. And I used two servos to get a border, which divided the container into two parts, moving with the change of environment. To make the loudness of sound more visible, I use two fans, which could also map their speed with noisy environment. There are small feathers inside the container, so that they will fly in the container while it is noisy outside.
#include <Servo.h>
int sensor1=11;
int sensor2 =10;
int sensor3 =12;
int pos1=0;
int pos2;
int sensor = A5;
int loudness;