Final Project Progress

Concept and Design

As for my final project, I have decided to work on an interactive painting program that allows its users to draw on the p5js sketch. So far the progress has been slow and steady as it is a well-known fact that any piece of art takes time, haha.

The main Arduino components I have included in my circuit are two potentiometers. When they are toggled the ellipse starts creating a generative art in whichever direction the user chooses to move the analog sensors. Since the alpha and r values of the ellipse have been mapped, every time the speed of the potentiometer changes, depending on how fast or slow it goes, the transparency and the hue change. I have also included a switch which when pressed clears the screen.

Initial advancement-

P5js Code

Draw function-

function draw() {
  
  fill(255, 0, 255, map(alpha, 0, 1023, 0, 255));
  ellipse(map(rVal, 0, 1023, 0, width), map(alpha,  0, 1023, 0, height), 50);
  
  if (buttonState == 1){
    // background(map(rVal, 0, 1023, 0, 255), 255, 255);
    background (190)
    
  }

Serial Communication-

function readSerial(data) {
  
  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 == 3) {
      // only store values here
      // do everything with those values in the main draw loop
      rVal = fromArduino[0];
      alpha = fromArduino[1];
      buttonState = fromArduino[2];
    }
    

    //////////////////////////////////
    //SEND TO ARDUINO HERE (handshake)
    //////////////////////////////////
     let sendToArduino = left+ "," + right + "\n";
    writeSerial(sendToArduino);
  }
}

Arduino Code

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

   pinMode(2, INPUT); 

  // start the handshake
  while (Serial.available() <= 0) {
    Serial.println("0,0"); // send a starting message
    // delay(300);            // wait 1/3 second
  }
}

void loop() {
  while (Serial.available()) {

    int left = Serial.parseInt();
    int right = Serial.parseInt();
    if (Serial.read() == '\n') {
      int sensor = analogRead(A0);
      delay(5);
      int sensor2 = analogRead(A1);
      delay(5);
      int button = digitalRead(2);
      Serial.print(sensor);
      Serial.print(',');
      Serial.print(sensor2);
      Serial.print(',');
      Serial.println(button);
    }
  }
}

Improvements

I am still working on a lot of components and hope to include them.

  1. Add another switch that allows the user to shift between shapes such as from an ellipse to a square.
  2.  I want the values of the colors to change when the shape enters a certain side of the canvas while it is being controlled by the P5js.
  3.  Design a creative P5js interface than just plain background.
  4.  I am still working on designing a board wherein I could attach the switches and the potentiometers.

Music Assignment

I worked with Ahmed and his post is here: https://intro.nyuadim.com/2022/11/17/musical-instrument-9/

Concept

In this assignment I worked with Mohamed to design a musical instrument using the arduino and breadboard. We used two main devices which are the piezo speaker and the servo motor. We decided to play the song “We will we will rock you” on the piezo buzzer, and then provide sound effects after that using the servo motor, by rotating it clockwise and counter-clockwise. The code to do this is shown below. Here is a schematic for our implementation.

 

 

#include "pitches.h"
#include <Servo.h>
// notes in the melody:
int melody[] = {
  NOTE_C4, NOTE_A3, NOTE_C4, NOTE_A3, 0, NOTE_G3, NOTE_G3,NOTE_G3
};
// note durations: 4 = quarter note, 8 = eighth note, etc.:
int noteDurations[] = {
  2, 2, 2, 2, 4, 4,4
};
Servo myservo; 
int pos = 0; 
void setup() {
  // iterate over the notes of the melody:
  
}
void loop() {
  bool switchState=digitalRead(A3);
  if(switchState){
  for (int thisNote = 0; thisNote < 8; thisNote++) {
    int noteDuration = 1000 / noteDurations[thisNote];
    tone(8, melody[thisNote], noteDuration);
    myservo.attach(9);
    int pauseBetweenNotes = noteDuration * 1.30;
    delay(pauseBetweenNotes);
    // stop the tone playing:
    noTone(8);
  }
    myservo.write(180);              // tell servo to go to position in variable 'pos'
    delay(1000*1.3);                       // waits 15ms for the servo to reach the position
    myservo.write(0);              // tell servo to go to position in variable 'pos'
    delay(1000*1.3);                       // waits 15ms for the servo to reach the position
}
}

