Concept and Design
Our project concept is very similar to a Tamagotchi. It is essentially an alien encapsulation in a box with controls to maintain its planetary environment. Thus, you may feed the alien to make it happy. However, changing the temperature will change its behavior. Getting too close to the alien will also make it react more nervously. A goal for the project is to make the interaction with the alien fun while also trying to test its environment to observe its optimal habitat.
The final project idea was a fusion of my and my partner’s ideas. I will insert our first sketches, respectively.
Individual Sketches
Final Design
We wanted users to be able to have easy interactions with the alien. We placed all necessary buttons and mechanisms on the front or side of the black box. The transparent cover ensures that users know to reach for the buttons and switches without touching the aliens themselves.
The user testing session was helpful, with many helpful suggestions and peer recommendations. One big issue was our distance sensor, as people didn’t realize the physical distance between the body and the alien could affect the alien’s behavior. To make this function more distinct, we decided to place our project on the far edge of the table so that the distance detector could be detected more and be more noticeable. There were also many other suggestions.
Below are some notes I jotted down during the user testing.
There were many suggestions, such as adding a “feeling full” reaction after food, designing the food button to be aesthetic, randomizing the speed of the alien’s movement, etc. Considering time constraints with final exams, we could only improve a few things. We changed our screen color depending on the temperature of the slider pot, moved the screen to the back of the encapsulation to look like the two are fused, changed the distance sensor, and added some hand-drawn details to the side of the box to give a futuristic esk. These were, of course, still practical improvements. After, the project looked more attractive and put together. It also made the user experience run more smoothly.
Fabrication and Production
– Process-
Connecting buttons and sensors to Arduino: We wanted to build the body from its essential components.
Button: food
Potentiometer: temperature
(Later on, we eventually switched out the potentiometer for the siding pot because it was more intuitive to have a slider moving left to right to indicate changes in temperature than a knob.)
Distance sensor: alien reaction
Our goal on the first day was to get each component working and displaying values on the serial monitor.
Material- Arduino, breadboard, wires, button, potentiometer, slider pot, wires, resistors, distance sensor
Failures & Successes- We reviewed the lecture slides to review how to wire each component. We connected the components to the Arduino and produced values, which meant each was functional.
Map function: This was the start of the coding process, as we needed to figure out the range of values and set them to depend on each other.
Early prototyping: We carved out a basic encapsulation structure with cardboard. At the same time, we elongated our wires. With the reference of a prototype, we knew how much wire and space was required to fit everything together for the final product.
Additional Material- cardboard, tape, additional wires
Failures & Successes- We cut out a general dimensions of the box prototype. We needed to leave an opening in one of the walls to work in and out of the project easily.
Laser cutting & 3-D printing: As mentioned previously, prototyping helped us visualize the final project. That said, we could calculate exact measurements for the box, holes for wires, and sensor openings. We produced the laser cutting template on Cuttle.xyz and 3-D printing on Tinkercad.
Additional Material- None
Failures & Successes- We were skeptical when designing the alien. We wanted to smooth out the edges, but because we were going to pour over a silicone layer for its body, the smoothness did not matter anymore. We just made sure the shape of the body and the eye were prominent.
Connecting Pieces:
Additional Material- Acrylic panels
Failures & Successes- Fitting the edges of the acrylic panels, we needed to be precise. One side cracked as fitting the last piece was particularly difficult. However, it was not noticeable to the naked eye, so we did not have to replace the piece.
We had a section cut out to place a small camera, but we later decided to use the laptop camera instead. Luckily, we replaced the area with a name tag for the alien. At first, we didn’t know how to attach the button to the box so that it had support when pressing on it. We cut four holes with coinciding distances to the button legs to solve this issue. Then, we soldered the wires to the legs of the bottom and pulled through the wires. This helped to stabilize the button when pressed and did not fall into the box.
Alien Vision: Processing
Now that we have the main physical components of the Arduino, we transferred to Processing. We wanted the screen to be the vision of what the alien sees. Initially, we wanted to attach a camera with the Arduino, but we found it easier to use the laptop camera. The first two visuals to produce were for the food and temperature. For temperature, the hue of the monitor was changed between red and blue. The tint was incorporated with (cam,0,0). We first tested out this function with the position of the (mouseX, mouseY). When x=0, it was blue. When x was maximized, the tint turned red. Moving onto the feeding visuals, we downloaded PNGs of hamburgers, pizzas, and cupcakes. We wanted to set them into an array where these images could be generated randomly on the screen. However, multiple images at once were overcrowded, so we stayed with the hamburgers. Like our DVD screen recitation, we wanted our hamburgers to bounce off the side of the screen similarly. For coding, the values were set for the initial position initial speed for x and y. We can refer to the recitation coding assignment for a more detailed explanation. Still, essentially, the burgers would bounce off the screen’s sides depending on the condition’s side boundaries. We wanted the burger arrays to pop up when the button is pressed. The velocities will reverse each time the image reaches a side of the screen.
Cleaning up the code:
There were edits to the code as the servo motor needed to be attached to the Arduino. Then, we finally move on to the distance sensor. We set a conditional for the distance sensor to detect different ranges of distances. At different speeds, we essentially had a slow and fast. It is meant for the user to feel like there is a range in the effect of distances on the alien’s speed of movement.
Slow: 20-50
Fast: 0-20
The servo motor was set to the conditional at which it will work under the sweep function. Something to add: to make the sweep faster, we needed to decrease the delay time. As well. The angle of the sweep was increased to display greater movement. Next, the three values from the button, distance, and the sliding pot were sent to the Arduino. Lastly, the processing code was modified to replace the button press for burgers with the digital values from the button connected to processing. Then, the x coordinated controlling the tint was replaced by mapping the analog Arduino values.
Final Touchups:
Silicone mold: flexible silicone mold 1:1 ratio of each solution
- We had to wait 2-3 hours between each layer to thicken the silicone. We were worried the thickness would not be enough, but after thoroughly drying, it was perfect. Another concern we had was the weight of the silicone, as our servo motor cannot hold much weight on its axis. However, the alien mold sat fine.
Detailing: red and blue indicators for temperature, futuristic design across the top cover
- Indicators were helpful for users to identify the functionality of the slider.
We propped up the 3-D printed alien so that it would drip down every time we poured the silicone. The cleaning process was easy as this particular silicone was soft. The bottom extra silicone was easy to remove as well. Once dried, we painted the alien a pink color.
To connect the alien mold to the servo motor, we cut out a small triangle that was hot glued onto the servo motor hinge. Then, we stuffed the alien cotton. Now, placing the alien on the servo motor will create movement. Regarding the servo motor, we encountered a major issue with this. The sweeping motion was not smooth. This was because the sweeping was initially controlled by the delays. We later changed it to be controlled to be controlled by sin functions, which solved this rigid movement.
You may also notice the two sounds used in the slider pot. From values 0 to 1023, each maximum had a different sound for hot and cold. Another sound file was for the feeding sounds.
Finally, the last touch-up created an eye shape on the processing to make the screen look like it was from the alien’s perspective. We did this by importing a black outline/cutout of an eye shape, which was attached at the end of the Processing code.
Work Process (Coding)
Arduino:
int buttonstate; //hold button state for food
int temperature = A1;
int food = 2;
int light = A0;
//below is variavles for distance sesnor
const int trigPin = 9;
const int echoPin = 10;
// defines variables
long duration;
int distance;
// servo setup
#include <Servo.h>
Servo myservo;
int pos = 0;
void setup() {
Serial.begin(9600);
pinMode(2, INPUT); //void set up for button
pinMode(light, INPUT); //void set up sliding potentiometer
// void set up for distance sensor
pinMode(trigPin, OUTPUT); // Sets the trigPin as an Output
pinMode(echoPin, INPUT); // Sets the echoPin as an Input
// set up for servo position
myservo.attach(8);
}
float sinAngle = 0.0;
void loop() {
// Code for reading food state
buttonstate = digitalRead(food);
//Serial.print(“button:”);
//Serial.println(buttonstate);
//delay(1);
// Code for reading temperature state
int sensorValue = analogRead(temperature);
//Serial.print(“meter:”);
//Serial.println(sensorValue);
//delay(1);
// Code for reading Light states
int value_slide_pot_a = analogRead(light);
//Serial.print(“Slide Pot value: “);
//Serial.println(value_slide_pot_a);
//delay(1);
//code for reading distance
// Clears the trigPin
digitalWrite(trigPin, LOW);
delayMicroseconds(2);
// Sets the trigPin on HIGH state for 10 micro seconds
digitalWrite(trigPin, HIGH);
delayMicroseconds(10);
digitalWrite(trigPin, LOW);
// Reads the echoPin, returns the sound wave travel time in microseconds
duration = pulseIn(echoPin, HIGH);
// Calculating the distance
distance = duration * 0.034 / 2;
// Prints the distance on the Serial Monitor
//Serial.print(“Distance: “);
//Serial.println(distance);
// max distance is 557
Serial.print(buttonstate);
Serial.print(“,”); // put comma between sensor values
Serial.print(sensorValue);
Serial.print(“,”);
Serial.print(value_slide_pot_a);
Serial.println();
if(distance <= 200 && distance >= 20){
sinAngle = sinAngle + 0.02;
/*
for (pos = 0; pos <= 20; pos += 1) { // goes from 0 degrees to 20 degrees
// in steps of 1 degree
myservo.write(pos); // tell servo to go to position in variable ‘pos’
delay(30); // waits 15 ms for the servo to reach the position
}
for (pos = 20; pos >= 0; pos -= 1) { // goes from 20 degrees to 0 degrees
myservo.write(pos); // tell servo to go to position in variable ‘pos’
delay(30); // waits 15 ms for the servo to reach the position
}
*/
}elseif(distance < 20){
sinAngle = sinAngle + 0.1;
/*
for (pos = 0; pos <= 35; pos += 1) { // goes from 0 degrees to 35 degrees
// in steps of 1 degree
myservo.write(pos); // tell servo to go to position in variable ‘pos’
delay(10); // waits 10 ms for the servo to reach the position
}
for (pos = 35; pos >= 0; pos -= 1) { // goes from 35 degrees to 0 degrees
myservo.write(pos); // tell servo to go to position in variable ‘pos’
delay(10); // waits 10 ms for the servo to reach the position
}
*/
}else{
sinAngle = sinAngle + 0.01;
/*
for (pos = 0; pos <= 10; pos += 1) { // goes from 0 degrees to 10 degrees
// in steps of 1 degree
myservo.write(pos); // tell servo to go to position in variable ‘pos’
delay(100); // waits 15 ms for the servo to reach the position
}
for (pos = 10; pos >= 0; pos -= 1) { // goes from 10 degrees to 0 degrees
myservo.write(pos); // tell servo to go to position in variable ‘pos’
delay(100); // waits 20 ms for the servo to reach the position
}
*/
}
int servoAngle = (int)(90.0 + sin(sinAngle) * 30.0);
myservo.write(servoAngle);
//Serial.println(servoAngle);
delay(10);
}
Processing:
//import arduino values
import processing.serial.*;
Serial serialPort;
int NUM_OF_VALUES_FROM_ARDUINO = 3; /* CHANGE THIS ACCORDING TO YOUR PROJECT */
/* This array stores values from Arduino */
int arduino_values[] = new int[NUM_OF_VALUES_FROM_ARDUINO];
//capture webcam footage
import processing.video.*;
String[] cameras = Capture.list();
Capture cam;
// insert sound
import processing.sound.*;
SoundFile yummy;
SoundFile hot;
SoundFile cold;
//importing images of food
PImage photo;
PImage img;
//food bouncing array
int numFood = 10;
float [] triXs = new float [numFood];
float [] triYs = new float [numFood];
float [] speedXs = new float [numFood];
float [] speedYs = new float [numFood];
void setup() {
size(640, 480);
background(0);
cam = new Capture(this, cameras[0]);
cam.start();
for (int i=0; i<numFood; i=i+1) {
triXs[i] = random(0,640);
triYs[i] = random(0,480);
speedXs[i] = random(-7,7);
speedYs[i] = random(-7,7);
}
photo = loadImage(“burger.png”);
img = loadImage(“eyehole.png”);
printArray(Serial.list());
// put the name of the serial port your Arduino is connected
// to in the line below – this should be the same as you’re
// using in the “Port” menu in the Arduino IDE
serialPort = new Serial(this, “/dev/cu.usbmodem11201”, 9600);
yummy = new SoundFile(this, “yummy.wav”);
hot = new SoundFile(this, “hot.wav”);
cold = new SoundFile(this, “Brrr.mp3”);
}
void draw() {
background(0);
//trying to rotate
//translate(width/2, height/2);
//rotate(radians(-180));
pushMatrix();
translate(cam.width,0);
scale(-1,1); // You had it right!
image(cam,0,0);
popMatrix();
// receive the values from Arduino
getSerialData();
if (cam.available()) {
cam.read();
}
//change color of footage
tint(map(arduino_values[2],1023,0,100,255), map(arduino_values[2], 0, 1023, 100, 255), map(arduino_values[2], 0, 1023, 100, 255), 255);
//image(cam, 0, 0);
if (arduino_values[2] == 0) {
if (hot.isPlaying() == false) {
// start playing it
hot.play();
}
}
if (arduino_values[2] == 1023) {
if (cold.isPlaying() == false) {
// start playing it
cold.play();
}
}
//bouncing burgers
if (arduino_values[0] == 1 ) {
// if the sound is not already playing
if (yummy.isPlaying() == false) {
// start playing it
yummy.play();
}
for (int i=0; i<numFood; i=i+1) {
image(photo, triXs[i],triYs[i],photo.width/3,photo.height/3);
triXs[i] = triXs[i] + speedXs[i];
triYs[i] = triYs[i] + speedYs[i];
if(triXs[i] > 580 || triXs[i] < 0) {
speedXs[i]=-speedXs[i];
} if (triYs[i] > 400 || triYs[i] < 0) {
speedYs[i]=-speedYs[i];
}
}
}
image(img, 0,0,640,480);
println(arduino_values[0]);
println(arduino_values[1]);
println(arduino_values[2]);
}
// the helper function below receives the values from Arduino
// in the “arduino_values” array from a connected Arduino
// running the “serial_AtoP_arduino” sketch
// (You won’t need to change this code.)
void getSerialData() {
while (serialPort.available() > 0) {
String in = serialPort.readStringUntil( 10 ); // 10 = ‘\n’ Linefeed in ASCII
if (in != null) {
print(“From Arduino: ” + in);
String[] serialInArray = split(trim(in), “,”);
if (serialInArray.length == NUM_OF_VALUES_FROM_ARDUINO) {
for (int i=0; i<serialInArray.length; i++) {
arduino_values[i] = int(serialInArray[i]);
}
}
}
}
}
Conclusion
The goal of the project was to create an interactive alien. Through manipulating tools, you can see how different factors contribute to its environment in the encapsulation. This project achieved our goals because it has multiple physical components: button, distance sensor, slider, and servo motor. Having multiple interactive pieces in the project is important for the user experience. Too much could be confusing, so making the project look clean and simple was the right move. The visual aspect of the detailing was also appealing. We drew the futuristic tech prints on the side, created the alien with silicone, and created a class case cover. Our users complimented the aesthetics. The interactions with the alien were mostly successful. Some people were confused by the distance sensor, possibly because the distance was already so close to the user, so there wasn’t much change in reaction from the alien’s servo motor. Otherwise, the interactions have been successful as the components were straightforward in their design. A button is pressed, and a slider needs to be moved.
Our project aligns with the definition of interaction because it is the interaction between humans and technology. The interaction is fun and exciting while learning how to change the alien’s environment. If we had more time, we would have tried incorporating the different food PNGs into the food button. The randomized images would have looked more fun. To design better, we should label the button and distance sensor for functionality.
The laptop camera display could look better if connected to a separate monitor or iPad. Lastly, to improve the project, we could have added a “full” bar for the food to create an end reaction. That way, your users have a goal when manipulating the components. Or, we could even have users be challenged to adjust the environment to the preferred habitat of the alien.
Building this project requires us to apply much knowledge from lectures and fuse it with our creativity. It was a fun yet strenuous task. Through the successes and failures, I’ve learned to prioritize time management. Finals week forced me to optimize my time usage with each course. At the same time, I should also be trying to maximize my potential. All in all, it’s all about being efficient with your resources. I am happy with how the project came to be. I am satisfied with the results and had fun along the way!
Disassembly
Appendix
The rest of the photos and videos can be found under here!
Google Drive Folder: Final Project
Citations
https://docs.google.com/document/d/1T47iQdFmL0VRU0n3F4-hnlN-dyB6WBlI2jsQan90yKc/edit?usp=sharing