Assignment #4 reading response

Creative Reading Response:

I think one recurring answer for me on the topic of “difficult tech/design” would be Notion. I’ve repeatedly given myself and Notion a “second-try”, which really went on to be more than two tries, just so I can get on the “trend” and make use of all the great, highly productive, convenient, and efficient functions that it’s known for. However, it’s exactly its variety of functions that trips me over and frustrates me immensely. Whenever I’m trying to customize my pages, it’s just confusing, then I turn to templates which work for a while but then becomes confusing again when I wish to edit some features to better suit my habits and lifestyle. The “advanced” functions also made me feel “inferior” in the sense that even if I watch tutorials and follow other people in making my own templates, I just can’t seem to “figure it out” and make the experience less like untangling a yarn ball, while the other people, who are the reason I wish to use Notion, just seem like they’ve got it all figured out and under control. Talking about control, that’s also something I find really important in my experience with Notion. Oftentimes, when I’m exploring or setting up pages and links, they just suddenly become messy and “wrongly organized” and hard to “undo”, which makes me feel very “powerless” and frustrated. However I do think it could be improved, or perhaps some products are just not meant for everyone, which brings me to my opinion on what the text mentioned about how consumers shouldn’t accommodate products but rather products should accommodate consumers.

While I totally agree with this point, I also see the difficulty in juggling an advanced variety of features in the product and consumer experience. I think it’s almost like calculators, you need a certain level of “knowledge” to know how to use it and make it to the full use, like me and Notion: yes, you can stop with the basics of 1+1 but once you know there’s tools for graphs and derivatives, you just can’t help but to want more from the product and end up struggling with it. Or perhaps I‘m wrong and that Notion could in fact be better in accommodating consumers like me but who am I to say that when people are doing just fine with it. Or perhaps it’s the “peer pressure” getting to me and that people don’t actually find the experience that enjoyable but I wouldn’t know and frankly, I’m just fine without Notion.

Exploring this opinion really made me reflect on myself both personally and academically: am I too comfortable with what’s already in the “market” and am I lacking opinions in the way I see popular designs and tools? Perhaps that’s what I should learn: to have a stronger opinion, and believe that things could always be better even if they’re widely accepted, just like the unreasonable doors.

Overall, I find the text very interesting, and very closely tied to our previous reading on what’s interactive. Both made me realize the importance of “experience” and that a good design should be enjoyable. Looking back, many of the products mentioned in the text have given me a difficult time yet I never really thought about the way it could be better and in fact, what factor is lacking. I really enjoy the idea of signifiers and affordance in the way that it ties to the human mind’s “modelling”. For instance, when he mentioned the sliding doors and how the door handle in fact gave a signal of push or pull but instead worked as a slide. This made me think of how it could’ve been better so the signifier is natural and leads to discovering the affordance, and I thought perhaps it should’ve made a vertical dent where people can place their fingers to grasp and slide the door, which was a thought that surprised me and made me feel good. 🙂

Week 3 Reading Response

Creative Reading Response:

I began the reading assuming I knew how to ‘define’ interactivity, however, as the author started giving counter examples of what’s not interactive, like the fridge and the books, I began to reflect on whether I really ‘know’ how to define interactivity or do I just recognize interactivity, because knowing is very different from recognizing; the former is active and genuine understanding and the latter is passive and intuitive/ shallow understanding. Throughout the text, I was just in this cycle between contemplation and realization.

On one hand, I strongly resonated with Crawford’s metaphor of interactivity as a ‘conversation’ between the user and computer, because indeed, that’s the traits I find in successful interactive art works; the art ‘speaks’ to you, ‘listens’ to your reaction, process them and then in response, speak to you again. However, on the other hand, when he began talking about user-interface designers and graphic designers, I grew confused and began to question what he meant by integrating “form with function”. I thought of it in 2 ways: first, the shallow way, in which by function he means literal computer function where the “thinking” is supposed to happen, like in AI; second, perhaps he means every ‘form’/ ‘visual design’ is supposed to be functional in a way that contributes to the interaction. Both ways of thinking feel a bit weird, in the sense that I don’t know if artworks should ‘think’, but perhaps he wasn’t talking about art works, and I just automatically assumed so because of my experiences with art works. It would make a lot more sense if he addressed, perhaps designers, than artists, but again, artists can be designers. Overall, I think I learned a lot in terms of expanding my view on the topic of interactivity and what it really means to make my works interactive, whether as a designer or an artist.

