As we were approaching the end of the semester, it was time for me and my classmates to think about our final projects. I really wanted to come up with something impressive that resonates with my persona. Obviously I desired to “go all out” for my final Interaction Lab project under our professor Rodolfo Cossovich. I have been thinking quite a lot about various ideas, as I wanted my project to create a great experience for both me – the creator – and the future users.
The origin of my idea is actually a bit funny. Around the end of March, I kept on having dreams about a pig, for about a week straight. In these dreams, I would basically be an owner of a pig, so I was taking care of it, as if that was a lap dog. I started researching on the internet, “what does a pig in a dream symbolize?”. The internet told me that it symbolizes incoming wealth and happiness, or pregnancy. I am still hoping for that wealth and happiness!
One day, during one of my classes, I had a bit of free time, so I drew a cute drawing of a little piglet, purely out of boredom.
I thought to myself, “That is a pretty cute drawing”. At this moment an idea popped into my mind. I decided that I want to draw an animation for my Final Project. I knew that I had to make it interactive, so that the user can also have fun with it. I wanted to create a game – The Piggy Game. I started with a concept. I wanted to connect emotions and enjoyment. Based on my dream the user would be supposed to take care of a cute piggy. It reminded me of an old game that I used to play when I was in primary school – a game called “Pou”, where I was supposed to take care of a little creature. I think that concept is really cute and nostalgic, I was sure that this experience would make future users feel sentimental and endeared. Taking care of cute animals brings everyone lots of positive emotions and feelings such as happiness, love, tenderness, fondness and affection.
When it comes to the technical side of the project it was much more difficult. I started with drawing an animation, which took me much longer than I estimated it would. I originally planned to draw three scenes: 1) Feeding the Hungry Piggy, 2) Washing the Piggy after it got dirty and 3) Putting the Piggy to sleep. I used the program Flipaclip and drew the animation on my iPad. I settled on two first scenes, as drawing them took me around 12 hours. Then, I came up with the idea on how the user is supposed to actually interact with the animated pig, and actually “take care” of it. I thought about installing two sensors – Magnet Sensor and Moisture Sensor. I really wanted to create a feeling of “feeding” and “washing” the pig, so it felt more natural. I wired up the sensors on my breadboard and created a code on Arduino. Magnet sensor was cooperating really well with me, the moisture sensor however, was actually bringing me lots of troubles. I tried “playing with values” in my code multiple times, to test its sensitivity. I wanted to put it into a laser-cut box with sponges inside, so the user pours the water in the box to “wash” the pig when it asks to. After a conversation with Professor Rudi, I realized that it might not be a good idea. Not only was that really problematic, as the level of water in the box was difficult to control, but it also did not have the sensation of “washing” the piggy.
I changed it the way the user has to manually “wash” the moisture sensor with a damp sponge. Afterwards I covered the sensor under the piggy’s bum, so it looks (and feels) as if the user was washing the pig through rubbing it. After a couple of tests with different values it finally worked out. The magnet sensor was working from the beginning. Later I changed the appearance of the magnet so it looked more like an apple, by covering it with tape, and gluing down a red coloring paper piece, as well as an apple tail from green flexible wire. Finally, my idea was slowly assembled. I divided my animation into three videos: 1) The Piggy gets hungry and asks for food, this is the moment when the user is supposed to bring the apple-shaped magnet to the sensor to feed it, after they do so, the second video starts playing 2) The piggy is happy because it has just been fed, however in the animation it starts raining, so the piggy gets dirty and asks the user to wash it, now the user is supposed to take the damp sponge and rub it on the moisture sensor to wash the piggy, 3) The third video starts playing where the piglet is being washed and it finally thanks the user for their help.
During the User Testing, only half of my project worked, as I still had to make corrections in my Processing code. Moreover I still had to make my project look aesthetically pleasing and create a scenery with the help of a laser-cutter.
The code in Processing was a real struggle. At first, there was no cooperation between the arduino code and the latter one. It was as if the moisture sensor was not working properly, or the values were completely off, it turned out that the values were, in fact, too drastic for the level of moisture. I got help from Professor Rudi and changed them into smaller ones. Then another struggle came on my way, as the third video suddenly stopped working. Even though it was downloaded, edited and shared in the same way as another two, and was in the same format. I was losing hope as I had no idea how that was possible or what the problem was. I booked an appointment with our Learning Assistant – Shengli, to seek help. However, after fighting with all possible options we were still hopeless. After pondering for a while, I thought about the simplest solution that requires no computer/programming related knowledge – I sent the third video to myself on messenger and downloaded it on there. I replaced the errored video with the new version and changed the values with the new name of the new video. THAT WORKED. I actually felt euphoria and relief. I will paste the codes from both Arduino and Processing below.
Now I could take on the challenge of designing the elements of my scenery. Firstly, I have to mention that I decided to name the Piggy Panger as it is a combination of english and chinese, as pang (胖)in chinese means “fat”. I designed parts of what was supposed to be a barn or a stable for Panger (that barn was also supposed to hide my computer, which would display the animation) in cuttle.xyz. I also decided to make parts to cover my laptop keyboard, and arduino with the breadboard to make the whole thing look even more aesthetically pleasing. After designing them, I used the laser cutter to cut the parts from the plywood. I assembled them, hot glued them and then painted them in baby pink color, to match the piggy.
The last element was making adjustments. I added the subtitles on some parts to make it easier for the user to find the elements and to instruct them what they should do. I placed the “apple” in a visible place and decorated it a bit. I wanted everything to look beautiful for the Final Presentation, during which I was extremely nervous, even though I felt really proud of my creation, and I knew how hard I worked to make it happen. Fantastically, the feedback I got was really positive and made me feel really appreciated. I loved how everything looked and I think everybody did too.
Reflecting on the journey of my Interaction Lab project under Professor Rodolfo Cossovich’s guidance, I can’t help but feel immensely grateful for the experience. This project pushed me beyond my boundaries, challenging me to think creatively and problem-solve in ways I hadn’t before. The process of bringing my idea to life taught me invaluable lessons about persistence, adaptability, and the joy of creation.Through this project, I not only honed technical skills like animation, sensor integration, and coding but also learned the importance of user experience and storytelling. The journey from conceptualizing a dream-inspired idea to troubleshooting technical problems was both exhilarating and rewarding. The Interaction Lab experience significantly boosted my confidence in my creative abilities. I found myself exploring new avenues of expression and discovering a passion for blending technology with art to evoke emotions and engage users. This journey has left a lasting impact on me, shaping me into a more versatile and resilient creator. I am deeply thankful for the support and guidance I received from Professor Cossovich, our Learning Assistants, and my classmates throughout this project. Their feedback, encouragement, and insights were instrumental in refining my vision and overcoming challenges. As I reflect on this experience, I am filled with gratitude for the opportunity to learn, grow, and create something meaningful. The Interaction Lab has not only equipped me with technical skills but also instilled in me a sense of confidence and curiosity to continue exploring the limitless possibilities at the intersection of art, technology, and human interaction.
Here is my Arduino Code:
const int moisturePin = A0; const int magneticSensorPin = 2; int moistureState; void setup() { // put your setup code here, to run once: Serial.begin(9600); pinMode(moisturePin, INPUT); pinMode(magneticSensorPin, INPUT); } void loop() { // put your main code here, to run repeatedly: int moistureValue = analogRead(moisturePin); int magneticSensorValue = digitalRead(magneticSensorPin); Serial.print(magneticSensorValue); Serial.print(","); Serial.print(moistureValue); Serial.println(); delay(50); }
Here is my Processing Code:
import processing.video.*; import processing.serial.*; Movie PangerAnimation1, PangerAnimation2; Movie PangerAnimation3; Serial serialPort; int NUM_OF_VALUES_FROM_ARDUINO = 2; /* This array stores values from Arduino */ int arduino_values[] = new int[NUM_OF_VALUES_FROM_ARDUINO]; int currentState = 0; int refMoistureValue = 0; int moistureState; // ARD_VALS NAMES: v1 = magnet V2 = moisture pin //ard_vals: v1 v2 void setup() { size(1280, 720); //fullScreen(); PangerAnimation1 = new Movie(this, "PangerAnimation1.MOV"); PangerAnimation2 = new Movie(this, "PangerAnimation2.MOV"); PangerAnimation3 = new Movie(this, "Animation3.mp4"); //PangerAnimation1.loop(); //PangerAnimation2.loop(); //PangerAnimation3.loop(); serialPort = new Serial(this, "COM5", 9600); } void draw() { getSerialData(); background(0); // println("Current state " + currentState); refMoistureValue = arduino_values[1]; if (currentState == 0) { // first video if (arduino_values[0] > 0) { //(arduino_values[1] >= 600) { currentState = 1; //we move to video 2 //println("Reference moisture value is " + refMoistureValue + ", going to state 1"); } else { PangerAnimation1.loop(); image(PangerAnimation1, 0, 0); } } else if (currentState == 1) { // second video if (arduino_values[1] > 150 ) { // ADD THIS TO () && arduino_values[1] >= 200 //if (arduino_values[0] <= 0 && moistureState == 1 ) { println("Moving to state 2"); delay(500); // refMoistureValue = arduino_values[1]; currentState = 2; } else { PangerAnimation2.loop(); image(PangerAnimation2, 0, 0); //pushMatrix(); //translate(width/2, height/2); // rotate(radians(90)); //image(myvideo2, -myvideo2.width/3, -myvideo2.height/3, myvideo2.width/1.5, myvideo2.height/1.5); // popMatrix(); } // } else if (currentState == 2) { // second video // if (PangerAnimation2.available()) { // PangerAnimation2.read(); // } // pushMatrix(); // translate(width/2, height/2); // rotate(radians(90)); // image(myvideo2, -myvideo2.width/3, -myvideo2.height/3, myvideo2.width/1.5, myvideo2.height/1.5); // popMatrix(); } else if (currentState == 2) { if (arduino_values[0] == 0 ) { println("Moving to state 3"); currentState = 3; } else { //PangerAnimation3.loop(); //image(PangerAnimation3, 0, 0); //pushMatrix(); // translate(width/2, height/2); //rotate(radians(90)); // image(myvideo3, -myvideo3.width/3, -myvideo3.height/3, myvideo3.width/1.5, myvideo3.height/1.5); // popMatrix(); } } else if (currentState == 3) { // if(PangerAnimation3.available()){ PangerAnimation3.loop(); image(PangerAnimation3, 0, 0, 1280, 720); // PangerAnimation3.resize(1280, 720); // } // third video // myvideo4.play(); // pushMatrix(); // translate(width/2, height/2); // rotate(radians(90)); //image(myvideo4, -myvideo4.width/3, -myvideo4.height/3, myvideo4.width/1.5, myvideo4.height/1.5); // popMatrix(); } } void movieEvent(Movie m) { m.read(); } 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]); } } } } }