As seen in the above code, we tried to make the sound effects that come from the servo motor sound better, by making the delay time between the rotations equal to the pause time between the notes. To control the musical instrument, we used a digital input which is a switch that should be pressed each time to play the sounds again

We really liked how the output looked like, but we believe that we can improve on it by making the servo motor be controlling an object like a drum stick when it is rotating to make it sound as a better musical instrument. Here is a video that shows our implementation.

 

 

Final Project

Proposal 

I want to Create a game for kids in my final project. My idea came from watching my little nephew playing with my niece when he showed her her toy animals and made the sounds of the animals. so i want to create a toy were when to connect the head of the animal to the right body it makes the animals sound.

This is how the idea kind of works.

Code(hopefully)

I hope i will be able to use ardino to detect the right head to the right body and use the P5j.s code to be able to detect the and make the sound. I am making this look easy but I am very worried about the code and am not sure how I will figure it out!

Final Project Progress Update

For my final project, I’m making a multi-stage cooking game for one of my favorite Filipino desserts, haluhalo.

So far, I’ve made quite a bit of art for the game. I’ve stuck to a style that’s more organic and colorful so that the art can feel more friendly and fun.

Here’s the sketch so far!

 

I’ve wired the digital switch and potentiometer, and I’ve implemented the potentiometer for Stage 1, so you can cook the sago if you hit the right temperature.

At first, I really hit a wall with this project and felt very tired of it, but the encouragement of other people really helped. After some reflection, I realized that I was feeling a bit tired because a lot of the work was just producing a lot of illustrations rather than more complex technologies that I hadn’t tried before.

As a result, I decided to try and make the project more ambitious, and to involve vectors, Handsfree.js, animations, interactivity, and maybe even some facial recognition and 3D via Three.js. Here is my revised plan.

I still have a lot to go, namely:

  1. A lot of UI screens (failure and success) — I’m thinking of ways to make this less taxing or more reusable without losing the organic handdrawn vibe
  2. Making the physical parts of the physical interface — I’m thinking of using wood and fabric rather than cardboard, and maybe 3D printing some of the more complex elements so they look more cool.
  3. Making the Posenet, video, and Handsfree work :’DDDDD

It’ll be very terrible and very fun. I’m excited to post the next update!

Final Project update – Daniel and Q M Naushad

CONEPT

Our final project will be a mixer using an arduino board and P5js’ sound library.

DESIGN

The mixer will use the following components:

    • 1 potentiometer – analog input (Will work like a slider would in an actual mixer)
    • 2 buttons to switch between effects
    • 1 button to work as a Pause/Play button
    • [MAYBE] 1 button to work as a Bypass/Standby function

Here is a sketch of what it would look like:

We will use the Arduino’s box  to make the board and double as a place to hide the board.

The interface where you will mix is looking like this, currently I am working on it and designing it, this is not the final product/result as we’d like to add some color to it:

The line at the middle will react to the sound and hopefully produce colors and make a sound wave.

FUTURE PLANS

During the week we expect to finish the interface and Arduino set-up, and would be working on the code and synching in the sounds.

Only project that may come is being able to translate the values from the potentiometer to the parameters to make the effects take effect.

Final Project update – Daniel and Q M

conept

Our final project will be a mixer using an arduino board and P5js’ sound library.

Design

The mixer will use the following components:

    • 1 potentiometer – analog input (Will work like a slider would in an actual mixer)
    • 2 buttons to switch between effects
    • 1 button to work as a Pause/Play button
    • [MAYBE] 1 button to work as a Bypass/Standby function

Here is a sketch of what it would look like:

We will use the Arduino’s box  to make the board and double as a place to hide the board.

The interface where you will mix is looking like this, currently I am working on it and designing it, this is not the final product/result as I’d like to add some color to it:

The line at the middle will react to the sound and hopefully produce colors and make a sound wave.

Future plans

During the week we expect to finish the interface and Arduino set-up, and would be working on the code and synching in the sounds.

Only project that may come is being able to translate the values from the potentiometer to the parameters to make the effects take effect.

final project commitment & progress

CONCEPT

In our last post we had come up with a game for our final project. After some further brainstorming, we thought it would be fun to try something other than a game, considering that this is what we did for our midterms. We thought about making an interactive system that could be experienced by multiple people at the same time. Our idea for the project is now to create a touchable “friendship lamp.” The basic idea is that we will build two lamps using two Arduino boards and LED strips. Each light will be equipped with different settings that can change the light pattern and color. These settings will be able to be manipulated within a program on p5.js, accessed on separate computers by the two users. After one user chooses the settings of their light, they then touch their lamp to send that light to the other user’s lamp. Communication between the two users can be simultaneous and there is no limit to the amount of times they can send each other messages. 