Week 3 – Reading and OOP exercise

Reading reflection

The part of interactivity that I really agree with is that it is a scale and not a binary. I believe interactivity is a huge aspect of how technology is perceived, and I am really interested in how it shapes the relationship between the user and the technology.  I believe interactivity doesn’t needs to be physical in its nature where a user has to press a button or a widget, but it is really about how involved they feel with the technology/or any other medium of interaction. The author then speaks about how they feel that reading is not interactive. I disagree with this part, and I believe that reading is highly interactive. In an era where there is so much online material/posts/apps/games to interact with I find reading to be highly interactive and not rushed. The author also speaks about how opening a fridge door is interactive, which is an interesting approach. I believe small everyday tasks have an interesting nuance to them and how their design matters I think it is in these tasks that we actually slow down. I don’t want to be philosophical about this, but I genuinely resonate with how interaction is people based like when communicating and dancing. As a sustained dialogue ambassador, I really agree with Crawford’s stance on how communication is interactive. Like as an ambassador, I have been trained to like communicate with participants and co-facilitators without the need of speaking, and letting silence set in and genuinely listening to everyone, including listening on different levels like their body language. This is also what interactivity looks like to me, so I think it does have different aspects to it, but it all comes down to how seen the user/person feels whether it is technical or not.

Coding Exercise

My inspiration for this code was the Ikigai concept in Japanese, where it means what you pursue in life has to be at the intersection of what you like and what you the world will need. I also really like the translucent aspect of this as well, and to me it appears to be like tainted glass.

Sources for images: https://www.istockphoto.com/photos/vertical-stained-glass-window
My Program

My code

I build this through the ikigai class I defined. The part of the code, I am proud of is how I integrated the translucency.

class IkigaiCircle {
  //it runs when a new circle is made
  constructor(x, y, col, appearAt) {
    //The centre of the circle
    this.x = x;
    this.y = y;
    //Colour name into a p5 colour
    this.col = color(col);
    //  a crucial part in helping us set the color to translucent
    this.col.setAlpha(100);
    // count value when this circle appears
    this.appearAt = appearAt;
  }

I started by drawing a single circle in the middle of the canvas, then added three more to build the ikigai diagram, using see-through colours so the overlaps would blend. To make it animate, I added a counter that goes up every frame and made each circle appear only after the counter reached a certain number. Once I noticed the four circles used almost the same code, I turned them into an IkigaiCircle class and moved the colours and positions into arrays, so a loop could create all four circles for me. Finally, I changed the background from grey to cream because the grey made the colours look dull.

Week 2 – Reading reflection

From the introduction, I had the following thoughts. Reas mentions of how chaos in major events in history like prevalence of quantum mechanics and world war 1  led to shifts in art. This made me question of whether chaos around AI will lead to shifts on how art is formed and viewed. Reas then continues talking about how software art is effected by noise while I understand what noise he is referring to; I think about how noise doesn’t allow me to focus while making art and how the same word could have such different impacts and meanings.

He then mentions Valentino Braitenberg as a neuro-atomist and his work about an imaginary robot to study about cognition. I really liked the crossover between art, math, and science. I read more into these robots and found how one robot’s motion was effected by temperature actually akined to the brownian motion. I really agree with the analogy here since the motion seemed so random when Reas modeled it; it links all back to nature even the randomness.

In the Order of Art, he also talks about making art of your own and I think that is what gives art life: individualism. I really found Mondrian’s evolution in artwork very humane too since we think about life or careers in something very linear or restricted, but seeing how his style emerged along with music in NewYork is a helpful in supporting that we can change paths, decisions, and expression and that is okay.

When Reas explores Computer Graphics, he varies the randomness which changes the art pattern and then shows examples of graphics which vary with different factors. For me, I worked with noise() particularly which brings in slight order in comparison to random(). If we were to talk quantitively, I still would lean into less randomness and more structure since an increased amount of disorder takes away what I want to communicate through artwork. I don’t really think there is an optimum balance as that would keep changing from project to project, here I really resonate with Mondrian’s view of art.

Week 2 – Computer Graphics

OVERVIEW

I was taking my makeup off with a cotton ball and found the strands of cotton to be the inspiration for the compute graphic. I went over the magazines as well but nothing in particular resonated, so I browsed more examples of computer graphics. This is when I came across Perlin noise which was a technique invented by Ken Perlin while working on his film: Tron. I was also very inspired by textures and blur, and how they add such personality. Ideally I was supposed to create a similar graphic.

sourced at https://genekogan.com/code/p5js-perlin-noise/

CODE HIGHLIGHT

The major part with the code was adjusting variables, I had a similar experience with drawing eyelashes for my self-portrait.

This is the main for loop that takes the noise field and the loop reads the noise field at the current position, converts that value to an angle, then uses cos and sin to turn the angle into a step of fixed length. It draws that segment, moves to its end, and repeats.

