Grove Guardians
PROJECT TITLE – YOUR NAME – YOUR INSTRUCTOR’S NAME
Grove Guardians – Jianing Li – Gottfried Haider
CONCEPTION AND DESIGN:
With the desertification of the land becoming more and more serious, we need to alleviate this problem by planting trees. However, living in cities, we may not realize the seriousness of this problem. Therefore, we hope this project can remind us to pay attention to environmental protection. In our project, users will have four physical trees and their digital reflections. To simulate how people should make sure to protect their environments, users can win the game by caring for the trees through actions such as ensuring that they have enough light, watering them, talking to them and cleaning weeds away. Just like in a real scenario, a forest with only a few trees will eventually be eroded, so one needs to make sure that all four trees are thriving and in order to grow. Our users are going to think about why we design the project like that and they will get an idea that we need to deal with the problem of deforestation soon.
There are two parts that make up this project, physical components that are controlled by the Arduino, and digital imagery that is managed by Processing. On screen, the player will see four trees, which they will be responsible for taking care of. If they are able to successfully nurture all the trees by activating all the different components at the same time, the environment will thrive and an animation will play. If they neglect the trees, the surroundings will start by showing warnings, and if they continue to be unable to care for the plants, the tree grove will begin to die and the game will be over. In order to complete these actions, the user will need to interact with the four physical trees that contain different Arduino sensors. However, each tree has a different sensor, so the user is required to complete different tasks in order to keep the plants healthy. The sensors we plan to use in this project are the light sensor, potentiometer, sound sensor, and pressure sensor. The first tree will be attached to a pressure sensor that will simulate the concept of picking weeds that can be harmful to growing plants, for the second plant the user will rotate a potentiometer to release water in order to water plants. Then, for the third tree a light sensor will be included to stress the importance of ensuring plants receive sunlight. Lastly, as some research suggests that talking with plants can help their growth, the last plant will have a sound sensor that tasks the user to converse with the plant. The Arduino is responsible for controlling the sensors that provide data. With the data collected, through serial communication, values are sent to the processing program which dictates the images seen on the canvas screen. The digital image is a reflection of what is happening to the physical components of the project.
We created four trees using 3D printing, hoping to prompt users that each sensor corresponds to a tree. And we carved icons into the wood to remind people what each sensor means. However, on User Testing, testers had a hard time understanding what actions they needed to make. Also, they suggested that the appearance of the device could be improved. So, we made some changes. We animated the INSTRUCTION and then re-created the look in acrylic. We carved the images of the four animated trees into the plastic panels so that people could clearly know that the four trees corresponded to the four sensors. We also displayed the significance of each sensor before the game started, so that people would have a clearer idea of what the game was about. As it turned out, our improvements made sense, people did understand the rules and meaning of the game better, and at the same time, the appearance of our project improved dramatically.
FABRICATION AND PRODUCTION:
My partner and I divided up the work. I finished the code for the Arduino and then finished the framework for the Processing part. After that, I started building the look of the project. Meanwhile, my partner started drawing animations and completing the specific Processing program. The most important step for me was to learn how to use prototypes, I built prototype1 out of cardboard, then prototype2 out of wood, and the last version, prototype3, out of acrylic. It took a long time, but the quality of the work was high, and the Arduino code is relatively simple, so it didn’t take very long. Our animations are drawn with procreate, which is very simple to use. However, the Processing part of the game was very complex, and my partner put a lot of effort into it and I helped her. Since we wanted to time it at first, we realized that Processing didn’t have a delay() in the program, so we had to use millis() instead. To give the image a gradient effect, we used tint(). The code didn’t work at first and our professor did help us a lot. He introduced these super sophisticated codes to us. We used a pressure sensor, a potentiometer, a light sensor, and a sound sensor We chose them to represent for different steps in planting trees like fertilization, watering, giving sunshine, and talking to them. Actually, our origin idea was not like that. In that idea, the user can control two buttons to choose between forward and backward. A 3D printed tree will be placed in front of the person and a light sensor will be embedded in the tree. So the person can control the four virtual tree with one same physical tree, and all he can do is to use torch to cast light on it. Both my partner and I found it too boring and meaningless, so we changed it into using four different sensors to make the game more playful.
CONCLUSIONS:
We hope this installation will serve as a reminder of the problems of global warming, deforestation, and desertification. However, because this project tackles a very heavy topic, we don’t want the audience to feel too depressed or serious. Overall, we hope that the users can gain more passion and a deeper understanding of this global issue through a fun interactive game.
But there’s still one thing remains to be improved that people may not think of the topic “deforestation” when interacting with the project. During the user testing and present, we found that the users’ understanding of the project was “it’s a tres-plating game”. But they did find it fun and were satisfied with the decoration and arcade game style. “This process of conversation cycles back and forth, as an interactive process in which each participant in turn listens, thinks, and speaks.” So our project greatly align with my definition of interaction. I would like to change the setting of the game by adjusting the animations to help people understand the topic of deforestation. For example, I can use a horrible dessert as the background and putting some floating words on the screen like “it’s a horrible dessert” or “let’s reverse the condition together”. Our project really took ss lot of time and we failed to complete it before present. I think it was because we had to begin the code for Processing after the pictures were drawn. So we wasted some time waiting for the pictures. So maybe we can use some sketches to substitute the formal pictures and begin coding early. This strategy may help us to save time. But the way of using many prototypes to keep improve our projects continuously is a good thing to keep. And the sophisticated codes used in this project did impressed me and I learned how to use them.
DISASSEMBLY:
APPENDIX
import processing.video.*;
import processing.serial.*;
import processing.video.*;
Serial serialPort;
Movie myMovie;
boolean showMovie = true;
int animationDuration = 17000; // Set the duration of the animation in milliseconds
int startTime;
Movie myMovie2;
boolean showMovie2 = true;
int animationDuration2 = 14000; // Set the duration of the animation in milliseconds
int startTime2;
Movie myMovie3;
boolean showMovie3 = true;
int animationDuration3 = 14000; // Set the duration of the animation in milliseconds
int startTime3;
int NUM_OF_VALUES_FROM_ARDUINO = 4;
int arduinoValue[] = new int[NUM_OF_VALUES_FROM_ARDUINO];
PImage[] img = new PImage[13];
int state = 1; //change this to 1
void setup() {
printArray(Serial.list());
serialPort = new Serial(this, “/dev/cu.usbmodem1101”, 9600);
size(1430, 780); //canvas size
//first animation
myMovie = new Movie(this, “startanimation.mp4”);
myMovie.play();
startTime = millis(); // Record the start time of the animation
//die animation
myMovie2 = new Movie(this, “dead.mp4”);
startTime2 = millis(); // Record the start time of the second animation
//win animation
myMovie3 = new Movie(this, “win.mp4”);
startTime3 = millis(); // Record the start time of the second animation
img[0] = loadImage(“bg.PNG”);
img[1] = loadImage(“tg1.PNG”);
img[2] = loadImage(“tg2.PNG”);
img[3] = loadImage(“tg3.PNG”);
img[4] = loadImage(“tg4.PNG”);
img[5] = loadImage(“td1.PNG”);
img[6] = loadImage(“td2.PNG”);
img[7] = loadImage(“td3.PNG”);
img[8] = loadImage(“td4.PNG”);
img[9] = loadImage(“e1.PNG”);
img[10] = loadImage(“e2.PNG”);
img[11] = loadImage(“e3.PNG”);
img[12] = loadImage(“e4.PNG”);
}
void draw() {
// receive the values from Arduino
getSerialData();
if (state == 1) {
state1(); // intro video
} else if (state == 2) {
state2(); // main gameplay
} else if (state == 3) {
state3();
} else if (state == 4) {
state4();
}
}
void state1() {
if (myMovie.available()) {
myMovie.read();
}
image(myMovie, 0, 0, width, height);
if (millis() – startTime > animationDuration) {
state = 2;
}
}
float tree1health = 63;
float tree2health = 63;
float tree3health = 63;
float tree4health = 63;
float bgX = 0;
void state2() {
image(img[0], bgX-width, 0, width, height);
image(img[0], bgX, 0, width, height);
bgX = bgX + 1;
if (bgX > width) {
bgX = bgX – width;
}
image(img[5], 0, 0, width, height);
tint(255, 255, 255, map(tree1health, 0, 100, 0, 255));
image(img[1], 0, 0, width, height);
tint(255);
image(img[6], 0, 0, width, height);
tint(255, 255, 255, map(tree2health, 0, 100, 0, 255));
image(img[2], 0, 0, width, height);
tint(255);
image(img[7], 0, 0, width, height);
tint(255, 255, 255, map(tree3health, 0, 100, 0, 255));
image(img[3], 0, 0, width, height);
tint(255);
image(img[8], 0, 0, width, height);
tint(255, 255, 255, map(tree4health, 0, 100, 0, 255));
image(img[4], 0, 0, width, height);
tint(255);
//tree health
//tree 1
if (arduinoValue[0] > 200) {
tree1health = tree1health + 0.5;
} else {
tree1health = tree1health – 0.2;
}
tree1health = constrain(tree1health, 0, 100);
//println(tree1health);
//tree 2
if ((arduinoValue[1] > 300) && (arduinoValue[1] < 700)) {
tree2health = tree2health + 0.5;
} else {
tree2health = tree2health – 0.5;
}
tree2health = constrain(tree2health, 0, 100);
//tree 3
if (arduinoValue[2] > 600) {
tree3health = tree3health + 0.5;
} else {
tree3health = tree3health – 0.3;
}
tree3health = constrain(tree3health, 0, 100);
//tree 4
if (arduinoValue[3] > 13) {
tree4health = tree4health + 0.5;
} else {
tree4health = tree4health – 0.1;
}
tree4health = constrain(tree4health, 0, 100);
//exclamation points
//tree 1
if (tree1health < 50) {
image(img[9], 0, 0, width, height);
}
//tree 2
if (tree2health < 50) {
image(img[10], 0, 0, width, height);
}
//tree 3
if (tree3health < 50) {
image(img[11], 0, 0, width, height);
}
//tree 4
if (tree4health < 50) {
image(img[12], 0, 0, width, height);
}
//tree win
if ((tree1health > 90) && (tree2health > 90) && (tree3health > 90) && (tree4health > 90)) {
state = 4;
}
//tree lose
if ((tree1health < 10) && (tree2health < 10) && (tree3health < 10) && (tree4health < 10)) {
state = 3;
}
}
void state3() {
if (myMovie2.available()) {
myMovie2.read();
}
myMovie2.play();
image(myMovie2, 0, 0, width, height);
}
void state4() {
if (myMovie3.available()) {
myMovie3.read();
}
myMovie3.play();
image(myMovie3, 0, 0, width, height);
}
void mousePressed() {
// Toggle between play and pause when a key is pressed
if (myMovie.isPlaying()) {
myMovie.pause();
} else {
myMovie.play();
}
}
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++) {
arduinoValue[i] = int(serialInArray[i]);
}
}
}
}
}