THE ROLE OF P5.js 

The sketch on p5.js will be a simple program with a few screens that allows the user to control the light they will send. They will be able to choose any color from a color wheel, and they will be able to choose from 3 different light modes: flicker, wave, and pulse. The choices made by the user will be stored by the program, and p5 will then send this data to the board of the other person’s lamp. However, data is not sent until some feedback is received from Arduino, explained in detail in the following section. 

 

THE ROLE OF ARDUINO 

A touch sensor and an LED strip would both be included in the Arduino circuit. When touched, the touch sensor transmits a signal to p5js, enabling p5js to transfer data to the Arduino board. Since p5js will be sending data about the color and pattern that the LED strip should light up in, the arduino board receives this data and turns the light on as requested by the user.

 

COMMUNICATION

As for the method of communication (serial mode) between the Arduino and p5js, we are still employing wires to transfer data back and forth at the time. However, because the two lamps and users in our original concept must be distanced from one another, we are exploring and, ideally, planning to include Bluetooth modules or, perhaps, an esp32 on our board to help with wireless communication between the two platforms.

PROGRESS 

We knew that we weren’t going to be able to have cross communication between two users without wireless Arduino boards, and that we would not be able to implement the touching aspect without an actual tactile sensor. Hence, our plan for this week was to finalize our idea and begin assembling the different components of the system separately. The p5 program is almost complete, with an exception to the code that will send the data to the wireless Arduino board. The sketch is shown below:

At the end of the program, the console prints out the data that would theoretically be sent to Arduino. Including the color value and the light mode. Also, because we do not have the tactile sensor yet, the light is “sent” figuratively by just pressing any key in the third step. 

For the Arduino component, we built our strips of 10 LED’s for each lamp and connected them to a board and focused on simply creating three different light modes that could be controlled within the Arduino code, separate from p5. The code that demonstrates how the various light modes are used to enable a flicker, wavy, or fading effect on the LED strip is provided below:

void loop() {
  NeoPixel.clear(); // set all pixel colors to 'off'. It only takes effect if pixels.show() is called
  NeoPixel.show();
  // WAVY
  //turn pixels to green one by one with delay between each pixel
  for (int pixel = 0; pixel < NUM_PIXELS; pixel++) { // for each pixel
    NeoPixel.setPixelColor(pixel, NeoPixel.Color(0, 255, 0)); // it only takes effect if pixels.show() is called
    // if(pixel > 0)
    // {
    //   NeoPixel.show();   // send the updated pixel colors to the NeoPixel hardware.
    //   NeoPixel.clear();
    // }
    NeoPixel.show();   // send the updated pixel colors to the NeoPixel hardware.
    NeoPixel.clear();
    
    delay(100); // pause between each pixel
  }
  // turn off all pixels for two seconds
  NeoPixel.clear();
  NeoPixel.show(); // send the updated pixel colors to the NeoPixel hardware.
  delay(2000);     // off time
  // FLICKERING:
  //turn on all pixels to red at the same time for two seconds
  for (int pixel = 0; pixel < NUM_PIXELS; pixel++) { // for each pixel
    NeoPixel.setPixelColor(pixel, NeoPixel.Color(255, 0, 0)); // it only takes effect if pixels.show() is called
  }
  NeoPixel.show(); // send the updated pixel colors to the NeoPixel hardware.
  delay(500);     // on time
  // turn off all pixels for two seconds
  NeoPixel.clear();
  NeoPixel.show(); // send the updated pixel colors to the NeoPixel hardware.
  delay(500);     // off time
  //PULSING
  brighten();
  darken();
}
// 0 to 255
void brighten() {
  uint16_t i, j;
  for (j = 0; j < 255; j++) {
    for (i = 0; i < NeoPixel.numPixels(); i++) {
      NeoPixel.setPixelColor(i, 0, 0, j);
    }
    NeoPixel.show();
    delay(10);
  }
  //delay(100);
}
// 255 to 0
void darken() {
  Serial.begin(9600);
  uint16_t i, j;
  for (j = 255; j > 0; j--) {
    for (i = 0; i < NeoPixel.numPixels(); i++) {
      NeoPixel.setPixelColor(i, 0, 0, j);
    }
    NeoPixel.show();
    delay(10);
    Serial.println(j);
  }
  delay(100);
}

 

