Week 11 – In Class Practice

The following are the p5 codes and the Arduino code for the  exercises that we had done in class. I have used a potentiometer as my sensor.

Exercise 1 :
P5 Code

let serial;
let xPos = 0;

function setup() {
  createCanvas(800, 400);

  // Initialize serial
  serial = new p5.WebSerial();
  serial.open(); // Opens serial connection

  // Listen for incoming data
  serial.on("data", serialEvent);
}

function draw() {
  background(220);
  ellipse(xPos, height / 2, 50, 50);
}

function serialEvent() {
  let data = serial.readLine(); // Read data from Arduino
  if (data.length > 0) {
    xPos = map(Number(data), 0, 1023, 0, width); // Map sensor value to canvas width
  }
}

Arduino Code

int potPin = A0;

void setup() {
  Serial.begin(9600);
}

void loop() {
  int potValue = analogRead(potPin);
  Serial.println(potValue); // Send value to p5.js
  delay(10);
}

Exercise 2:
P5 Code

let serial;
let brightness = 0;

function setup() {
  createCanvas(400, 200);

  // Initialize serial
  serial = new p5.WebSerial();
  serial.open(); // Opens serial connection
}

function draw() {
  background(220);
  brightness = map(mouseX, 0, width, 0, 255); // Map mouse position to brightness
  serial.write(brightness + "\n"); // Send brightness to Arduino
  fill(0);
  text("Brightness: " + brightness, 10, 20);
}

Arduino Code

int ledPin = 9;

void setup() {
  pinMode(ledPin, OUTPUT);
  Serial.begin(9600);
}

void loop() {
  if (Serial.available() > 0) {
    int brightness = Serial.parseInt();
    analogWrite(ledPin, brightness); // Set LED brightness
  }
}

Exercise 3:
P5 Code

let serial;
let balls = [];
let wind = 0;

function setup() {
  createCanvas(400, 400);
  serial = new p5.WebSerial();
  serial.open();

  // Initialize balls
  for (let i = 0; i < 10; i++) {
    balls.push(new Ball(random(width), random(height / 2)));
  }

  serial.on("data", serialEvent);
}

function draw() {
  background(220);
  for (let ball of balls) {
    ball.applyForce(createVector(wind, 0.1)); // Apply wind
    ball.update();
    ball.display();
    if (ball.isBouncing()) {
      serial.write("bounce\n"); // Send bounce signal to Arduino
    }
  }
}

function serialEvent() {
  let data = serial.readLine();
  if (data.length > 0) {
    wind = map(Number(data), 0, 1023, -0.2, 0.2); // Map sensor value to wind
  }
}

class Ball {
  constructor(x, y) {
    this.pos = createVector(x, y);
    this.vel = createVector(0, 0);
    this.acc = createVector(0, 0);
    this.r = 10;
  }

  applyForce(force) {
    this.acc.add(force);
  }

  update() {
    this.vel.add(this.acc);
    this.pos.add(this.vel);
    this.acc.set(0, 0);

    // Check for bounce
    if (this.pos.y > height - this.r) {
      this.pos.y = height - this.r;
      this.vel.y *= -0.8; // Reverse and reduce velocity
    }
  }

  display() {
    ellipse(this.pos.x, this.pos.y, this.r * 2);
  }

  isBouncing() {
    return this.pos.y >= height - this.r;
  }
}

Arduino Code

int sensorPin = A0;
int ledPin = 13;

void setup() {
  pinMode(ledPin, OUTPUT);
  Serial.begin(9600);
}

void loop() {
  int sensorValue = analogRead(sensorPin);
  Serial.println(sensorValue); // Send sensor value to p5.js

  // Toggle LED for bounce feedback
  digitalWrite(ledPin, HIGH);
  delay(100);
  digitalWrite(ledPin, LOW);
}

 

 

FINAL PROJECT IDEA

For my Final project, I am still unsure of what I want to do. However, something came to mind that I think is a cool concept. I want to create an Interactive mood lamp with music integration.  So basically, the lamp changes colors and plays music based on the user’s actions and mood. The project will integrate the Arduino for a sensor-based interaction and P5 for a visual interface. For now I’m thinking of having 3 modes:

    • Mode 1: Calm (ambient sounds and soft colors).
    • Mode 2: Party (dynamic colors and upbeat music).
    • Mode 3: Focus (single-color light with lo-fi beats).