 for (i = 0; i < 20; i++) {
        n3 = noise(oldX * resolution, oldY * resolution) + 0.045;
        angle = map(n3, 0.3, 0.7, 0, PI * 4);

        newX = cos(angle) * len + oldX;
        newY = sin(angle) * len + oldY;
        line(oldX, oldY, newX, newY);
        oldX = newX;
        oldY = newY;
}

EMBEDDED SKETCH

 

HOW THIS WAS MADE

I divided this in 3 main sections with defining the canvas first, and then the variables which I will need to vary, and then the seed grid and reading the noise field. I also used different resources for the main algorithm like https://www.youtube.com/watch?v=Qf4dIN99e2w

by coding train and a walk through by Steve’s Masterclass. I read about the noise() function on GeekforGeeks and the p5j. website. The looping logic was learnt through youtube.

Initially, 2 nested loops help to walk a path of starting positions, and then saving the grid positions. A third nested loop works by reading the noise field at current position, turning that value into an angle, converting the angle into a step of length len via cos and sin, drawing the segment, and moving to the end of it and repeat. This loop runs for 20 times which gives it a wriggling tail, and the paths curve because the noise value is re-read at every step.

Reflection and Ideas for future work

I do still find the main idea of perlin noise to be complicated. However, I am very intrigued by how many intersections this sits at right now like how it is a noise field which means it includes bunch of vectors, but at the same time they are directed in terms of direction. I think I would like to take it as close as possible to the image I have shared and maybe an animated version.

Week 2 – Generative Artwork

Concept

For this assignment, I wanted to create something that moves and looks alive using the programming concepts and techniques that I know and have learned so far. The idea that came to me was to create a weather scene showing a house during rainy weather. This idea was inspired by the difference between the weather in my home country, Fiji, where it is currently the rainy season, and Abu Dhabi, where the weather is generally very sunny. I decided to represent these two different environments in the same artwork. I used concepts like arrays, loops, Boolean variables, functions, conditionals, randomness, and animation to create a lively artwork.

Click on it!

Code I am Proud of

function draw() {
  // To draw and move the raindrops
  if (raining == true) {

    // Goes through all 100 raindrops 
    for (let i = 0; i < 100; i++) {
      // To draw the current raindrop 
      drawRainDrop(i);

      // To move the current raindrop
      moveRainDrop(i);
    }
}
// Function for drawing individual raindrop
function drawRainDrop(i) {
  fill(50, 100, 255);
  noStroke();

  // For making each raindrop
  ellipse(rainDropX[i], rainDropY[i], 5, 10);
}

// Function for moving an individual raindrop
function moveRainDrop(i) {
  rainDropY[i] += 5;

  /* If the raindrop reaches the ground, Its moved back randomly to the top with a random x position also */
  if (rainDropY[i] > 500) {
    rainDropY[i] = random(-50,0);
    rainDropX[i] = random(0, width);
  }
}

The part of the code I am most proud of is the falling rain effect. It took me several attempts and a lot of thinking to figure out how I wanted the raindrops to behave. At first, I was thinking about how I could continuously generate new raindrops while older ones were still falling. I eventually realized that I did not actually need to create completely new raindrops every time. Instead, I could create 100 raindrops and continuously reuse them by changing their positions after they reached the ground.

The arrays were important for this because they allow the program to store the position of every raindrop. The for loop then goes through all 100 raindrops and updates each one. I particularly like this approach because there are only 100 raindrops being managed, but they can continue falling and respawning throughout the entire animation. This creates the impression of continuous rain without needing to continuously create more and more objects. I am also proud of use of randomness when the raindrops respawn. If every raindrop started at exactly the same x and y position, the rain would look artificial and repetitive. Randomizing the positions makes the scene look more natural. I was able to connect this programming technique to Casey Reas’ idea of Chance Operation. Rather than using randomness just because it was useful for the animation, I was able to think about randomness as part of the artistic design of the project.

Implementation

I created arrays called rainDropX and rainDropY to store the x and y positions of the 100 raindrops. These arrays allow the program to keep track of every raindrop individually. In the setup() function, I used a for loop to create 100 raindrops and give each one a random starting position. The x-position is randomly generated across the width of the canvas, while the y-position is randomly generated across the canvas. This means that when the program starts, the raindrops are already distributed throughout the scene.

The main animation happens inside the draw() function. I used a Boolean variable called raining to determine which weather condition should be displayed. When the program starts, it shows a rainy scene, and when the mouse is clicked, the rain stops and the scene changes to a sunny one. Clicking again brings the rain back. I used a for loop to go through all 100 raindrops every frame. For each raindrop, the program calls drawRainDrop(i) to draw it and moveRainDrop(i) to move it downward. The movement of each raindrop is relatively simple. Every frame, its y-position increases by 5.

Reflection

The most challenging part was creating the falling rain, but working through it helped me better understand how arrays and loops can be used to manage multiple objects at the same time. In the future, I would like to improve the project by making the transition between rainy and sunny weather smoother, perhaps adding moving clouds and lightning, and possibly adding sound effects. I would also like to experiment more with randomness and explore how I can use programming to create more interactive and visually interesting artwork. Overall, I am happy with the project because I was able to use the programming concepts I have learned to create something animated, interactive and personal.

 

Weel 1 Self Portrait photo

During my time of creating the self-portrait, I had to use the code practice from last class for reference; the reason being that the code would allow me to remember certain commands that I ended up using to make my portrait. For example, the commands from the practice code, “// Body fill(‘orange’) rect (etc.)” allowed me to get an idea of how I can create a body for my portrait which is then followed by creating said-rectangular body. This proved to be very helpful for me because what I was aiming for within my portrait was a kind of modern look; by modern look, I mean by how in most social media platforms, some people choose to have a blank profile picture that only depicts an almost rectangular body and circular head. It may sound boring, but I personally like to think of it as a reminder of how times around the world are so drastically different than how one can imagine. Speaking of circular head, i was originally going to use the “circle()” command to create my head, until I found out that the command best suitable for the requirement is the “ellipse” command since it had proven to me that it can create a far more accurate shape of the head for me. This wasn’t the only time I replaced a shape during the whole process, because when I was creating the nose, I almost went with an oval circular shaped nose. However, some part of me felt as if it were “too clownish” to say the least; hence why i decided to go with the triangle since it just felt more respectful with the nonchalant tone that i have been trying to keep up rather than a tone similar to that of an off-brand circus. As for eyes, my original goal was to create 2 big white circles and then create 2 smaller black circles that would be placed on top of the white ones in the middle; yet I remembered the “ellipse” command and how it would prove to be a more beneficial tool if it slipped horizontally, shrinked by eye-size, and then be placed in their respective spots all while the idea of 2 smaller black circles being centralized within the 2 white sclera of the eyes remained. Lastly, with the hair, this the most difficult for me, since I could not figure out which series of commands to use in order to replicate my hair as need be. Since I am not the most experienced artist in the room, I had no choice but to go forward with the decision to create those lines of hair that perhaps would at least resemble my short bangs.

Despite the headache from all the creation of shapes after shapes, a code series that I can’t help but feel happy about is the creation of the smiling mouth that you may see in the portrait. Before the mouth was even formed, I nearly went with the idea of using the “line()” command to form my mouth and perhaps stretch upwards. But of course, I would come to realize that the lines are meant to be nothing more than straight, thus enabling as incapable of being bent/altered further. When hope seemed lost, that is when I stumbled upon the command of “arc()” from the coding’s list of references. There, I would discover how certain arcs of line in this different command can be altered just in the way I desired! Thus, that is how I was able to get the smiling mouth as you would see here in the portrait!

Despite the work being done, I do want to mention that not only did I use the code practice and the coding site’s references as my guide, but I also had ai (one that I paid for), check my work to see if I must either change a coordinate or correct a common usually wrongly. This is because I saw that through my time working, my weakness has been second-guessing certain coordinates for certain shapes for too many unnecessary times. I just could not tell which coordinate was the right way to write in order to set the shape and/or color as I wanted. Therefore, that is why for each coordinate of each part of the portrait that I write, I would share it with the AI and simply hear its advice of what I can keep and what I must modify. Even though it has helped me recognize my mistakes, it still serve as a signal for me that what I should be working on for this class is a better understanding of how shapes must be correctly positioned/modified as for each project I work on. After all, this idea of improvement should help prepare me for possibly more complex projects that require more shapes somewhere in the future.

function setup() {
  createCanvas(640, 580);
}

function draw() {
  // background set-up
  background(135, 206, 235);
  // sun at the top right corner
  noStroke();
  fill("yellow")
  circle(40,40,180);

  // Head
  fill("tan");
  ellipse(300, 300, 250, 300);

  // Body
  noStroke();
  fill("green");
  rect(210, 430, 180, 220);
  
  // Hair 
  stroke("Black");
  strokeWeight(5);

  line(260, 190, 250, 150);
  line(280, 180, 275, 140);
  line(300, 175, 300, 135);
  line(320, 175, 320, 135);
  line(340, 180, 345, 140);
  line(360, 190, 370, 150);

  // Sclera of eyes
  fill("white");
  ellipse(250, 300, 65, 38);
  ellipse(350, 300, 65, 38);

  // Pupils of the eyes
  fill("black");
  circle(250, 300, 14);
  circle(350, 300, 14);

  // Nose
  fill("brown");
  triangle(300, 320, 285, 335, 315, 355);

  // Smiling mouth
  noFill();
  stroke("black");
  strokeWeight(5);
  arc(300, 370, 90, 60, 0, PI);
}

 

Inside Your Mind – Interactive Fluid Typography Experience and User Testing

As I was experimenting with m project, I built Inside Your Mind – a second-person psychological narrative experience created in p5.js. I felt like with the creativity I developed in the class Tinkercad would not be enough to show my ideas, altough I tried to make a project on Tinkercad I did not open fully with it, so I chose to do my interactive experinec in p5. The project moves away from game mechanics and goals, and toward something more expressive and open-ended: a guided journey through four emotional stages of the mind, rendered through fluid particle typography and sound.

The experience opens with a kinetic typography intro sequence a personal greeting, a typewriter reveal, a search bar that types “inside your mind” — before transitioning into the main particle world. From there, users navigate different stages of mind, noise, overthink, break and finally silence.

User Testing

User testing was conducted with participant who experienced the full interactive sequence from the intro through all four stages. My little brother.  Participant were observed interacting freely with no instructions given beyond “explore it.”

The response was overwhelmingly positive.

Tester consistently described the experience as something they hadn’t encountered before, not a game, not a website, something in between that felt genuinely immersive. My brother spent more time in the experience than expected, going back and forth between stages to compare how the particles moved differently in each one. The fluid typography was the element that resonated most strongly. Tester were drawn to how the text was simultaneously readable and alive. The sound design was a notable highlight. Tester immediately noticed that each stage sounded different, and several remarked that the cursor sounds made the experience feel tactile, like they were touching something. The wind sound in Stage 1, the water drops in Stage 2, the glitch crackle in Stage 3, and the bell chimes in Stage 4 each reinforced the emotional tone of that chapter which made it more cohesive.

Link to user testing video: https://drive.google.com/file/d/1y8koBlJ7WqWSgiGLDeGFhjZYJn5P-0Ib/view?usp=drivesdk

Areas noted for potential refinement:

I am considering to add an introduction to the experience explaining more about the interactivness, I am inspired by motion design, lately have been watching different motion design ad proposals for brands and I enjoyed the animations, so I would want to implement it to my project by learning and applying it.

Week 14 – Final Project (PawPortion)

🐾 PawPortion🐾 Smart Pet Feeding Assistant

Concept

I started this project from a very simple everyday problem: feeding a pet on time. It sounds like something that should be easy to remember, but in real life, routines can get busy, and small responsibilities can be delayed or forgotten. I did not want to make a fully automatic feeder because that would remove the user from the process completely. Instead, I wanted to create a system that supports the user while still keeping them involved in the act of care.

PawPortion is an interactive pet feeding assistant that combines an Arduino-controlled physical feeder with a p5.js digital dashboard. The system keeps track of feeding time, reminds the user when it is time to feed, and responds when the feeding action is completed. The project is not just about dispensing food. It is about creating a clear relationship between the user, the interface, and the physical machine.

The main idea behind PawPortion is assisted responsibility. The system does not take over the task entirely, but it helps make the task more visible, structured, and responsive. The user can see when the pet was last fed, when the next feeding should happen, and whether the feeding has been missed. The pet’s mood on the screen also changes depending on the state of the system, which makes the interaction feel more emotional and less robotic.

Video of Project

Images of Project


Schematic



Assembly Instructions 


User Testing Videos

During user testing, I wanted to see whether people could understand the system without me explaining every step. The main interaction was mostly clear. Users understood that the p5 dashboard was giving them feeding information, and they were able to recognize the “Feed Now” button as the main action. Once the servo moved and food was released, the connection between the digital interface and the physical feeder became much clearer.

One important issue appeared during testing with the IR sensor. I had placed a printed image near the sensor to guide the user, but the image made some people interpret the IR sensor as a physical button. Instead of triggering it by placing something near it, they tried to press it directly. The problem was not that the sensor failed. The problem was that my visual instruction gave the wrong impression.

This taught me that physical interaction is not only about whether the circuit works. It is also about how the user reads the object. A small label, icon, or printed sign can completely change how someone understands what they are supposed to do. After seeing this confusion, I changed the printed label so it was clearer that the sensor detects presence rather than pressure. This made the interaction easier to understand and reduced the need for verbal explanation.

How Does the Implementation Work?

Description of Interaction Design

The interaction is built around a cycle between the user, p5, and Arduino. First, the p5 dashboard tracks time and displays the feeding schedule. The user can see when the pet was last fed, when the next feeding is due, and how much time is left. This makes the system readable before anything physical happens.

When feeding time arrives, the dashboard changes state. The pet becomes hungry, and the status message tells the user that it is feeding time. This is meant to guide the user instead of forcing the system to act automatically. The user then presses the “Feed Now” button on the p5 interface, which sends a command to Arduino.

Arduino receives the command and moves the servo motor. The servo acts like a small door or gate that opens to release food, then closes again. When Arduino finishes dispensing, it sends a message back to p5. After p5 receives that message, the dashboard updates the last feeding time, resets the countdown, and changes the pet’s mood to happy.

If the user does not feed within the grace period, the system marks the feeding as missed. The pet becomes sad, which makes the missed action more visible. I wanted this to feel gentle, not dramatic, but still noticeable enough that the user understands the consequence of ignoring the schedule, and that they should probably feed their pet.

Description of Arduino Code

Github Full Code

The Arduino code controls the physical side of the project. It is responsible for reading the IR sensor, controlling the servo motor, and communicating back to p5 when feeding is complete. I used named constants for the pins instead of random numbers, which makes the code easier to understand and edit later.

Snippet: defining the sensor pin, servo pin, and servo object.

#include <Servo.h>

const int SENSOR_PIN = 7;

const int SERVO_PIN  = 6;

Servo tap_servo;

The main function in the Arduino code is dispenseFood(). This function opens the servo, waits while food is released, closes the servo, and then sends “DONE” to p5. This message is important because it tells the dashboard that the physical feeding action has finished.

Snippet: the feeding function that opens the servo, closes it, and sends confirmation to p5.

void dispenseFood() {

  isDispensing = true;

  tap_servo.write(110);

  delay(2000);

  tap_servo.write(0);

  delay(300);

  lastFedTime = millis();

  isDispensing = false;

  Serial.println("DONE");

}

The Arduino also listens for serial messages from p5. When p5 sends “FEED”, Arduino immediately calls the feeding function. This is what connects the digital button to the physical movement.

Snippet: receiving the FEED command from p5.

if (Serial.available() > 0) {

  String cmd = Serial.readStringUntil('\n');

  cmd.trim();

  if (cmd == "FEED") {

    dispenseFood();

  }

}

I also added a cooldown so the IR sensor does not trigger repeatedly if something stays in front of it. Without this, the servo could keep dispensing again and again. The cooldown makes the physical interaction more controlled.

Description of p5.js Code

 

The p5.js code controls the digital dashboard. It handles the schedule, the pet mood, the buttons, and the communication with Arduino. The dashboard shows the last feeding time, the next feeding time, and a countdown. It also shows the pet’s mood, which changes depending on what is happening.

Snippet: timing values for the feeding schedule.

const FEED_INTERVAL_SEC = 60;

const MISSED_GRACE_SEC = 15;

The main schedule logic checks whether feeding time has arrived. If there is still time left, the pet stays neutral. If feeding time has arrived but is still within the grace period, the pet becomes hungry. If the grace period passes, the pet becomes sad.

Snippet: schedule logic that updates the pet mood.

if (secUntilFeed > 0) {

  petMood = "neutral";

  if (serialConnected) {

    statusMsg = "Waiting for next feeding";

  }

} else if (secUntilFeed > -MISSED_GRACE_SEC) {

  petMood = "hungry";

  statusMsg = "Feeding time!";

} else {

  petMood = "sad";

  statusMsg = "Feeding missed!";

}

When the user clicks “Feed Now,” p5 sends the word “FEED” to Arduino through serial communication. I used a newline at the end because it helps Arduino read the command as one complete message.

Snippet: sending the FEED command to Arduino.

const encoder = new TextEncoder();

const writer = port.writable.getWriter();

await writer.write(encoder.encode("FEED\n"));

writer.releaseLock();

The p5 code also listens for messages from Arduino. When it receives “DONE”, it updates the dashboard. This is what makes the interface respond only after the physical action finishes.

Snippet: checking for DONE from Arduino.

if (line === "DONE") {

  onFeedingDone();

}

I also added fullscreen functionality using the F key. This makes the dashboard easier to present during the final demo and makes it feel more like a complete interface rather than just a small sketch window. The course documentation specifically mentions fullscreen and responsive resizing as part of final project programming considerations.

Description of Communication Between Arduino and p5.js

The communication between Arduino and p5.js is one of the most important parts of the project. The system works through a two-way serial communication loop. p5 sends “FEED” to Arduino, Arduino moves the servo to dispense food, and then Arduino sends “DONE” back to p5.

This means the dashboard does not simply assume that feeding happened. It waits for Arduino to confirm that the physical action was completed. This made the project feel more reliable because the screen and the machine were connected through actual feedback.

This was also one of the hardest parts of the project because if the serial communication failed, the entire interaction felt broken. The dashboard could look fine, and the Arduino could work alone, but the project only felt complete when both sides were speaking to each other correctly.

Aspects Of The Project I’m Proud Of 

One of the strongest parts of this project is how far it goes compared to where I started at the beginning of the course. If I had seen this project in week one, I genuinely would not have believed that I could build it. It combines physical computing, serial communication, a digital dashboard, user interaction, timing logic, an animated interface, and a mechanical feeding system. That feels ambitious for me, and I am proud that I was able to execute it in a way that actually works.

I am also proud of how complete the project feels as an experience. It is not just Arduino moving a servo, and it is not just a p5 interface on a screen. The two parts depend on each other. The dashboard guides the user, the Arduino performs the physical action, and the screen updates after receiving confirmation. That connection makes the project feel like a full interactive system.

Another part that I think worked well is the personality of the interface. The pet mood makes the system feel more alive, and it helps communicate the feeding state without needing complicated instructions. The sad, hungry, happy, and resting states make the dashboard easier to understand and more engaging.

I am also proud that I improved the project through user testing. The IR sensor confusion could have been ignored, but I used it as a design lesson. Changing the printed label made the interaction clearer, which showed me that the physical design and the code are equally important.

Resources Used

p5.js

https://p5js.org/reference/ https://p5js.org/tutorials/get-started/ https://www.youtube.com/watch?v=c3TeLi6Ns1E

Serial Communication

https://itp.nyu.edu/physcomp/labs/labs-serial-communication/lab-webserial-input-to-p5-

js/https://itp.nyu.edu/physcomp/labs/labs-serial-communication/lab-webserial-output-from-p5-

js/https://makeabilitylab.github.io/physcomp/communication/p5js-serial.html

https://medium.com/@yyyyyyyuan/tutorial-serial-communication-with-arduino-and-p5-js-cd39b3ac10ce

Servo Motor

https://docs.arduino.cc/tutorials/generic/basic-servo-control/

https://learn.adafruit.com/adafruit-arduino-lesson-14-servo-motors/overview

https://www.youtube.com/watch?v=1mDnaiEytAI

IR Sensor

https://arduinogetstarted.com/tutorials/arduino-infrared-obstacle-avoidance-sensor

https://projecthub.arduino.cc/aboda243/obstacle-detector-using-ir-module-tutorial-101320

https://www.youtube.com/watch?v=vi4hkrrkwkY

https://www.youtube.com/watch?v=ESqhOKgKt5c

AI Usage

I used AI as a support tool during the development of this project. The most important use was debugging my p5.js code, especially because this was one of my first larger coding projects involving serial communication between Arduino and p5. Debugging was difficult because problems could come from the Arduino code, the p5 code, the serial connection, or the browser. AI helped me break down the problem and understand where the issue might be coming from.

AI also helped me understand how to structure parts of the p5 dashboard, especially the schedule logic, and serial communication. I still tested, adjusted, and integrated the code myself to make sure it worked with my actual Arduino setup.

if (secUntilFeed > 0) {
  petMood = "neutral";

  if (serialConnected) {
    statusMsg = "Waiting for next feeding";
  }

} else if (secUntilFeed > -MISSED_GRACE_SEC) {
  petMood = "hungry";
  statusMsg = "Feeding time!";

} else {
  petMood = "sad";
  statusMsg = "Feeding missed!";
}

I also used AI to generate visual design elements for the project, including the PawPortion logo and printable signs for the physical machine. These visuals helped make the project feel more polished and easier for users to understand.

Challenges Faced and How I Tried to Overcome Them

The biggest challenge was serial communication between Arduino and p5. This was one of the first times I worked on a larger project where hardware and software had to communicate continuously. When something did not work, it was hard to know whether the problem was in the Arduino code, the p5 code, the USB connection, or the browser’s serial port.

I overcame this by testing each part separately. First, I tested the servo on Arduino by itself. Then I tested whether p5 could connect to the Arduino. Then I tested sending one simple command. After that, I tested receiving “DONE” back from Arduino. Breaking it into smaller steps made the project less overwhelming.

Another challenge was making the interaction clear to users. The IR sensor confusion showed me that a working sensor does not automatically mean a clear interaction. Users interpreted the printed image as a button because that was the visual language I accidentally created. I fixed this by changing the label and making the physical instruction clearer.

A third challenge was making the project feel polished. Since the project includes both physical and digital parts, it needed to look intentional from both sides. I worked on the dashboard design, printable labels, and project logo so the final setup felt like one system rather than separate pieces.

Future Improvements

If I had more time, I would improve the physical build of the feeder. I would make the container more stable, the food release cleaner, and the overall structure more durable. Right now, the prototype communicates the idea, but a more refined version could look and function more like a real product.

I would also improve the interface by adding sound feedback. For example, a small sound could play when feeding time arrives, when food is dispensed, or when feeding is missed. This would make the system more noticeable and more satisfying to use.

Another future improvement would be adding more customization to the schedule. Instead of using a short demo interval, the user could choose real feeding times, like morning and evening. This would make the system more practical outside of the class demo.

I would also conduct more user testing with people who have not seen the project before. Watching how people understand the physical setup, the IR sensor, and the dashboard would help me refine the interaction even more.

Overall, I am very very proud of how far i’ve come and can confidently say that this class was a very formative step for me in my university journey and the first step to taking on my passion for Interactive Media. 

Stipend Breakdown (50$):

Total Spend: 47.92$