Finally, a demo of the different modes is displayed below:

 

Final Project – Progress

Concept/ Idea

For the project, we (Tim and Samyam) have decided to develop a system that lets the user sketch a diagram or shape on the p5.js canvas. This sketch then will be used to control the physical arm of our drawing platform. To accomplish this, we will send canvas data from p5.js to Arduino, controlling different parts of the drawing device. 

The striking feature of the project is the interconnectivity of the drawing. The user can draw as many shapes or sketches as they desire, but everything will remain connected to each other. This idea is inspired by the Eulerian trail, where the floor is divided into multiple sections when multiple people step on it. 

 

Hardware Design

Following the previous post, we have finalized our concept to be a polar coordinate pen plotter that plots a shape drawn on the computer screen. Unlike our previous design, we have decided to make a 2-DOF system (linear movement on one axis, and rotational motion around an orthogonal axis). Although the mechanical design of the machine became more complex, this will make the software much simpler. For the design, we used Autodesk Fusion 360 to create a 3d model, which was manufactured with a 3d printer and a laser cutter. For the precision of the plotter, we purchased a linear guide rail, commonly used in CNC machines and 3d printers; we used a stepper motor for controlled movement. Below is a 3 d model design for the project:

A rack and pinion system was used, so as a gear connected to a stepper motor rotates, it will move the whole pen carrier along a linear rail.

One distinctive feature of this plotter is that the position of the rotating (base) plate can be adjusted freely. This allows the user to produce different drawings every time he or she moves the base plate.

Because drawings on the screen use cartesian coordinates, we had to convert XY coordinates into polar coordinates. This was very simple because T:(X,Y) –> (r, θ), where r = sqrt(x^2+y^2) and θ = tan^-1(y/x). r will determine the movement of a linear DOF and θ will determine how much the base plate will rotate. Do you see how simple the calculation got compared to the previous design?

Making Parts

As mentioned above, a laser cutter and 3d printer was used to make parts.

Prototype

Laser Cutting

Due to the high rigidity of the acrylic plates, we decided to make the main body with acrylic parts. Based on our design, we were able to laser-cut the parts that we needed.

3D Printing

Parts that cannot be made with laser cutters were made using 3d printers. This included a base plate, a spacer between acrylic parts, and a pen moving mechanism.

P5.js Component

The preliminary phase of the project depends on the functionalities of the p5.js component. The user can use the mouse to draw shapes on the p5.js canvas; the shape will be replicated in the actual design using the Arduino component. 

In order to sketch a shape on the canvas, the user can click the mouse and drag the cursor to draw the desired shape. This is regulated by two functions titled “mousePressed()” and “mouseReleased()” respectively. When the mouse is clicked, the global variable “isclicked” is set to True and when the mouse click is released, “isClicked” is set to False. This way, the global variable keeps track of the sketch being drawn. 

Once the mouse is clicked, the program checks the position of the cursor – if it is static while being tracked, the position is ignored, i.e., the user must move the cursor, while the mouse is being clicked, so that a sketch can be drawn on the screen. It is facilitated by the following code:

// Make sure the mouse is clicked and cursor position is different
if (isClicked && mouseX !== pmouseX && mouseX !== pmouseY)
{
  // Create a vector and add it to the list
  // let pt = createVector(mouseX, mouseY);          // When origin is at the top-left corner
  let pt = createVector(mouseX - width/2, mouseY - height/2);
  positions.push(pt);
  // console.log(pt.x, pt.y);
  
  
  // Mapping Cartesian to Polar and appending it in mappedPositions array
  let temp_list = [];
  temp_list = cartToPolar(pt.x, pt.y)
  let pt_mapped = createVector((temp_list[0] * one_px_mm), temp_list[1]);
  mappedPositions.push(pt_mapped);
 
}

Here, we can see, if the aforementioned conditions are met, a new vector based on the cartesian location of the cursor is created and appended to the (global variable) list “positions”. The entire canvas is translated to the middle of the canvas, that’s why a certain amount is subtracted to the x and y coordinates before appending to the list. Similarly, with the help of a function titled “cartToPolar()”, each vector in the cartesian coordinates is converted to polar coordinates equivalent and appended to a list titled “mappedPositions[]”.