For the P5 visualization, which I’m still unsure if I’ll keep it this way, I might do a real-time visualization of soundwaves and color patterns that mirrors the lamp’s output on a screen.

A mood lamp for your reference:

mood lamp

For the design im planning to do something similar. I want to input the LEDs from the Arduino inside, like a lamp jar, to give. the aesthetic of the mood lamp, I still need to look into this more and see if there are other ways to do this.

Week 11: In-class Activity (by Taskin & Zavier)

# Jump To:


# Introduction

Hi there! 👋

These are a few in-class activities Taskin and I did this week (and had to post), resolving around serial communication between p5 and Arduino.

# Exercise 1: Arduino Affecting p5

 

Task:

“Make something that uses only one sensor on Arduino and makes the ellipse in p5 move on the horizontal axis, in the middle of the screen, and nothing on arduino is controlled by p5.”

 

Code:
Arduino:
 
void setup() {
	Serial.begin(9600);
	pinMode(A0, INPUT);
}

void loop() {
	Serial.println(analogRead(A0));
	delay(10);
}
 
p5:
 
let xPos = 0;

function setup() {
	createCanvas(600, 600);
	noFill();
}

function draw() {
	background(32, 64);
	
	stroke("white")

	ellipse(map(xPos, 0, 1023, 0, width), height/2, 100, 100);
	
	// Turn the screen red to make it very clear that we aren't connected to the Arduino
	if (!serialActive)
		background(128, 0, 0);
}

function keyPressed() {
	if (key == " ")
		setUpSerial(); // Start the serial connection
}

function readSerial(data) {
	if (data != null) // Ensure there's actually data
		xPos = int(data);
}			
 

 

# Exercise 2: p5 Affecting Arduino

 

Task:

“Make something that controls the LED brightness from p5.”

 

Code:
Arduino:
 
void setup() {
	Serial.begin(9600);
	pinMode(3, OUTPUT);
}

void loop() {
	analogWrite(3, Serial.parseInt());
	Serial.println();
	delay(10);
}
 
p5:
 
let xPos = 0;
let LEDBrightness = 0; // 0 - 255

function setup() {
	createCanvas(600, 600);
}

function draw() {
	if (keyIsDown(UP_ARROW) && LEDBrightness < 255) LEDBrightness += 1; else if (keyIsDown(DOWN_ARROW) && LEDBrightness > 0)
		LEDBrightness -= 1;
	
	// Just a visual indicator of the brightness level on p5
	background(LEDBrightness);
	fill(LEDBrightness < 128 ? 'white' : 'black')
	text(LEDBrightness, 25, 25);
	
	// Turn the screen red to make it very clear that we aren't connected to the Arduino
	if (!serialActive)
		background(128, 0, 0);
}

function keyPressed() {
	if (key == " ")
		setUpSerial(); // Start the serial connection
}

function readSerial(data) {
	writeSerial(LEDBrightness);
}
 

 

# Exercise 3: Arduino and p5 Affecting Each Other

 

Task:

“Take the gravity wind example and make it so every time the ball bounces one led lights up and then turns off, and you can control the wind from one analog sensor.”

 

Code:
Arduino:
 
const int LED_PIN = 3;
const int POT_PIN = A0;

void setup() {
	Serial.begin(9600);
	pinMode(LED_PIN, OUTPUT);
	pinMode(POT_PIN, INPUT);

	// Start the handshake
	while (Serial.available() <= 0) {
		Serial.println("0"); // Send a starting message
		delay(300); // Wait ~1/3 second
	}
}

void loop() {
	while (Serial.available()) {
		int LEDState = Serial.parseInt(); // 0 or 1
		
		if (Serial.read() == '\n') {
			digitalWrite(LED_PIN, LEDState);
			Serial.println(analogRead(POT_PIN));
		}
	}
}
 
p5:
 
let position, velocity, acceleration, gravity, wind; // vectors
let drag = 0.99, mass = 50, hasBounced = false;

function setup() {
	createCanvas(640, 360);
	noFill();
	position = createVector(width/2, 0);
	velocity = createVector(0,0);
	acceleration = createVector(0,0);
	gravity = createVector(0, 0.5*mass);
	wind = createVector(0,0);
	
	textAlign(CENTER);
	textSize(18);
}

function draw() {
	background(255);
	applyForce(wind);
	applyForce(gravity);
	velocity.add(acceleration);
	velocity.mult(drag);
	position.add(velocity);
	acceleration.mult(0);
	fill(hasBounced ? 'green' : 'white')
	ellipse(position.x,position.y,mass,mass);
	if (position.y > height-mass/2) {
		velocity.y *= -0.9;  // A little dampening when hitting the bottom
		position.y = height-mass/2;
		
		if (!hasBounced && abs(velocity.y) > 1) {
			hasBounced = true;
			setTimeout(() => hasBounced = false, 100); // Set hasBounced to false after 0.1 s
		}
	}  
	
	if (!serialActive) {
		background(8);
		fill('white');
		text("Press c to connect to the Arduino", width/2, height/2)
	}
}

function applyForce(force){
	// Newton's 2nd law: F = M * A
	// or A = F / M
	let f = p5.Vector.div(force, mass);
	acceleration.add(f);
}

function keyPressed(){
	if (key == ' '){
		mass = random(15,80);
		position.set(width/2, -mass);
		velocity.mult(0);
		gravity.y = 0.5*mass;
		wind.mult(0);
		
	} else if (key == 'c') {
		setUpSerial(); // Start the serial connection
	}
}

function readSerial(data) {
	if (data != null) { // Ensure there's actually data
		wind.x = map(int(data), 0, 1023, -2, 2);
		writeSerial((hasBounced ? 1 : 0) + '\n');
	}
}
 

 

Circuit:

 

Demo:

Reading Reflection – Week #11

Design Meets Disability is an extremely captivating piece that raised interesting questions for me to contemplate. I find the first example, with glasses, to be the most compelling, as it illustrates that design is a necessary component even for seemingly medical tools and devices. It is surprising to learn that glasses were initially not intended to be styled at all, whereas nowadays they belong to their own branch of fashion. The fact that glasses are not simply used but worn gives them importance from a different perspective: as a social tool rather than purely a medical one. Similarly, design is critical for various prosthetics, and each one of them has its own specifics. Unlike glasses, prosthetics are integrations of the body, a crucial factor for designers to consider.

The text also touches upon the universality of design, a concept I approach with caution. While design can aim for inclusivity, I don’t believe a single design can ever accommodate everyone at once. This goal is elusive and should not be the designer’s primary focus. It was interesting to point out two different approaches to “universality” in design: one that tries to include everything so it works for everyone, and another that, on the contrary, makes the design as simplistic as possible to ensure it is universally straightforward to use.

Both methods are quite problematic, and the task of a good designer is to situate their work somewhere in between these two extremes. However, what is certain is that universality should not be the primary goal of design; simplicity should be valued above all. I agree with the text’s author that good design is not only about how an object looks but, more importantly, about how it works, as Steve Jobs aptly stated. This principle applies to everything, from iPod to an arm prosthetic.

Week 11 – In-Class Practice

Following codes are built upon the bidi serial example

Practice 1: Shifting Ellipse

let rVal = 0;

function setup() {
  createCanvas(640, 480);
  textSize(18);
}

function draw() {
  background(10);

  fill(map(rVal, 0, 1023, 100, 255));

  if (!serialActive) {
    text("Press Space Bar to select Serial Port", 20, 30);
  } else {
    text("Connected", 20, 30);
    
    // Print the current values
    text('rVal = ' + str(rVal), 20, 50);

    ellipse(map(rVal, 150, 600, 0, width), height /2, map(rVal, 150, 600, 50, 200));
  }
}

function keyPressed() {
  if (key == " ") {
    // important to have in order to start the serial connection!!
    setUpSerial();
  }
}

// This function will be called by the web-serial library
// with each new *line* of data. The serial library reads
// the data until the newline and then gives it to us through
// this callback function
function readSerial(data) {
  ////////////////////////////////////
  //READ FROM ARDUINO HERE
  ////////////////////////////////////

  if (data != null) {
    // make sure there is actually a message
    // split the message
    let fromArduino = split(trim(data), ",");
    // if the right length, then proceed
    if (fromArduino.length == 1) {
      // only store values here
      // do everything with those values in the main draw loop
      
      // We take the string we get from Arduino and explicitly
      // convert it to a number by using int()
      // e.g. "103" becomes 103
      rVal = int(fromArduino[0]);
    }

    //////////////////////////////////
    //SEND TO ARDUINO HERE (handshake)
    //////////////////////////////////
    let sendToArduino = 0 + '\n';
    writeSerial(sendToArduino);
  }
}

/* Arduino Code

void setup() {
  // Start serial communication so we can send data
  // over the USB connection to our p5js sketch
  Serial.begin(9600);

  // We'll use the builtin LED as a status output.
  // We can't use the serial monitor since the serial connection is
  // used to communicate to p5js and only one application on the computer
  // can use a serial port at once.
  pinMode(LED_BUILTIN, OUTPUT);

  // start the handshake
  while (Serial.available() <= 0) {
    digitalWrite(LED_BUILTIN, HIGH); // on/blink while waiting for serial data
    Serial.println("0,0"); // send a starting message
    delay(300);            // wait 1/3 second
    digitalWrite(LED_BUILTIN, LOW);
    delay(50);
  }
}

void loop() {
  // wait for data from p5 before doing something
  while (Serial.available()) {
    digitalWrite(LED_BUILTIN, HIGH); // led on while receiving data

    if (Serial.read() == '\n') {
      int sensor = analogRead(A0);
      delay(5);
      Serial.println(sensor);
    }
  }
  digitalWrite(LED_BUILTIN, LOW);
}

*/

Practice 2: Brightness Control

let brightness = 0;
let rVal = 0;

function setup() {
  createCanvas(640, 480);
  textSize(18);
  background(0);
}

function draw() {
  background(map(brightness, 0, 255, 0, 255), 0, 0);

  fill(255);
  if (!serialActive) {
    text("Press 'Space' to connect to Serial Port", 20, 30);
  } else {
    text("Connected to Arduino", 20, 30);
    text('Brightness: ' + brightness, 20, 60);
    text('rVal: ' + rVal, 20, 90);

    // Map mouseX to brightness (0-255)
    brightness = map(mouseX, 0, width, 0, 255);
    brightness = int(constrain(brightness, 0, 255));

    // Display instructions
    text("Move mouse horizontally to change LED brightness", 20, height - 20);
  }
}

function keyPressed() {
  if (key === ' ') {
    setUpSerial();
  }
}

// This function will be called by the web-serial library
// with each new *line* of data. The serial library reads
// the data until the newline and then gives it to us through
// this callback function
function readSerial(data) {
  ////////////////////////////////////
  //READ FROM ARDUINO HERE
  ////////////////////////////////////
  if (data != null) {
    // make sure there is actually a message
    // split the message
    let fromArduino = split(trim(data), ",");
    // if the right length, then proceed
    if (fromArduino.length == 1) {
      // only store values here
      rVal = fromArduino[0];
    }

    //////////////////////////////////
    //SEND TO ARDUINO HERE (handshake)
    //////////////////////////////////
    let sendToArduino = brightness + '\n';
    writeSerial(sendToArduino);
  }
}

/*

// LED Brightness Control via Serial
const int ledPin = 9; 

void setup() {
  // Initialize serial communication at 9600 baud
  Serial.begin(9600);
  
  // Set LED pin as output
  pinMode(ledPin, OUTPUT);
  pinMode(LED_BUILTIN, OUTPUT);
  pinMode(2, OUTPUT);
  
  // Blink them so we can check the wiring
  analogWrite(ledPin, 255);
  delay(200);
  analogWrite(ledPin, 0);

  // start the handshake
  while (Serial.available() <= 0) {
    digitalWrite(LED_BUILTIN, HIGH); // on/blink while waiting for serial data
    Serial.println("0,0"); // send a starting message
    delay(300);            // wait 1/3 second
    digitalWrite(LED_BUILTIN, LOW);
    delay(50);
  }
}

void loop() {
  // Check if data is available on the serial port
  while (Serial.available()) {
    digitalWrite(LED_BUILTIN, HIGH);

    // Read the incoming byte:
    int brightness = Serial.parseInt();
    // Constrain the brightness to be between 0 and 255
    brightness = constrain(brightness, 0, 255);
    if (Serial.read() == '\n') {
      // Set the brightness of the LED
      analogWrite(ledPin, brightness);
      delay(5);
      // Send back the brightness value for confirmation
      Serial.println(brightness);
    } 
  }
  digitalWrite(LED_BUILTIN, LOW);
}

*/

Practice 3: Windy Balls Bouncing

let velocity;
let gravity;
let position;
let acceleration;
let wind;
let drag = 0.99;
let mass = 50;

// for uno connection
let rVal = 0;
let LED = 0; 

function setup() {
  createCanvas(640, 360);
  noFill();
  position = createVector(width/2, 0);
  velocity = createVector(0,0);
  acceleration = createVector(0,0);
  gravity = createVector(0, 0.5*mass);
  wind = createVector(0,0);
}

function draw() {
  background(255);

  fill(10);
  
  if (!serialActive) {
    text("Press S to select Serial Port", 20, 30);
  } else {
    text("Connected", 20, 30);
  
    // Print the current values
    text('rVal = ' + str(rVal), 20, 50);
  }
  
  if (rVal > 0) {
    wind.x += map(constrain(rVal, 200, 600), 200, 600, -0.5, 0.5);
    applyForce(wind);
  }
  
  applyForce(gravity);
  velocity.add(acceleration);
  velocity.mult(drag);
  position.add(velocity);
  acceleration.mult(0);
  ellipse(position.x,position.y,mass,mass);
  if (position.y > height-mass/2) {
      LED = 1;
      velocity.y *= -0.9;  // A little dampening when hitting the bottom
      position.y = height-mass/2;
  } else {
    LED = 0;
  }
}

function applyForce(force){
  // Newton's 2nd law: F = M * A
  // or A = F / M
  let f = p5.Vector.div(force, mass);
  acceleration.add(f);
}

function keyPressed(){
  if (key == "s") {
    // important to have in order to start the serial connection!!
    setUpSerial();
  }

  if (key==' '){
    mass=random(15,80);
    position.y=-mass;
    position.x=width/2;
    acceleration = createVector(0,0);
    velocity.mult(0);
    wind = createVector(0,0);
  }
}

function readSerial(data) {
  ////////////////////////////////////
  //READ FROM ARDUINO HERE
  ////////////////////////////////////

  if (data != null) {
    // make sure there is actually a message
    
    // split the message
    let fromArduino = split(trim(data), ","); 
    
    // if the right length, then proceed
    if (fromArduino.length == 1) {
      // convert it to a number by using int()
      rVal = int(fromArduino[0]);
    }

    //////////////////////////////////
    //SEND TO ARDUINO HERE (handshake)
    //////////////////////////////////
    let sendToArduino = LED+'\n';
    writeSerial(sendToArduino);
  }
}

/*

int ledPin = 9;

void setup() {
  // Start serial communication so we can send data
  // over the USB connection to our p5js sketch
  Serial.begin(9600);

  // We'll use the builtin LED as a status output.
  // We can't use the serial monitor since the serial connection is
  // used to communicate to p5js and only one application on the computer
  // can use a serial port at once.
  pinMode(LED_BUILTIN, OUTPUT);
  pinMode(ledPin, OUTPUT);

  // Blink them so we can check the wiring
  analogWrite(ledPin, 255);
  delay(200);
  analogWrite(ledPin, 0);

  // start the handshake
  while (Serial.available() <= 0) {
    digitalWrite(LED_BUILTIN, HIGH); // on/blink while waiting for serial data
    Serial.println("0,0"); // send a starting message
    delay(300);            // wait 1/3 second
    digitalWrite(LED_BUILTIN, LOW);
    delay(50);
  }
}

void loop() {
  // wait for data from p5 before doing something
  while (Serial.available()) {
    digitalWrite(LED_BUILTIN, HIGH); // led on while receiving data

    int ledState = Serial.parseInt();
    if (Serial.read() == '\n') {
      digitalWrite(ledPin, ledState);
      int sensor = analogRead(A0);
      delay(5);
      Serial.println(sensor);
    }
  }
  digitalWrite(LED_BUILTIN, LOW);
}


*/

Week 11: Final project concept

For my final projecting I am planning to expand on my midterm project to that it involves physical hands on components. Currently the project features two mini games and some helpful information regarding film photography in general. I plan to modify one of the pre-existing mini games (a mixing chemistry game) so that users have to hold a button in order to pour each chemical. I would also like to add 2-3 mini games. One of them would be assisting a customer calibrate the light meter in their camera (this would use a light sensor and potentiometer). Another idea is a further development of the dilm development station. This would feature the user loading their film in to a developing tank and would use dc motor to simulate the tanks spinning. Lastly, I am hoping to do some kind of lens assembly puzzle. I am the least sure about this idea because it would require 3D printing each piece of the lens and finding a way to simulate them locking together like they would on an actual camera. My biggest concern at the moment is being over ambitious in the conceptual phase and thus not having enough time to actually develop what I planned for. Please let me know if you have any suggestions!

Week 11: Reading Response

This week’s reading, Design Meets Disability, explores the ways in which assistive technologies and art are being used together to represent disabilities. The author highlights how this type of design works to extend these tools beyond the problem they solve and instead focuses on the user and their experience with them. Whether that be through prioritizing aesthetics or representing these resources as art themselves, this drives a new type of design process, one in which functionality is not the only factor. This proposition, of sorts, is something we have explored countless times with a special mention to Don Norman’s The Design of Everyday Things. The idea that the user experience is just as important as the design and purpose are common theme of these two articles and I am particularly interested in how it is presented in this article.

Not only is this design methodology more effective but in this context, it evidently makes individuals’ lives more accessible and inclusive. Whether it be through re-designing hearing aids to better match the needs and preferences of users or representing diverse bodies with different disabilities in media, this approach not only makes their lives easier but they open up space for conversation on a larger scale about why this type of inclusion is important. We can apply these practices in class when designing and implementing our projects through user-focused design and testing. Although on the design side it is oftentimes difficult to recognize these shortcomings, through field testing and design/usability-centric improvements it is more than possible.

Week 11: Design meets Disability

One of the main arguments I extracted from this week’s reading is the interplay between fashion and discretion in design, particularly in the context of disability. Whether a design should blend in or stand out is subjective and depends on the user. For instance, teeth implants and removable teeth were initially functional medical solutions meant to resemble natural teeth. Over time, however, these appliances have become fashion statements, with materials like gold being used to signify wealth or spirituality. This shift exemplifies how functional designs can appeal to broader audiences and evolve into tools of self-expression. Similarly, the example of the athlete in the reading, who embraced her prosthetic legs as a fashionable part of her identity, demonstrates how design choices can transcend functionality to reflect individuality. This underscores the idea that the line between utility and self-expression is fluid and often shaped by societal influences.

The reading also provokes thought about the ethics of design, particularly when it comes to medical appliances. While designers from unrelated fields might bring fresh perspectives, their lack of specialized knowledge can lead to unintended consequences. For example, the trend of hearing aids resembling earphones doesn’t address how excessive earphone use may itself lead to hearing loss, creating a harmful cycle. This highlights the risk of prioritizing aesthetics or profit over the users’ actual needs. These insights also apply to interactive design, reminding us that functionality and user experience must take precedence over superficial appeal. Thoughtful design must strike a balance, respecting the user’s needs and individuality while avoiding exploitation or unnecessary commercialization.

Final Project Idea

For two of my assignments this semester, I incorporated my guitar in arduino as an unusual switch for turning on LED lights. I really enjoyed working with it, and I figured that I might as well expand upon it for my final project. The idea of an unusual switch reminded me of videos I’ve watched in which people try to beat video games using modified objects as controllers —  dance pads, bongos, and even bananas.

Combining my hobbies, I will create an interactive system where players will use a guitar as a gamepad of sorts to defeat enemies in a p5 game. I don’t have an idea for the actual game yet, but I expect it to have a quirky, cartoonish style inspired by the Scott Pilgrim franchise, in which the titular character is a bassist and finds himself in video-game-esque fights.

Reading Reflection #8: Design Meets Disability

The author offers a really insightful perspective on the relationship between  fashion and practical design. We often assume that medical devices and aesthetic value are inherently incompatible, but the emotional is just as important as the physical; fashionable prosthetics can provide emotional value for its users by creating a positive image and de-stigmatizing disabilities without deliberately hiding the device.

This just goes to show how inspiration often comes from the most unexpected places, therefore we must keep an open mind in order to come up with good designs instead of setting too much limitations. It is only through interdisciplinary efforts that we can take each field to new heights. While I still do not have a concrete idea for my final project, this excerpt made me consider making something that enhances some kind of human activity adding an artistic touch to it, which is more of my strong suit.