“Our First Dinner After the Pandemic”
Pearl and Mega
“Our first dinner after pandemic” is an interactive experience on dining table where two people have each other’s “image” and heartbeat sound as their main course.
Since the pandemic our appreciation for eating with others has grown immensely, we now cherish the opportunity to eat with friends and share a dining experience. So, we decided to create a dining experience which emphasizes the “dining-partner” more than the food itself.
Documentation:
Arduino Code:
#include <Wire.h>
#include “MAX30105.h”
#include “heartRate.h”
MAX30105 particleSensor;
const byte RATE_SIZE = 4; //Increase this for more averaging. 4 is good.
byte rates[RATE_SIZE]; //Array of heart rates
byte rateSpot = 0;
long lastBeat = 0; //Time at which the last beat occurred
float beatsPerMinute;
int beatAvg;
void setup() {
Serial.begin(115200);
Serial.println(“Initializing…”);
// Initialize sensor
if (!particleSensor.begin(Wire, I2C_SPEED_FAST)) {
Serial.println(“MAX30102 was not found. Please check wiring/power. “);
while (1);
}
Serial.println(“Place your index finger on the sensor with steady pressure.”);
particleSensor.setup(); //Configure sensor with default settings
particleSensor.setPulseAmplitudeRed(0x0A); //Turn Red LED to low to indicate sensor is running
particleSensor.setPulseAmplitudeGreen(0); //Turn off Green LED
}
void loop() {
long irValue = particleSensor.getIR();
if (checkForBeat(irValue) == true) {
//We sensed a beat!
long delta = millis() – lastBeat;
lastBeat = millis();
beatsPerMinute = 60 / (delta / 1000.0);
if (beatsPerMinute < 255 && beatsPerMinute > 20) {
rates[rateSpot++] = (byte)beatsPerMinute; //Store this reading in the array
rateSpot %= RATE_SIZE; //Wrap variable
//Take average of readings
beatAvg = 0;
for (byte x = 0 ; x < RATE_SIZE ; x++)
beatAvg += rates[x];
beatAvg /= RATE_SIZE;
}
}
Serial.print(beatsPerMinute);
Serial.print(“.”);
Serial.print(beatAvg);
Serial.println();
}
P5js Code:
let xspacing = 16; // Distance between each horizontal location
let w; // Width of entire wave
let theta = 0.0; // Start angle at 0
let amplitude; // Height of wave
let period = 500; // How many pixels before the wave repeats
let dx; // Value for incrementing x
let yvalues; // Using an array to store height values for the wave
let colorcode;
let colorcode2;
let overlay;
let webcam;
let osc;
function preload() {
overlay = loadImage (‘overlay.png’);
webcam = createCapture(VIDEO);
webcam.hide();
}
function setup() {
createCanvas(1920, 1080);
w = width + 16;
dx = (TWO_PI / period) * xspacing;
yvalues = new Array(floor(w / xspacing));
serial = new p5.SerialPort();
serial.open(“/dev/tty.usbmodem14401”);
serial.on(“data”, gotData);
osc = new p5.Oscillator();
osc.freq(220);
osc.setType(‘sine’);
osc.amp(1);
osc.start();
}
function draw() {
background(255);
image (webcam, 0, 0, 1920, 1080);
calcWave();
renderWave();
image (overlay, 0, 0, 1920, 1080);
}
function gotData() {
let currentString = serial.readLine();
if (currentString.length > 0) {
let readings = split(currentString, “.”);
let data1 = readings[0];
let data2 = readings[1];
let data3 = readings[2];
amplitude = map(data3, 0, 300, 0, height);
w = map (data3,0, 300, 0, width + 16);
colorcode2 = map(data1, 0, 100, 0, 255)
colorcode = map(data2, 0, 100, 0, 255 )
console.log (data3);
if(data3 >= 100 && data3 <= 110){
osc.freq(900)
}else if(data3 >= 97 && data3 <= 100){
osc.freq(861)
} else if(data3 >= 93 && data3 <= 96){
osc.freq(822)
} else if (data3 >= 89 && data3 <= 92) {
osc.freq(783)
} else if (data3 >= 85&& data3 <= 88) {
osc.freq(744)
} else if (data3 >= 81 && data3 <= 84) {
osc.freq(705)
} else if (data3 >= 77 && data3 <= 80) {
osc.freq(666)
} else if(data3 >= 73 && data3 <=76){
osc.freq(627)
} else if(data3 >= 69 && data3 <= 72){
osc.freq(588)
} else if(data3 >= 65 && data3 <= 68){
osc.freq(549)
} else if(data3 >= 61 && data3 <= 64){
osc.freq(510)
} else if(data3 >= 59 && data3 <= 62){
osc.freq(471)
} else if(data3 >= 55 && data3 <= 58){
osc.freq(432)
} else if(data3 >= 51 && data3 <= 54){
osc.freq(393)
} else if(data3 >= 47 && data3 <= 50){
osc.freq(354)
} else if(data3 >= 43 && data3 <= 46){
osc.freq(315)
} else if(data3 >= 39&& data3 <= 42){
osc.freq(276)
} else if(data3 >= 35 && data3 <= 38){
osc.freq(237)
} else if(data3 >= 31 && data3 <= 34){
osc.freq(198)
} else if(data3 >= 27&& data3 <= 30){
osc.freq(159)
} else if(data3 >= 23 && data3 <= 26){
osc.freq(120)
} else if(data3 >= 19 && data3 <= 22){
osc.freq(100)
}
}
}
function calcWave() {
// Increment theta (try different values for
// ‘angular velocity’ here)
theta += 0.02;
// For every x value, calculate a y value with sine function
let x = theta;
for (let i = 0; i < yvalues.length; i++) {
yvalues[i] = sin(x) * amplitude;
x += dx;
}
}
function renderWave() {
noStroke();
fill(colorcode, colorcode2, 0);
// A simple way to draw the wave with an ellipse at each location
for (let x = 0; x < yvalues.length; x++) {
ellipse(x * xspacing, height / 2 + yvalues[x], 16, 16);
}
}
function calcWave() {
// Increment theta (try different values for
// ‘angular velocity’ here)
theta += 0.02;
// For every x value, calculate a y value with sine function
let x = theta;
for (let i = 0; i < yvalues.length; i++) {
yvalues[i] = sin(x) * amplitude;
x += dx;
}
}
function renderWave() {
noStroke();
fill(colorcode, colorcode2, 0);
// A simple way to draw the wave with an ellipse at each location
for (let x = 0; x < yvalues.length; x++) {
rect(x * xspacing, height / 2 + yvalues[x], 16, 16);
}
}
Highlights of process documentation:
- We had such a fun time making the fake sushi and dumplings, and working with clay.
- It was nice to watch people experience the project and get feedback on how they felt after the experience.
- The set up was a bit of a challenge because there are so many wires and different elements involved.
- The p5 code was also a challenge, mapping the frequencies to the waves and making sure they correlated with the users heartbeat.
-
It was also a challenge to represent the heartbeat. We were aiming to create really complex artwork on the screen, however we soon realized that we have to simplify our idea in order to deliver the main point. So, we used waves and different frequencies of sound for our project.
If you had more time on this project, what would you improve? :
If we had more time on this project, I think we could make the set up feel electronic, meaning that we would put the projectors on the ceiling and hide the wires, so the user is not distracted by those things and just focuses on the experience. We could also work on the projection onto the table, as it was a bit off and we could have used more time to make it perfect. We could also make the code a bit more complex and experiment with different shapes and patterns to show the heartbeat, making it more seamless.
With the improvement to the project, where do you imagine this project to be installed/used?
I imagine this project being shown in some sort of public eating space, like a food court. People can take a break from actually eating, to truly focus on one another and the experience of dining with another person. I can also see this project being installed in an outdoor space, sort of like a picnic.