function cartToPolar(x, y)
{
  let radius, angle;
  
  radius = sqrt(sq(x) + sq(y));
  // console.log(radius);
  
  angle = atan(y/x);
  // console.log(angle);
  
  let temp_list = [];
  temp_list[0] = map(radius, 0, sqrt(2 * sq(width/2)), 0, disc_radius);         // Mapped radius
  temp_list[1] = angle;
  
  return temp_list;
  
}

The program also consists of two manually coded buttons — RESET and SEND DATA. The former reset the canvas and resets the required variables so that the sketch can be redrawn from the beginning. While the latter is used to send data to the Arduino connected to the system. Both these functions derive from a template function titled “button()” that takes text, x, y coordinates, height and width of the button as arguments. To develop the SEND DATA functionality, a function named “send_data_button()” calls the main button function with the required parameters. The main function returns a boolean value [1 if the cursor is within the button and 0 otherwise]. If the boolean value is 1 and the button is pressed, the values in the “mappedPositions[]” list are forwarded to the Arduino using an inbuilt serial.write() function. In each iteration, the angle of the coordinate is transmitted following its radius. 

function reset_button()
{
  let x = 26;
  let y = canvas_h - 70;
  let w = 125;
  let h = 50;
  
  // If the cursor is within the button button() function returns 1, else 0;
  let resetBool = button("RESET", x, y, w, h);
  
  // Resetting sketch if the cursor iswithin the button and mouse is clicked
  if (resetBool && mouseIsPressed)
  {
    positions = [];
    mappedPositions = [];
    isClicked = false;
  }
  
}

 

The p5.js component also comprises different functions like choosePort(), openPort(), serialEvent() and so forth to keep track of the port selection, data transmission as well as error handling. 

Arduino Component

Arduino is connected to 2 stepper motors, each controlled by different stepper drivers. The Arduino will read data sent from p5js and move the pen and plate accordingly. Total of 2 switches will be connected to the board, both for homing the pen carrier (one push button and one limit switch).

When the button is pressed, the Arduino will begin to move the pen carrier back until the carrier hits the limit switch. Once the limit switch is closed, the Arduino will move the pen carrier slightly front and move the carrier back until it hits the switch again. The second part will be done at a much slower speed for accuracy. Homing a pen carrier is significant because the machine must always be aware of the pen’s current position. Homing allows the machine to always start from the same initial position.

This is the sample code showing how the code will work (no motors added yet):

const int limitSw = 7;

const int homeButt = 8;

long long currentTime = 0;

bool homing = false;

bool reachEnd = false;

void setup() {

  // put your setup code here, to run once:

  pinMode(limitSw, INPUT);

  pinMode(homeButt, INPUT);

  Serial.begin(9600); 

}


void loop() {

  // put your main code here, to run repeatedly:

  if(!homing && digitalRead(homeButt) == 1){

    homing = true;

  }


  if(homing){

    if(!reachEnd){

      Serial.println("homing fast");

      if(digitalRead(limitSw) == 1){

        Serial.println("SW pressed");

        reachEnd = true;

        currentTime = millis();

      }

    }

    else{

      Serial.println("homing slow");

      if(digitalRead(limitSw) == 1 && millis() - currentTime > 500){

        Serial.println("SW slow pressed. homing complete");

        homing = false;

        reachEnd = false;

      }

    }

  }

}

The other part of the code will include moving each part accordingly to the coordinate values from p5js. This would be relatively easy to achieve because we can calculate how much each part will move in mm when the motor turns by half or a single step.

Further coding can be done once we are ready with fully assembled hardware.

Future Plan

The time it takes to 3D print parts is the only problem we are facing until now. Once we are done printing our parts, we will be able to assemble the parts together soon. 

For now, the future plan includes the functionality to successfully coordinate the Arduino component with the data sent from the p5.js component. Since the canvas sketch is drawn based on cartesian coordinates, while the physical drawing is based on polar coordinates, we are planning to program the project so that artistic output is achieved. 

Demo

The software phase of the project can be tested here using this link. The project will be completed once the printing phase is completed.

Final Project Update 1

Concept/ Idea

For the project, we (Tim and Samyam) have decided to develop a system that lets the user sketch a diagram or shape on the p5.js canvas. This sketch then will be used to control the physical arm of our drawing platform. To accomplish this, we will send canvas data from p5.js to Arduino, controlling different parts of the drawing device.

