Responsive Altar
Concept
For Project 2, I decided to create a responsive altar that invites people walking by to come to share their feelings. There are three color options that each correlate to a different emotional state: red = desire, yellow = joy, blue = grief. It uses a distance sensor to recognize when a person is present. The close the person is the more candles light. They are arranged in 4 tiers that are triggered at different distance ranges. The distance also determines what appears on a p5 sketch. Once the person is 30 inches from the sensor all the lights remain on and the p5 sketch invites them to respond to one of the three emotion prompts. Once the person writes their response they submit it through a slot in the altar. This slot houses an RGB sensor that is meant to trigger a change in the sketch based on the color of the note. In this iteration, I did not have the RGB sensor fully set up. It was able to read the color and provide the R, G, and B values, but I was not able to figure out the parameters to consistently distinguish between the three colors.
Prototypes
Construction
Demo
Code
Arduino Code
/* Candle Controller, flickering LEDs Used to Read MaxSonar MB1010 Written for Arduino Nano Reading Pin3 output Started 11/03/21 */ const int anPin = 0; long anVolt, mm, inches; void setup() { Serial.begin(9600); pinMode(2, OUTPUT); pinMode(3, OUTPUT); pinMode(4, OUTPUT); pinMode(5, OUTPUT); } void loop() { read_sensor(); approach(); delay(100); } void read_sensor() { anVolt = analogRead(anPin); mm = anVolt * 5; //Takes bit count and converts it to mm inches = mm / 25.4; //Takes mm and converts it to inches delay(1); } void approach() { if (inches <= 30 ) { tier4(); } else if (inches >= 30 && inches <= 54) { tier3(); } else if (inches >= 54 && inches <= 96) { tier2(); } else if (inches >= 96 && inches <= 120) { //10 feet tier1(); } else { altarOff(); } } void tier4() { Serial.print("tier4 on: "); Serial.println(inches); altarOn(); Serial.write(inches); delay(1); } void tier3() { Serial.print("tier3 on: "); Serial.println(inches); digitalWrite(5, LOW); //bottom digitalWrite(4, HIGH); digitalWrite(3, HIGH); digitalWrite(2, HIGH); //top Serial.write(inches); delay(1); } void tier2() { Serial.print("tier2 on: "); Serial.println(inches); digitalWrite(5, LOW); //bottom digitalWrite(4, LOW); digitalWrite(3, HIGH); digitalWrite(2, HIGH); //top Serial.write(inches); delay(1); } void tier1() { Serial.print("tier1 on: "); Serial.println(inches); digitalWrite(5, LOW); //bottom digitalWrite(4, LOW); digitalWrite(3, LOW); digitalWrite(2, HIGH); //top Serial.write(inches); delay(1); } void altarOff() { Serial.print("altar off: "); Serial.println(inches); digitalWrite(2, LOW); //bottom digitalWrite(3, LOW); digitalWrite(4, LOW); digitalWrite(5, LOW); //top Serial.write(inches); delay(1); } void altarOn() { digitalWrite(2, HIGH); //bottom digitalWrite(3, HIGH); digitalWrite(4, HIGH); digitalWrite(5, HIGH); //top } // written based on code from: https://www.maxbotix.com/Arduino-Ultrasonic-Sensors-085/
p5.js Code
let serial; let portName = '/dev/cu.usbmodem1421'; let distanceData; let colorData; let myFont; let W, H, txtW, txtH; function preload() { myFont = loadFont("TheNeue-Black.otf"); } function setup() { serial = new p5.SerialPort(); // make a new instance of the serialport library serial.on('connected', serverConnected); // callback for connecting to the server serial.on('open', portOpen); // callback for the port opening serial.on('data', serialEvent); // callback for when new data arrives serial.on('error', serialError); // callback for errors serial.on('close', portClose); // callback for the port closing serial.list(); // list the serial ports serial.open(portName); // open a serial port createCanvas(windowWidth,windowHeight); rectMode(CENTER); textAlign(CENTER,TOP); W = width; H = height; txtW = width/2; txtH = height/2; } function draw() { if (distanceData <= 30 ) { instructions(); } else if (distanceData >= 30 && distanceData <= 54) { question(); } else if (distanceData >= 54 && distanceData <= 96) { hello(); } else if (distanceData >= 96 && distanceData <= 120) { //10 feet screen(); } else { screen(); } emotion(); //if (colorData == 1) //grief(); //joy(); //desire(); } function emotion(){ if (mouseX <= windowWidth/4 && mouseY > windowHeight-windowHeight/8){ joy(); } else if (mouseX >= windowWidth-windowWidth/4 && mouseY > windowHeight-windowHeight/8){ desire(); } else if (mouseX <= windowWidth/2 && mouseY > windowHeight-windowHeight/8){ grief(); } } function screen(){ background(0); } function hello(){ background(0); fill(204,229,255); textFont(myFont); textSize(W/10); text("Hello.", txtW, txtH+50, W, H); } function question(){ background(0); fill(204,229,255); textFont(myFont); textSize(W/10); text("Hello.", txtW, txtH+50, W, H); fill(255,198,81); textSize(W/15); text("Would you like to leave an offering?", txtW, txtH+175, W, H); } function instructions(){ background(0); fill(204,229,255); textFont(myFont); textSize(W/10); text("Hello.", txtW, txtH+50, W, H); fill(255,198,81); textSize(W/15); text("Would you like to leave an offering?", txtW, txtH+175, W, H); fill(204,255,153); textSize(W/20); text("Choose one of the three. Write a message. Leave it with me.", txtW, txtH+400, W, H) fill("yellow"); text("joy", txtW-200, txtH+550, W, H); fill("blue"); text("grief", txtW, txtH+550, W, H); fill("red"); text("desire", txtW+200, txtH+550, W, H); } function grief(){ background("blue"); fill(0,0,0); textFont(myFont); textSize(W/10); text("Thank You for Your Sharing", txtW, txtH+25, W, height); fill(240,240,240); textFont('Futura'); textSize(W/16); text("In this altar all feelings are cherished.", txtW, txtH+275, W, height); text("Let this offering be a release from some of the aches your grief brings.", txtW, txtH+400, W, height); } function joy(){ background("yellow"); fill(255,128,0); textFont(myFont); textSize(W/10); text("Thank You for Your Sharing", txtW, txtH+25, W, height); fill(153,76,0); textFont('Futura'); textSize(W/16); text("In this altar all feelings are cherished.", txtW, txtH+275, W, height); text("Let this be a chance for you to feel the tangible comfort of your joy.", txtW, txtH+400, W, height); } function desire(){ background("red"); fill(255); textFont(myFont); textSize(W/10); text("Thank You for Your Sharing", txtW, txtH+25, W, height); fill(255,102,102); textFont('Futura'); textSize(W/16); text("In this altar all feelings are cherished.", txtW, txtH+275, W, height); text("Let this be a nonjudgemental acknowledgement of the desires you hold.", txtW, txtH+400, W, height); } function serverConnected() { console.log('connected to server.'); } function portOpen() { console.log('the serial port opened.') } function serialEvent() { distanceData = Number(serial.read()); //colorData = Number(serial.read()); } function serialError(err) { console.log('Something went wrong with the serial port. ' + err); } function portClose() { console.log('The serial port closed.'); }
Sources: