Final Project – Lime Liner

Concept and Implementation: 

For my final project, I created a digital version of the classic Etch-a-Sketch toy which utilizes both Arduino and P5JS. I personalized the design by using neon green and black colors to give it a modern, sleek look. The goal was to replicate the drawing experience of the original toy while adding new features that enhance the user’s creativity and leaving a personal mark on the concept. Additionally, to better reflect my altered version of the toy, I decided to name it Lime Liner.

The Lime Liner was created using an Arduino Uno board and two potentiometers connected to analog pins A0 and A1. The potentiometers control the movement of the cursor on the screen. A switch connected to digital pin 2 was also used to clear the screen. The p5.js sketch is used to draw the cursor and lines on the canvas. The user interacts with the Etch-a-Sketch by turning the potentiometers to move the cursor horizontally and vertically, and pressing the switch to clear the screen. The cursor moves smoothly on the screen and leaves a trail as it moves. The user can create different patterns and shapes by changing the direction and speed of the cursor.

Arduino Code: 

The Arduino code initializes the serial communication and reads the values of the potentiometers and switch. It sends the values to the p5.js sketch using the Serial library.

// This code is for an Arduino project that receives data from p5.js and sends sensor data back to p5.js
// The inputs are:
// - A0: first potentiometer
// - A1: second potentiometer
// - 2: switch input

void setup() {
  // Serial communication is started to send the data
  Serial.begin(9600);

  // Set pin 2 as input
  pinMode(2, INPUT);

  // Bidirectional communication starts
  while (Serial.available() <= 0) {
    // Send a starting message to p5.js
    Serial.println("0,0");
  }
}

void loop() {
  // Waits to receive data from p5.js first and then starts executing
  while (Serial.available()) {

    // Parse the incoming data from p5.js
    int left = Serial.parseInt();
    int right = Serial.parseInt();
    
    // If a new line character is received, read the sensors and button and send the data back to p5.js
    if (Serial.read() == '\n') {
      int sensor = analogRead(A0);
      delay(5);
      int sensor2 = analogRead(A1);
      delay(5);
      int button = digitalRead(2);
      delay(5);

      // Send the sensor and button data to p5.js
      Serial.print(sensor);
      Serial.print(',');
      Serial.print(sensor2);
      Serial.print(',');
      Serial.println(button);
    }
  }
} 

P5js Code: 

The p5.js code sets up the canvas and draws the cursor and lines using the values received from the Arduino. It also includes functions to clear the screen and prevent the cursor from going outside the canvas.

// Variables for controlling color, position, and switch state
let xPos = 0; // horizontal position of the ellipse
let yPos = 0; // vertical position of the ellipse
let switchState = 0; // state of the switch that clears the Etch A Sketch

// Setup function, runs once when the sketch is loaded
function setup() {
  createCanvas(600, 400);
  textSize(18);
  background(255);
  frame();
}

// Counter variable for the while loop in draw function
let i = 0;

// Draw function, runs continuously to update the sketch
function draw() {
  // While loop to set the button state to 1 only once
  while (i < 1) {
    switchState = 1;
    i++;
  }

  // Map the xPos and yPos to the canvas size to control ellipse position
  fill("#39FF13");
  // Draw the ellipse at a position determined by the mapped xPos and yPos
  ellipse(
    map(xPos, 0, 1023, 70, width - 90),
    map(yPos, 0, 1023, 70, height - 80),
    3
  );

  // Check if the switchState is 1, and call the frame function to clear the sketch
  if (switchState == 1) {
    frame(); // calls the frame function i.e. restarts the sketch
  }
}

// Function to set up the serial connection when spacebar is pressed
function keyPressed() {
  if (key == " ") {
    setUpSerial();
  }
}

// Function to read data from the Arduino
function readSerial(data) {
  ////////////////////////////////////
  //READ FROM ARDUINO HERE
  ////////////////////////////////////

  // Check if there is any data received
  if (data != null) {
    // Split the message
    let fromArduino = split(trim(data), ",");
    // If the message is of the correct length, store the Arduino values
    if (fromArduino.length == 3) {
      xPos = fromArduino[0]; // Update the xPos value based on input from Arduino
      yPos = fromArduino[1]; // Update the yPos value based on input from Arduino
      switchState = fromArduino[2];
    }
    //////////////////////////////////
    //SEND TO ARDUINO HERE (handshake)
    //////////////////////////////////
    let sendToArduino = xPos + "," + yPos + "\n";
    writeSerial(sendToArduino);
  }
}

// Function to draw the frame of the Etch A Sketch
function frame() {
  // Draw the outer frame
  strokeWeight(120);
  noFill();
  stroke("#2BC20E");
  rect(0, 0, width, height);

  // Draw the inner frame
  fill("#010B12");
  strokeWeight(30);
  stroke("#010B12");
  strokeJoin(ROUND);
  rect(70, 70, width-140, height-140);

  // Draw the title 
  noStroke();
  fill("#1E1F21");
  textAlign(CENTER);
  textSize(30);
  textFont("Brush Script MT");
  text(" ~ Lime Liner ~ ", width/2, 40);

  // Draw the two knobs at the bottom
  noStroke();
  fill("#010B12");
  ellipse(width-570, 365, 50, 50);
  ellipse(570, 365, 50, 50);
}

Serial communication is used to send and receive data between the Arduino and p5.js. The Arduino sends the position of the potentiometers and button to p5.js, which uses this data to draw on the screen. The clear button also uses serial communication to send a signal from p5.js to the Arduino.

Areas I am proud of and future improvments:

I am particularly proud of the clean and modern design of the Etch-a-Sketch, which makes it stand out from other versions. I also spent a lot of time debugging both the physical and code components of the project to ensure that everything was functioning properly.

Since this was a back-up project, I am a bit disappointed that I did not have the skills and time to finish my initial idea of a radar. Regardless, I feel satisfied with the final version of my project. In the future, one area for improvement would be to add more features to the Lime Liner, such as the ability to change the color of the lines or adjust the thickness of the stylus. Another potential improvement would be to make the stylus wireless to allow for more freedom of movement. Additionally, the code could be optimized to reduce latency and improve performance and a game could be implemented in which the user will interact more with the project.

 

Leave a Reply