The striking feature of the project is the interconnectivity of the drawing. The user can draw as many shapes or sketches as they desire, but everything will remain connected to each other. This idea is inspired by the Eulerian trail, where the floor is divided into multiple sections when multiple people step on it.

 

Hardware Design

Following the previous post, we have finalized our concept to be a polar coordinate pen plotter that plots a shape drawn on the computer screen. Unlike our previous design, we have decided to make a 2-DOF system (linear movement on one axis, and rotational motion around an orthogonal axis). Although the mechanical design of the machine became more complex, this will make the software much simpler. For the design, we used Autodesk Fusion 360 to create a 3d model, which was manufactured with a 3d printer and a laser cutter. For the precision of the plotter, we purchased a linear guide rail, commonly used in CNC machines and 3d printers; we used a stepper motor for controlled movement. Below is a 3 d model design for the project:

A rack and pinion system was used, so as a gear connected to a stepper motor rotates, it will move the whole pen carrier along a linear rail.

One distinctive feature of this plotter is that the position of the rotating (base) plate can be adjusted freely. This allows the user to produce different drawings every time he or she moves the base plate.

Because drawings on the screen use cartesian coordinates, we had to convert XY coordinates into polar coordinates. This was very simple because T:(X,Y) –> (r, θ), where r = sqrt(x^2+y^2) and θ = tan^-1(y/x). r will determine the movement of a linear DOF and θ will determine how much the base plate will rotate. Do you see how simple the calculation got compared to the previous design?

Making Parts

As mentioned above, a laser cutter and 3d printer was used to make parts.

Prototype

Laser Cutting

Due to the high rigidity of the acrylic plates, we decided to make the main body with acrylic parts. Based on our design, we were able to laser-cut the parts that we needed.

3D Printing

Parts that cannot be made with laser cutters were made using 3d printers. This included a base plate, a spacer between acrylic parts, and a pen moving mechanism.

P5.js Component

The preliminary phase of the project depends on the functionalities of the p5.js component. The user can use the mouse to draw shapes on the p5.js canvas; the shape will be replicated in the actual design using the Arduino component.

In order to sketch a shape on the canvas, the user can click the mouse and drag the cursor to draw the desired shape. This is regulated by two functions titled “mousePressed()” and “mouseReleased()” respectively. When the mouse is clicked, the global variable “isclicked” is set to True and when the mouse click is released, “isClicked” is set to False. This way, the global variable keeps track of the sketch being drawn.

Once the mouse is clicked, the program checks the position of the cursor – if it is static while being tracked, the position is ignored, i.e., the user must move the cursor, while the mouse is being clicked, so that a sketch can be drawn on the screen. It is facilitated by the following code:

// Make sure the mouse is clicked and cursor position is different
if (isClicked && mouseX !== pmouseX && mouseX !== pmouseY)
{
  // Create a vector and add it to the list
  // let pt = createVector(mouseX, mouseY);          // When origin is at the top-left corner
  let pt = createVector(mouseX - width/2, mouseY - height/2);
  positions.push(pt);
  // console.log(pt.x, pt.y);
  
  
  // Mapping Cartesian to Polar and appending it in mappedPositions array
  let temp_list = [];
  temp_list = cartToPolar(pt.x, pt.y)
  let pt_mapped = createVector((temp_list[0] * one_px_mm), temp_list[1]);
  mappedPositions.push(pt_mapped);
 
}

Here, we can see, if the aforementioned conditions are met, a new vector based on the cartesian location of the cursor is created and appended to the (global variable) list “positions”. The entire canvas is translated to the middle of the canvas, that’s why a certain amount is subtracted to the x and y coordinates before appending to the list. Similarly, with the help of a function titled “cartToPolar()”, each vector in the cartesian coordinates is converted to polar coordinates equivalent and appended to a list titled “mappedPositions[]”.

function cartToPolar(x, y)
{
  let radius, angle;
  
  radius = sqrt(sq(x) + sq(y));
  // console.log(radius);
  
  angle = atan(y/x);
  // console.log(angle);
  
  let temp_list = [];
  temp_list[0] = map(radius, 0, sqrt(2 * sq(width/2)), 0, disc_radius);         // Mapped radius
  temp_list[1] = angle;
  
  return temp_list;
  
}

The program also consists of two manually coded buttons — RESET and SEND DATA. The former reset the canvas and resets the required variables so that the sketch can be redrawn from the beginning. While the latter is used to send data to the Arduino connected to the system. Both these functions derive from a template function titled “button()” that takes text, x, y coordinates, height and width of the button as arguments. To develop the SEND DATA functionality, a function named “send_data_button()” calls the main button function with the required parameters. The main function returns a boolean value [1 if the cursor is within the button and 0 otherwise]. If the boolean value is 1 and the button is pressed, the values in the “mappedPositions[]” list are forwarded to the Arduino using an inbuilt serial.write() function. In each iteration, the angle of the coordinate is transmitted following its radius.

function reset_button()
{
  let x = 26;
  let y = canvas_h - 70;
  let w = 125;
  let h = 50;
  
  // If the cursor is within the button button() function returns 1, else 0;
  let resetBool = button("RESET", x, y, w, h);
  
  // Resetting sketch if the cursor iswithin the button and mouse is clicked
  if (resetBool && mouseIsPressed)
  {
    positions = [];
    mappedPositions = [];
    isClicked = false;
  }
  
}

 

The p5.js component also comprises different functions like choosePort(), openPort(), serialEvent() and so forth to keep track of the port selection, data transmission as well as error handling.

Arduino Component

Arduino is connected to 2 stepper motors, each controlled by different stepper drivers. The Arduino will read data sent from p5js and move the pen and plate accordingly. Total of 2 switches will be connected to the board, both for homing the pen carrier (one push button and one limit switch).

When the button is pressed, the Arduino will begin to move the pen carrier back until the carrier hits the limit switch. Once the limit switch is closed, the Arduino will move the pen carrier slightly front and move the carrier back until it hits the switch again. The second part will be done at a much slower speed for accuracy. Homing a pen carrier is significant because the machine must always be aware of the pen’s current position. Homing allows the machine to always start from the same initial position.

This is the sample code showing how the code will work (no motors added yet):

const int limitSw = 7;

const int homeButt = 8;

long long currentTime = 0;

bool homing = false;

bool reachEnd = false;

void setup() {

  // put your setup code here, to run once:

  pinMode(limitSw, INPUT);

  pinMode(homeButt, INPUT);

  Serial.begin(9600); 

}


void loop() {

  // put your main code here, to run repeatedly:

  if(!homing && digitalRead(homeButt) == 1){

    homing = true;

  }


  if(homing){

    if(!reachEnd){

      Serial.println("homing fast");

      if(digitalRead(limitSw) == 1){

        Serial.println("SW pressed");

        reachEnd = true;

        currentTime = millis();

      }

    }

    else{

      Serial.println("homing slow");

      if(digitalRead(limitSw) == 1 && millis() - currentTime > 500){

        Serial.println("SW slow pressed. homing complete");

        homing = false;

        reachEnd = false;

      }

    }

  }

}

The other part of the code will include moving each part accordingly to the coordinate values from p5js. This would be relatively easy to achieve because we can calculate how much each part will move in mm when the motor turns by half or a single step.

Further coding can be done once we are ready with fully assembled hardware.

Future Plan

The time it takes to 3D print parts is the only problem we are facing until now. Once we are done printing our parts, we will be able to assemble the parts together soon.

For now, the future plan includes the functionality to successfully coordinate the Arduino component with the data sent from the p5.js component. Since the canvas sketch is drawn based on cartesian coordinates, while the physical drawing is based on polar coordinates, we are planning to program the project so that artistic output is achieved.

Demo

The software phase of the project can be tested here using this link. The project will be completed once the printing phase is completed.

Week 12 – Final Project Proposal (Phoebe & Fuad)

CONCEPT

In our last post we had come up with a game for our final project. After some further brainstorming, we thought it would be fun to try something other than a game, considering that this is what we did for our midterms. We thought about making an interactive system that could be experienced by multiple people at the same time. Our idea for the project is now to create a touchable “friendship lamp.” The basic idea is that we will build two lamps using two Arduino boards and LED strips. Each light will be equipped with different settings that can change the light pattern and color. These settings will be able to be manipulated within a program on p5.js, accessed on separate computers by the two users. After one user chooses the settings of their light, they then touch their lamp to send that light to the other user’s lamp. Communication between the two users can be simultaneous and there is no limit to the amount of times they can send each other messages. 

THE ROLE OF P5.js 

The sketch on p5.js will be a simple program with a few screens that allows the user to control the light they will send. They will be able to choose any color from a color wheel, and they will be able to choose from 3 different light modes: flicker, wave, and pulse. The choices made by the user will be stored by the program, and p5 will then send this data to the board of the other person’s lamp. However, data is not sent until some feedback is received from Arduino, explained in detail in the following section. 

THE ROLE OF ARDUINO 

A touch sensor and an LED strip would both be included in the Arduino circuit. When touched, the touch sensor transmits a signal to p5js, enabling p5js to transfer data to the Arduino board. Since p5js will be sending data about the color and pattern that the LED strip should light up in, the Arduino board receives this data and turns the light on as requested by the user.

HOW THEY COMMUNICATE 

As for the method of communication (serial mode) between the Arduino and p5js, we are still employing wires to transfer data back and forth at the time. However, because the two lamps and users in our original concept must be distanced from one another, we are exploring and, ideally, planning to include Bluetooth modules or, perhaps, an esp32 on our board to help with wireless communication between the two platforms.

PROGRESS 

We knew that we weren’t going to be able to have cross communication between two users without wireless Arduino boards, and that we would not be able to implement the touching aspect without an actual tactile sensor. Hence, our plan for this week was to finalize our idea and begin assembling the different components of the system separately. The p5 program is almost complete, with an exception to the code that will send the data to the wireless Arduino board. The sketch is shown below:

At the end of the program, the console prints out the data that would theoretically be sent to Arduino. Including the color value and the light mode. Also, because we do not have the tactile sensor yet, the light is “sent” figuratively by just pressing any key in the third step. 

For the Arduino component, we built our strips of 10 LED’s for each lamp and connected them to a board and focused on simply creating three different light modes that could be controlled within the Arduino code, separate from p5. The code that demonstrates how the various light modes are used to enable a flicker, wavy, or fading effect on the LED strip is provided below:

void loop() {
  NeoPixel.clear(); // set all pixel colors to 'off'. It only takes effect if pixels.show() is called
  NeoPixel.show();


  // WAVY
  //turn pixels to green one by one with delay between each pixel
  for (int pixel = 0; pixel < NUM_PIXELS; pixel++) { // for each pixel
    NeoPixel.setPixelColor(pixel, NeoPixel.Color(0, 255, 0)); // it only takes effect if pixels.show() is called
    // if(pixel > 0)
    // {
    //   NeoPixel.show();   // send the updated pixel colors to the NeoPixel hardware.
    //   NeoPixel.clear();
    // }
    NeoPixel.show();   // send the updated pixel colors to the NeoPixel hardware.
    NeoPixel.clear();
    
    delay(100); // pause between each pixel
  }

  // turn off all pixels for two seconds
  NeoPixel.clear();
  NeoPixel.show(); // send the updated pixel colors to the NeoPixel hardware.
  delay(2000);     // off time


  // FLICKERING:
  //turn on all pixels to red at the same time for two seconds
  for (int pixel = 0; pixel < NUM_PIXELS; pixel++) { // for each pixel
    NeoPixel.setPixelColor(pixel, NeoPixel.Color(255, 0, 0)); // it only takes effect if pixels.show() is called
  }
  NeoPixel.show(); // send the updated pixel colors to the NeoPixel hardware.
  delay(500);     // on time

  // turn off all pixels for two seconds
  NeoPixel.clear();
  NeoPixel.show(); // send the updated pixel colors to the NeoPixel hardware.
  delay(500);     // off time

  //PULSING
  brighten();
  darken();
}


// 0 to 255
void brighten() {
  uint16_t i, j;

  for (j = 0; j < 255; j++) {
    for (i = 0; i < NeoPixel.numPixels(); i++) {
      NeoPixel.setPixelColor(i, 0, 0, j);
    }
    NeoPixel.show();
    delay(10);
  }
  //delay(100);
}

// 255 to 0
void darken() {
  Serial.begin(9600);
  uint16_t i, j;

  for (j = 255; j > 0; j--) {
    for (i = 0; i < NeoPixel.numPixels(); i++) {
      NeoPixel.setPixelColor(i, 0, 0, j);
    }
    NeoPixel.show();
    delay(10);
    Serial.println(j);
  }
  delay(100);
}

Finally, a demo of the different modes is displayed below: