Inter Lab | Final Project

Stringless

—- by Alan Guo & Rainee Wang, Instructor: Andy Garica

 
 video edited by Rainee

 

CONCEPTION AND DESIGN

The basic concept of this project, Stringless, intends to create a Pipa without actual strings, when users touch the invisible laser strings, different pieces of music and patterns would be triggered. Combining the traditional Chinese culture with the modern technology nowadays, this project raises people awareness of Chinese traditional heritage and brings back the culture origins in our country.

The origin concept and idea of this project is raised by Rainee, my teammate (thanks Rainee so much for her marvelous great idea). She came up the idea from on exhibition in one Japan Museum, traditional Chinese Pipa from Tang dynesty are now perceived in Japan. The wars and a series of revolution happened in the latest several hundred years in China causes many precious traditional Chinese cultural relics to be kept away from their homeland and perceived in other countries all over the world. Thus, Rainee raised the idea that we could bring these ancient Pipa back to us with modern technology, and here comes our final project.

At the stage of designing, we thought about different artifacts and different ways to interact. We raised the idea to use a real Pipa, and while users are playing with the instrument, the sound would be recorded. Different patterns and images will then show up according to the pitch and rhythm the user is playing. However, we didn’t finally adapt this idea for most of our users are beginners to this specific instrument, so beautiful melody can’t be guaranteed and users may even don’t know how to play Pipa at all.

We also thought about how to present the project at first, we thought about different ways to show image. Putting the Pipa on the ground, suspended, horizontally or put it straight. We finally adapted the idea of letting the Pipa lean against a wall, which is the best way to present the image projected on it as well as to give users a better view of the whole piece.

Another part we struggled with was the interaction. We found the interaction of triggering music might be too simple, so we tried to add on more to the interaction. As inspired by Andy, after discussion with him, we decided that different strings can be triggered at the same time, so there exists a lot of combinations for four strings to play with. We also add more sets of music and patterns, at total we have three different sets of music and image to show.

Thus, we decided the plan of making a Pipa ourselves, and using laser strings to represent the real strings on Pipa for people to play with. Projectors would show different patterns to our instrument when users touch the laser strings.

FABRICATION AND PRODUCTION

For the producing procedure, there are mainly several parts as building the circuits, music projecting the images, laser cutting the Pipa and the coding process.

Building the Circuits:

During the whole process, we first built a prototype using cardboards, to try what is feasible and what is not. We cut the cardboard to roughly the shape of a Pipa and built part of the circuits on it to test. No doubt, there must be something happened beyond our expectation.

The first difficulty we met was that we used laser strings to represent the real string. We thought that we could see the red light of the laser, however, the lasers harps aren’t powerful enough to show the whole string, we can only see the dot it’s pointing. Only with smokes the string is visible. We tried to use the dry ice to generate smoke, but it didn’t work out so well.

The next hard part was to position the light dependent resistors  with laser harps. Andy encouraged us to use light dependent resistors to detect the laser strings. But it’s really really a hard job to put the resistors and laser harps exactly in places so that the small dot of laser can be located on the resistor.

After simple testing that both the laser harps and the resistors can work with each other, we decided to laser cut the Pipa out and then build the whole circuits on it. We cut with the shape of one ancient Chinese Pipa, along with the shape we put some traditional Chinese pattern on the wood, making it more like a traditional Chinese instrument.

After having the final vision for the Pipa, we started to built the circuits on it. For laser harps, we hot glued them on the board, and we cut small wood pieces to lift them up as well as making them more stable.

For the lightness resistors, as helped by Andy, we positioned them on a piece of wood by making four holes on the wood and insert the resistors on them. As the holes are exactly the position of the laser dots, each pair of resistor and laser harp finally matched perfected.

The final part of the circuits are the buttons, as we laser cut the Pipa with holes with the size of the buttons. It’s simple and easy to just put the buttons on.

Last but not least, the Arduino board along with the breadboard are positioned at the back of the instrument. We hide all the wires to the back, connecting the the Arduino board.

Music and Projecting the Images:

Rainee generated three sets of music from one famous piece of Pipa music “春江花月夜”, the three different sets of patterns are from real ancient Chinese Pipa. When playing different strings, different parts of the pattern would be projected to the surface of the instrument.

Coding Process:

The coding part of this project involves Arduino as input and Processing as the sound and visual outputs.

The Arduino reads the four lightness resistors as well as the three buttons. With the lasers, resistors would have a high number exceeding 800, and only about 500 without the laser. So the code reads the number of resistor and convert them into 0 and 1. 0 indicating no lights and 1 means the laser is pointing the resistor.

 int sensor1 = analogRead(A0);

  if (sensor1 > 800){
    values1 = 1;
  }else {
    values1 = 0;
  }

For the three buttons, we name their value as 1, 2, 3. Once a button is pressed, the button value would change correspondingly. Arduino detects whether a button is pressed and if its current state is not the previous one, meaning that the Arduino only detects the change of button from 0 to 1, the moment when the button is pressed. And the initial button is set to be 1, so the first set of music and pattern would be shown is default, only when pressing the second or the third button would the music and image alter.

  if (button1 == 1 && pb1 == 0) {
    values5 = 1;
  }
  else if (button2 == 1 && pb2 == 0){
    values5 = 2;
  }
  else if (button3 == 1 && pb3 == 0){
    values5 = 3;
  }

Thus, the four values of resistors and the one button value is detected by the Arduino and sent to Processing.

For the Processing part, the program detects whether the invisible string is triggered or not, once triggered, it would play a short piece of music and show one fragment of pattern on the screen.After the music stops, the image would gradually fade away on the screen and finally disappear. The code here detects whether the certain music is playing or not, if not, the image would become more transparent every loop until it disappears.

  //sound 0
  if (sensorValues[0] == 0 && p0 == 1 && sound0.isPlaying() == false){
    sound0.play();
    i0 = 0;
  }
  //image 0  
  if (sound0.isPlaying() == true){
    tint(255, i0);
    image(image0, 0, 0);
    i0 = i0 + 15;
  }
  else if (sound0.isPlaying() == false && i0 > 0){
    tint(255, i0);
    image(image0, 0, 0);
    i0 = i0 - 15;
  }

There is another function in Processing that reads the button value, and once is changes, the Processing would load a different set of music and pattern to show.

void button(int x){
  if (x != px){
    if (x == 1){
      sound0 = new SoundFile(this, "set101.wav");
      image0 = loadImage("1Flower.png");
    }
    else if (x == 2){
      sound0 = new SoundFile(this, "set201.wav");
      image0 = loadImage("1rich.png");
    }
    else if (x == 3){
      sound0 = new SoundFile(this, "set301.wav");
      image0 = loadImage("1click.png");
    }
  }
}

User Testing:

                     This photo actually comes from IMA show

When user testing out project, we haven’t finished adding all the sounds and images to the processing, also because we just set up everything from the cardboard to the laser cut Pipa, one of the lightness sensor is not working so well. So we tested the basic functions of our project as well as part of the music images. Through only a prototype, the project received plenty of comments and feedbacks for us to further work on.

Suggestions and feedbacks:

1. Our project has four laser strings but only one piece of music could be placed at a time, and the sound might repeat a lot if the user frequently “touches” the same string. 

2. It’s one of the difficult part to accurately install the laser harps and lightness resistors so that they could match perfectly. Or otherwise the project can’t actually function well. One professor suggest us to glue the laser harp and resistor at the same time using low temperature glue guns so we can adjust them easily.

3. We are using lasers strings representing the real strings on the instrument, so the users can’t really see the lasers. We received one feedback that we don’t actually need to see the strings, since it’s part of our concept that the project represents the heritage currently not reachable.

cDuring the user testing process, we have received a lot of useful and helpful feedbacks. From the way to interact, how to install and build up everything to even further develop the concept and meaning of the whole project. We adapted a lot of the suggestions and feedbacks to improve our final work.

The feedbacks from user testing influenced a lot in our later work, we changed many details according to the suggestion from the users, they also gave us many useful and helpful instructions as building the circuits and enriching the concepts.

CONCLUSIONS:

This project, Stringless, tends to arise people’s awareness of the traditional Chinese culture. By building a Pipa without string, a combination of modern technology and Chinese heritage, this project shed lights on the Chinese history and its meaningful sediments.

We think our project accomplished this goal, as during the user testing and IMA show, a lot of users showed their interests in the pattern and music. By drawing audience’s attention to the ancient pattern and image of Pipa, this project strengthens Chinese history heritage and culture.

If having more time, we would make further improvements to our project from different angles. First, we were planning to cover the back of the Pipa, making it a belly to hold all the wires as well as making it more like a real Pipa. We would also work on to have more and variable interactions with the project more than three sets of music and images. As Andy told us, there is no limit for a project, we can always do something more and make the project even better.

The interaction part of this project has two angles, the first one is that users interact with the four invisible strings and three buttons, the project would react back with different music and pattern showing on the surface. It is the interaction between the user and the computer programming. 

However, the second part is the user interacting with traditional Chinese culture, the heritage facing the danger of loss. When audience play with the instrument, they listen, see and feel the ancient culture of Chinese, these images are calling back users to pay more attention and awareness to the protecting of them. This part of interaction comes along with my definition with “interaction” that the two parts may not be restricted to the user and the programming, the environment or something else can also be part of the interaction. In this project, the third part is the Chinese culture that connects users with the project Stringless.

Taking the project as a whole, the building process involves difficulties and problems, but it is overall a very fun and exciting experience. As there are so many parts in the projects, from generating ideas, narrowing downing thoughts, making minimum valuable progress, building up everything, encountering and solving numerous problems, receiving suggestions and feedbacks, having changes all the time and finally showing the project to all the audience, every single part of the experience worth ten thousand words recording. The most precious thing I get is the experience of walking through all these parts. All these experience would help me so much in future project making and also problem solving process, that everything I met in this project helps me to do the next project better.

Long story short, besides all my experience and joy, this project, Stringless, points at the heritage of traditional Chinese Pipa and its culture. By making this modern combined Pipa, we aim to arise people’s awareness of Chinese traditional culture and call on protection of them. Through the real Pipa is not here with us, our project can only be stringless, we hope that more social awareness could be drawn on the culture heritage.

Maybe on day in the future, our Pipa can have real strings back.

TECHNICAL DOCUMENTATION:

Circuits:

Arduino:

int values1;
int values2;
int values3;
int values4;
int values5 = 1;
int button1 = 0;
int button2 = 0;
int button3 = 0;
int pb1;
int pb2;
int pb3;

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

void loop() {
  pb1 = button1;
  pb2 = button2;
  pb3 = button3;
  
  int sensor1 = analogRead(A0);
  int sensor2 = analogRead(A1);
  int sensor3 = analogRead(A2);
  int sensor4 = analogRead(A3);
  
  button1 = digitalRead(9);
  button2 = digitalRead(10);
  button3 = digitalRead(11);
  
  if (sensor1 > 800){
    values1 = 1;
  }else {
    values1 = 0;
  }
  
  if (sensor2 > 800){
    values2 = 1;
  }else {
    values2 = 0;
  }
  
  if (sensor3 > 800){
    values3 = 1;
  }else {
    values3 = 0;
  }
  
  if (sensor4 > 500){
    values4 = 1;
  }else {
    values4 = 0;
  }

  if (button1 == 1 && pb1 == 0) {
    values5 = 1;
  }
  else if (button2 == 1 && pb2 == 0){
    values5 = 2;
  }
  else if (button3 == 1 && pb3 == 0){
    values5 = 3;
  }

  Serial.print(values1);
  Serial.print(",");
  Serial.print(values2);
  Serial.print(",");
  Serial.print(values3);
  Serial.print(",");
  Serial.print(values4);
  Serial.print(",");
  Serial.print(values5);
  Serial.println();

  delay(100);
}

Processing:

import processing.serial.*;
import processing.sound.*;

SoundFile sound0;
SoundFile sound1;
SoundFile sound2;
SoundFile sound3;

PImage image0;
PImage image1;
PImage image2;
PImage image3;

float x;
float y;

int p0;
int p1;
int p2;
int p3;
int px;

int i0 = 0;
int i1 = 0;
int i2 = 0;
int i3 = 0;

String myString = null;
Serial myPort;
boolean playSound = true;

int NUM_OF_VALUES = 5;
int[] sensorValues;

void setup() {
  size(600, 1000);
  setupSerial();
}


void draw() {
  p0 = sensorValues[0];
  p1 = sensorValues[1];
  p2 = sensorValues[2];
  p3 = sensorValues[3];
  px = sensorValues[4];
  
  updateSerial();
  printArray(sensorValues);
  background(0);
  button(sensorValues[4]);

  //sound 0
  if (sensorValues[0] == 0 && p0 == 1 && sound0.isPlaying() == false){
    sound0.play();
    i0 = 0;
  }
  //sound 1
  if (sensorValues[1] == 0 && p1 == 1 && sound1.isPlaying() == false){
    sound1.play();
    i1 = 0;
  }
  //sound 2
  if (sensorValues[2] == 0 && p2 == 1 && sound2.isPlaying() == false){
    sound2.play();
    i2 = 0;
  }
  //sound 3
  if (sensorValues[3] == 0 && p3 == 1 && sound3.isPlaying() == false){
    sound3.play();
    i3 = 0;
  }
    
  //image 0  
  if (sound0.isPlaying() == true){
    tint(255, i0);
    image(image0, 0, 0);
    i0 = i0 + 15;
  }
  else if (sound0.isPlaying() == false && i0 > 0){
    tint(255, i0);
    image(image0, 0, 0);
    i0 = i0 - 15;
  }
  //image 1
  if (sound1.isPlaying() == true){
    tint(255, i1);
    image(image1, 0, 0);
    i1 = i1 + 15;
  }
  else if (sound1.isPlaying() == false && i1 > 0){
    tint(255, i1);
    image(image1, 0, 0);
    i1 = i1 - 15;
  }
  //image 2
  if (sound2.isPlaying() == true){
    tint(255, i2);
    image(image2, 0, 0);
    i2 = i2 + 15;
  }
  else if (sound2.isPlaying() == false && i2 > 0){
    tint(255, i2);
    image(image2, 0, 0);
    i2 = i2 - 15;
  }
  //image 3
  if (sound3.isPlaying() == true){
    tint(255, i3);
    image(image3, 0, 0);
    i3 = i3 + 15;
  }
  else if (sound3.isPlaying() == false && i3 > 0){
    tint(255, i3);
    image(image3, 0, 0);
    i3 = i3 - 15;
  }
}

void setupSerial() {
  myPort = new Serial(this, Serial.list()[1], 9600);
  myPort.clear();
  myString = myPort.readStringUntil( 10 );
  myString = null;
  sensorValues = new int[NUM_OF_VALUES];
}

void updateSerial() {
  while (myPort.available() > 0) {
    myString = myPort.readStringUntil( 10 );
    if (myString != null) {
      String[] serialInArray = split(trim(myString), ",");
      if (serialInArray.length == NUM_OF_VALUES) {
        for (int i=0; i<serialInArray.length; i++) {
          sensorValues[i] = int(serialInArray[i]);
        }
      }
    }
  }
}

void button(int x){
  if (x != px){
    if (x == 1){
      sound0 = new SoundFile(this, "set101.wav");
      sound1 = new SoundFile(this, "set102.wav");
      sound2 = new SoundFile(this, "set103.wav");
      sound3 = new SoundFile(this, "set104.wav");
      image0 = loadImage("1Flower.png");
      image1 = loadImage("2Flower.png");
      image2 = loadImage("3Flower.png");
      image3 = loadImage("4Flower.png");
    }
    else if (x == 2){
      sound0 = new SoundFile(this, "set201.wav");
      sound1 = new SoundFile(this, "set202.wav");
      sound2 = new SoundFile(this, "set203.wav");
      sound3 = new SoundFile(this, "set204.wav");
      image0 = loadImage("1rich.png");
      image1 = loadImage("2rich.png");
      image2 = loadImage("3rich.png");
      image3 = loadImage("4rich.png");
    }
    else if (x == 3){
      sound0 = new SoundFile(this, "set301.wav");
      sound1 = new SoundFile(this, "set302.wav");
      sound2 = new SoundFile(this, "set303.wav");
      sound3 = new SoundFile(this, "set304.wav");
      image0 = loadImage("1click.png");
      image1 = loadImage("2click.png");
      image2 = loadImage("3click.png");
      image3 = loadImage("4click.png");
    }
  }
}

Thanks^

Inter Lab | Recitation User Testing

User Testing For others project

One project I user tested in the recitation is Lane’s project “Embracing Sadness: End 2020”. This project concentrates on the sadness and negative emotions in the tough year 2020. When sitting down on the right position, plastic balls filled with feathers above my head would rotate, representing that the sadness would gradually flow away from us. Also, I could control two balls in front of me, and when rotating them, images on the screen would change. As I constantly rotate the balls in one direction, the sad emoji on the screen would be vague and finally fade away.

I really like the concept of this project as we should embrace our sadness and let go of them to enter the next brand new year. Especially after Lane explained to me her idea, I found the concept meaningful to all of us. Also, I really like the part that balls above me could rotate, it’s really fun to play with. The rotating balls add motion and engage to the project.

For  suggestions and feedbacks:

1. I think the concept of embracing sadness might be a little bit vague when first looking at the project, I don’t really get the idea that the project conveys to me. Maybe the project can represent the sadness in a more clear way.

2. If I stay too long time sitting, the balls would rotate too fast and hit the frame poles. The motors might be adjusted to a lower speed so that the balls could rotate smoothly.

3. The image on the screen contains only a sad face. I think the idea of embracing sadness can be better convinced if the screen shows something more than the fading of sadness emoji. Something like a laughing face shown when the sadness disappears can be better.

User Testing For my project

When user testing out project, we haven’t finished adding all the sounds and images to the processing, also because we just set up everything from the cardboard to the laser cut Pipa, one of the lightness sensor is not working so well. So we tested the basic functions of our project as well as part of the music images. Through only a prototype, the project received plenty of comments and feedbacks for us to further work on.

Suggestions and feedbacks:

1. Our project has four laser strings but only one piece of music could be placed at a time, and the sound might repeat a lot if the user frequently “touches” the same string. I would adjust the program codes so that different strings can be triggered at the same time so that all four strings can be used just like a real instrument. Also, music should be prevented from playing over again before it ends.

2. It’s one of the difficult part to accurately install the laser harps and lightness resistors so that they could match perfectly. Or otherwise the project can’t actually function well. One professor suggest us to glue the laser harp and resistor at the same time using low temperature glue guns so we can adjust them easily.

3. We are using lasers strings representing the real strings on the instrument, so the users can’t really see the lasers. We received one feedback that we don’t actually need to see the strings, since it’s part of our concept that the project represents the heritage currently not reachable.

most and least successful parts:

For the successful parts, users like the pattern and music of the project a lot. The images, pattern and music are part of  ancient Chinese culture, they are also the key points this project wants to convey. Through playing the instrument, the user can really interact with it and receive what the project wants to tell. However, the project we presented was still a prototype with only part of the functions, users can’t have a complete understanding and interaction with it, which are the parts we need to further work on.

During the user testing process, we have received a lot of useful and helpful feedbacks. From the way to interact, how to install and build up everything to even further develop the concept and meaning of the whole project. We would pay much attention to all these feedbacks and continually work on these specific parts to better complete and display our project.

Inter Lab | Recitation 9

Arduino and Processing Documentations

In this recitation, I tried to make some fun actions with the camera captured image. Inspired by the example codes given, I change the size and positions of each pixel of the camera captured image. These two values are controlled by the potentiometers from Arduino. By rotating the two potentiometers, the face of the user or whatever the camera is capturing would be formed by pixels of different size and position, making an interesting image to interact with.

This work is associated with the computer vision, since the computer camera inputs a image, and it process through different algorithms and output new images.

Codes for Arduino

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

void loop() {
  int sensor1 = analogRead(A0);
  int sensor2 = analogRead(A1);

  Serial.print(sensor1);
  Serial.print(",");
  Serial.print(sensor2);
  Serial.println();

  delay(100);
}

Codes for Processing

import processing.serial.*;

import processing.video.*; 
String[] cameras = Capture.list();

String myString = null;
Serial myPort;

int NUM_OF_VALUES = 2;
int[] sensorValues; 

Capture cam;


void setup() {
  size(640, 480); 
  printArray(cam.list());
  
  cam = new Capture(this, cam.list()[0]);
  cam.start(); 

  setupSerial();
}

void draw() {
  updateSerial();
  clear();
  
  printArray(sensorValues);
  if (cam.available()) { 
   cam.read(); 
  } 
  if (sensorValues[0] < 10){
    image(cam, 0, 0);
  }else{
  float dotSpacing = map(sensorValues[0], 0, 1023, 1, 20);
  float dotSize = map(sensorValues[1], 0, height, 1, dotSpacing * 1.4);
  for (int x = 0; x < cam.width; x += dotSpacing) {
    for (int y = 0; y < cam.height; y += dotSpacing) {
      color c = cam.get(x, y);
      fill(c);
      noStroke();
      circle(x, y, dotSize);
    }
   }
  }
}

void setupSerial() {
  printArray(Serial.list());
  myPort = new Serial(this, Serial.list()[1], 9600);
  myPort.clear();
  myString = myPort.readStringUntil( 10 );
  myString = null;
  sensorValues = new int[NUM_OF_VALUES];
}

void updateSerial() {
  while (myPort.available() > 0) {
    myString = myPort.readStringUntil( 10 );
    if (myString != null) {
      String[] serialInArray = split(trim(myString), ",");
      if (serialInArray.length == NUM_OF_VALUES) {
        for (int i=0; i<serialInArray.length; i++) {
          sensorValues[i] = int(serialInArray[i]);
        }
      }
    }
  }
}

Inter Lab | Final Project Essay

A Rainy Night in Spring

Statement and Purpose:

In this project of A Rainy Night in Spring, Music can be visualized, and the metaphor and the scene from an ancient musical piece can be reimagined using modern technologies. This project intends to redefine the concept of musical instruments, revolutionize the way of making and appreciating music, and modernize the ancient traditional Chinese music culture by adding modern elements. As well as foster the awareness of protecting culture, arise the pride of our history and culture.

The targeted audience of our project are those who wants to expand their senses to appreciate music. Cultural lovers, anti-war supporters, culture protectors, people who are interested in music, digital heritage, and design are all welcomed by this project.

Project Plans:

Laser-cutting: We want to laser cut a wood panel to represent the concept of pipa, or as a metaphor of the Chinese musical instruments, or even the lost Chinese cultural heritage at all.

Sensors and Inputs: We would add sensors on the “instrument”, they would be the light resistors, detecting whether or not the laser is pointing at it. Laser lines would be used to represent the strings of the instrument. The sensors would be triggered when the user holds the pipa on their lap and plays it.

Processing and Outputs: When playing the instruments, different patterns will be projected on the panel. The very patterns are those from ancient instruments and drawings with the concept and meaning of ancient Chinese culture that are not being well reserved these days.

We would finish building the real instrument in the next week, figuring out how  could the input and output work. And we would continue working on the patterns and music presented by the processing in the week after, to make our project more complete and convey the very idea we want.

Context and Significance:

Due to wars and the cultural revolution of China, China’s precious cultural relics have been plundered and destroyed. Now if we want to see the most glorious historical remains of the great Tang dynasty, we have to go to Japan. It is sadly true that Japanese people see and know more about pipa than Chinese. It is time to use some technology to bring our culture back.

春江花月夜[ A Rainy Night in Spring] is one of the oldest and most famous Pipa pieces. It pictures a poetic and Zen atmosphere on a spring night, combining metaphors like flowers, warm river water, and the moonlight. Together it creates a beautiful soundscape.  Although many people find this musical piece pleasant to listen to, people who are not familiar with traditional Chinese culture can hardly understand it culturally, losing the most important part. 

This project intends to visualize the music piece for audiences to better feel the atmosphere of the music and to spread the traditional Chinese culture by making it modernized and readable to all. 

Inter Lab | Recitation 8

Processing Documentations

Exercise 1: Make a Processing Etch A Sketch

For this exercise, I used two potentiometers to control the position of the pen on processing. The Arduino could read the data from potentiometers and send them to the processing.

The interaction in this exercise is pretty intuitive that the user can interact and control the pen by switching the potentiometers.

 

Exercise 2: Make a musical instrument with Arduino

In this exercise, the buzzer is controlled by the position of the mouse in the processing. The circuit building part isn’t that hard, all I have to do is to connect the buzzer to the Arduino. For the coding part, I struggled sometime trying to figure out how the duration variable of the buzzer works. Finally, I found out one way that only when pressing the mouse would the buzzer work, in this way, the buzzer can show both the frequency and the duration. So, I passed the third  variable to the Arduino to show whether the mouse is pressed.

The interaction in this exercise is similar to exercise 1, that user’s interaction is directed showed by the sound of the buzzer.

Homework  Documentations

For the homework, since the codes for the star shape as well as the rotating codes are given to us, the processing part code isn’t that hard. For the Arduino part, the difficult part is to detect whether the button is pressed, and how should the press of button operation being illustrated in integer variables. I used HIGH and several if statements to accomplish that. Also, one difficulty I met was how to connect the buttons to the Arduino, I checked the documentations before to help me build the circuits of buttons and resistors.

For the Interaction, by pressing the button, the star would show up or disappear. The interaction here is pretty simple and easy.

Below are the long codes:

Exercise 1:

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

void loop() {
  int sensor1 = analogRead(A0);
  int sensor2 = analogRead(A1);

  Serial.print(sensor1);
  Serial.print(",");
  Serial.print(sensor2);
  Serial.println();

  delay(100);
}

import processing.serial.*;

float x;
float y;
float px;
float py;

String myString = null;
Serial myPort;

int NUM_OF_VALUES = 2;
int[] sensorValues; 

void setup() {
  size(600, 600);
  background(255);
  setupSerial();
}

void draw() {
  px = sensorValues[0];
  py = sensorValues[1];
  updateSerial();
  x = sensorValues[0];
  y = sensorValues[1];
  printArray(sensorValues);
  
  line(px, py, x, y);
}

void setupSerial() {
  printArray(Serial.list());
  myPort = new Serial(this, Serial.list()[1], 9600);
  myPort.clear();
  myString = myPort.readStringUntil( 10 );
  myString = null;
  sensorValues = new int[NUM_OF_VALUES];
}

void updateSerial() {
  while (myPort.available() > 0) {
    myString = myPort.readStringUntil( 10 );
    if (myString != null) {
      String[] serialInArray = split(trim(myString), ",");
      if (serialInArray.length == NUM_OF_VALUES) {
        for (int i=0; i<serialInArray.length; i++) {
          sensorValues[i] = int(serialInArray[i]);
        }
      }
    }
  }
}

Exercise 2:

#define NUM_OF_VALUES 3

int tempValue = 0;
int valueIndex = 0;
float fre ;
float dur ;
int pin = 9;

int values[NUM_OF_VALUES];


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

void loop() {
  getSerialData();
  fre = map (values[0], 0, 500, 0, 3000);
   
  if (values[2] == 1){
     tone(pin, fre, values[1]);
   }
}
    

void getSerialData() {
  if (Serial.available()) {
    char c = Serial.read();
    switch (c) {
      case '0'...'9':
        tempValue = tempValue * 10 + c - '0';
        break;
      case ',':
        values[valueIndex] = tempValue;
        tempValue = 0;
        valueIndex++;
        break;
      case 'n':
        values[valueIndex] = tempValue;
        tempValue = 0;
        valueIndex = 0;
        break;
        for (int i = 0; i < NUM_OF_VALUES; i++) {
          Serial.print(values[i]);
          if (i < NUM_OF_VALUES - 1) {
            Serial.print(',');
          }
          else {
            Serial.println();
          }
        }
        break;
    }
  }
}

import processing.serial.*;

int NUM_OF_VALUES = 3;

Serial myPort;
String myString;

int values[] = new int[NUM_OF_VALUES];

void setup() {
  size(500, 500);
  background(255);

  printArray(Serial.list());
  myPort = new Serial(this, Serial.list()[1], 9600);
  myPort.clear();
  myString = myPort.readStringUntil( 10 );
  myString = null;
}

void draw() {
  background(255);

  values[0] = mouseX;
  values[1] = mouseY;
  if (mousePressed) {
    values[2] = 1;
  }else{
    values[2] = 0;
  }
  line(pmouseX, pmouseY, mouseX, mouseY);

  sendSerialData();
  println(values);
}

void sendSerialData() {
  String data = "";
  for (int i=0; i<values.length; i++) {
    data += values[i];
    if (i < values.length-1) {
      data += ",";
    } 
    else {
      data += "n";
    }
  }
  myPort.write(data);
}


void echoSerialData(int frequency) {
  if (frameCount % frequency == 0) myPort.write('e');

  String incomingBytes = "";
  while (myPort.available() > 0) {
    incomingBytes += char(myPort.read());
  }
  print( incomingBytes );
}

Homework:

int button1;
int button2;
int prebutton1 = LOW;
int prebutton2 = LOW;
int values1;
int values2;

void setup() {
  Serial.begin(9600);
  pinMode(9, INPUT);
  pinMode(11, INPUT);
}

void loop() {
  int button1 = digitalRead(9);
  int button2 = digitalRead(11);
  if (button1 == HIGH) {
    if (button1 != prebutton1){
      if (values1 == 1){
        values1 = 0;
      }else{
        values1 = 1;
      }
     }
    }
    prebutton1 = button1;
    
    if (button2 == HIGH) {
    if (button2 != prebutton2){
      if (values2 == 1){
        values2 = 0;
      }else{
        values2 = 1;
      }
     }
    }
  prebutton2 = button2;
    
  Serial.print(values1);
  Serial.print(",");
  Serial.print(values2);
  Serial.println();

  delay(100);
}

import processing.serial.*;

float x;
float y;

String myString = null;
Serial myPort;


int NUM_OF_VALUES = 2;
int[] sensorValues;


void setup() {
  size(600, 600);
  background(0);
  setupSerial();
}

void draw() {
  updateSerial();
  printArray(sensorValues);

  background(0);
  showImage();
}

void setupSerial() {
  printArray(Serial.list());
  myPort = new Serial(this, Serial.list()[1], 9600);
  myPort.clear();
  myString = myPort.readStringUntil( 10 );
  myString = null;
  sensorValues = new int[NUM_OF_VALUES];
}

void updateSerial() {
  while (myPort.available() > 0) {
    myString = myPort.readStringUntil( 10 );
    if (myString != null) {
      String[] serialInArray = split(trim(myString), ",");
      if (serialInArray.length == NUM_OF_VALUES) {
        for (int i=0; i<serialInArray.length; i++) {
          sensorValues[i] = int(serialInArray[i]);
        }
      }
    }
  }
}

void star(float x, float y, float radius1, float radius2, int npoints) {
  float angle = TWO_PI / npoints;
  float halfAngle = angle/2.0;
  beginShape();
  for (float a = 0; a < TWO_PI; a += angle) {
    float sx = x + cos(a) * radius2;
    float sy = y + sin(a) * radius2;
    vertex(sx, sy);
    sx = x + cos(a+halfAngle) * radius1;
    sy = y + sin(a+halfAngle) * radius1;
    vertex(sx, sy);
  }
  endShape(CLOSE);
}

void showImage(){
  if (sensorValues[0] == 1){
    pushMatrix();
    translate(width*0.3, height*0.3);
    rotate(frameCount / 200.0);
    star(0, 0, 30, 70, 5); 
    popMatrix();
  }
  
  if (sensorValues[1] == 1){
    pushMatrix();
    translate(width*0.7, height*0.7);
    rotate(frameCount / 100.0);
    star(0, 0, 80, 100, 40); 
    popMatrix();
  }
}

Inter Lab | Final Project Proposal

1. Noice Map

To continue my midterm project that focuses on the noise pollution, one serious problem in nowadays modern cities, processing can deal with the noise pollution in many ways. This noise map project intends to raise people’s intention of the noise pollution problem by alerting the audience the noise around them.

The noise map is a graphic representation of the sound level distribution in a certain area.

Bureau of Transportation Statistics/Screenshot by NPR                   

With processing, the noice map can be something more than a simple map with different colors, more graphs and animations can be added to it. Using sensors like sound sensor or loudness sensor, the Arduino can detect the noise level in a certain area. In this way, with realtime data, the processing can produce one type of new noise map with animations showing the realtime changes of the noise level. 

Potential Audience: People who are suffering from the noise pollution and whoever is concerned with this serious social problem.

Limits and Difficulties: To detect the noise level in one area, multiple sensors might be needed. And the project might can’t adapt to different environment easily since sensors need to be relocated and the map also needs to alter.

2. Dancing Song

This project is about combining people’s movements, music and image together. With the different movements of the user, such as waving hands, walking around, different patterns of sound would be played. As the user moves around one certain area, part of his image would be shown on the screen. The more user moves, the more parts of the full image would appear. To get the whole image, the user has to play a piece of music using his/her own body.

This project is inspired by the phenomenon that nowadays many students and office workers would sit at their desks all day long, with headphones on and not having exercise at all. The interaction of this project could tell users to enhance exercise. Only by having enough exercise, the user can enjoy the music, which is created and performed by themselves.

Potential Audience: Students, office workers and people who stay indoor without enough exercise.

Limits and Difficulties: It would be hard to detect the different movements of the user using the Arduino sensors, those sensors might can’t precisely detect the user’s acts. Also, the amounts of music pieces, like sounds from different instruments are limited. The processing might use receive sounds from the outside in realtime. But the music produced with such might not be that fair-sounding.

3. Singing Weather

Inspired by the Weather Thingy by Adrien Kaeser (discussed in the final project research post). That is an interactive project which can produce with data come from realtime weather. The music would alter with the changing of the wind and rain. By shifting the input and output, here emerges a new interactive project that can detect the music and produce the corresponding weather. This project intends to alert people of the weather changes all around the world.

By detecting the beats, rhythm and other features of the music, the Arduino would input certain data to the processing, where the weather on the screen would alter according to changes in the music. With passionate music, there could have extreme weathers, and when the music is slow and quiet, the weather would also clam down to peace.

Nature’s symphony. Acrylic.

However, as the time goes on, the weather presented with be more severe even the music doesn’t change, indicating the weather changes now happening as more extreme weather takes place nowadays.

Potential Audience: People who concerns with the global weather changes as well as people who are fond of music and sound visualization.

Work Cited

Visnjic, Filip. “Weather Thingy – Real Time Climate Sound Controller”. Creativeapplications.Net, 2018, https://www.creativeapplications.net/sound/weather-thingy-real-time-climate-sound-controller/.

Inter Lab | Recitation 7

Processing Documentations

In this recitation, I created a hexagram, looks like a snowflake, as the basic graph.  According to the instructions, I used several different arrays to store positions, colors, speed and size. After displaying the 100 shapes on the screen, I added movements just like in the previous class, the snowflakes would move randomly and bounce back once they touch the bound. I also added two keyboard functions such that when pressing ‘c’, all the snowflakes would change color randomly. And when pressing UP and DOWN, the size of snowflakes would change within a certain range.

int n = 100;
float s3 = sqrt(3);
float x[] = new float [n];
float y[] = new float [n];
float xs[] = new float [n];
float ys[] = new float [n];
float s[] = new float [n];
color ct[] = new color [n];
color cc[] = new color [n];

void setup(){
  size(600, 600);
  background(255);
  for (int i = 0; i < 100; i ++){
    x[i] = random(width);
    y[i] = random(height);
    s[i] = 10;
    xs[i] = random(-1, 1);
    ys[i] = random(-1, 1);
    ct[i] = color(random(255), random(255), random(255), 50);
    cc[i] = color(random(255), random(255), random(255), 50);
  }
}

void draw(){
    background(255);
    for (int i = 0; i < 100; i ++){
      if (x[i] <= 0 || x[i] >= width){
        xs[i] *= -1;
      }
      if (y[i] <= 0 || y[i] >= width){
        ys[i] *= -1;
      }
     x[i] += xs[i];
     y[i] += ys[i];
    shape(i);
  }
}

void shape(int i){
  fill(ct[i]);
  triangle(x[i], y[i]-2*s3*s[i]/3, x[i]-s[i], y[i]+s3 * s[i] /3, x[i] + s[i], y[i] + s3 * s[i] /3);
  triangle(x[i] - s[i], y[i] - s3*s[i]/3, x[i] + s[i], y[i] - s3*s[i]/3, x[i], y[i] + 2*s3*s[i]/3);
  fill(cc[i]);
  circle(x[i] , y[i], 2*s[i]/s3);
}

void keyPressed(){
  if (key == 'c'){
    for (int i = 0; i < 100; i ++){
     ct[i] = color(random(255), random(255), random(255), 50);
     cc[i] = color(random(255), random(255), random(255), 50);
     }
  }
  if (key == CODED){
    if (keyCode == UP){
      for (int i = 0; i < 100; i ++){
        if (s[i] < 50){
          s[i] ++;
        }
      }
    }else if (keyCode == DOWN){
      for (int i = 0; i < 100; i ++){
        if (s[i] > 10){
          s[i] --;
        }
      }
    }
  }
}

For the additional homework, I first tried to code it by myself. I finished part of the homework as mapping the different dots and having them changing size and position. But it turns out that my code doesn’t present the animation in the exact way of the example, and the animation can’t deal with dots too close to the mouse. 

Thus, I attended the workshop for this homework. Im the workshop, I learned about the min, max function along with other codes that helped a lot in polishing the animation. I also used functions to rewrite the code provided in the workshop in my own style.

int row = 25;
int column = 25;
int total = row * column;
int padding = 140;
float[] R = new float [total];
float[] x = new float [total];
float[] y = new float [total];
float[] xs = new float [total];
float[] ys = new float [total];
float[] xn = new float [total];
float[] yn = new float [total];
float[] s = new float [total];

void setup(){
  size(800, 800);
  background(255);
  for (int j = 0; j < row; j++){
    for (int i = 0; i < column; i++){
      int index = i + j * column;
      x[index] = map(i, 0,  column - 1, padding, width - padding);
      y[index] = map(j, 0,  row - 1, padding, width - padding);
      xs[index] = map(i, 0,  column - 1, padding, width - padding);
      ys[index] = map(j, 0,  row - 1, padding, width - padding);
      s[index] = 1;
    }
  }
}

void draw(){
  background(255);
  for ( int i = 0; i < total; i ++){
    
    calculatePosition(i);
    
    //changePosition(i);
    
    changePositionWithLerp(i);
    
    changeSize(i);
    
    drawCircle(i);
  }
}

void drawCircle(int i){
  pushMatrix();
  pushStyle();
  translate(xs[i], ys[i]);
  scale(s[i]);
  fill(0);
  noStroke();
  circle(0, 0, 10);
  popMatrix();
  popStyle();
}

void calculatePosition(int i){
  R[i] = dist(mouseX, mouseY, x[i], y[i]);
  R[i] = max(R[i], 0,01);
}

void changeSize(int i){
  s[i] = 100 / R[i];
  s[i] = max(s[i], 0.4);
  s[i] = min(s[i], 2);
}

void changePosition(int i){
  xs[i] =x[i] - (35 / R[i]) * (mouseX - x[i]);
  ys[i] =y[i] - (35 / R[i]) * (mouseY - y[i]);
}

void changePositionWithLerp(int i){
  xn[i] =x[i] - (35 / R[i]) * (mouseX - x[i]);
  yn[i] =y[i] - (35 / R[i]) * (mouseY - y[i]);
  xs[i] = lerp(xs[i], xn[i], 0.05);
  ys[i] = lerp(ys[i], yn[i], 0.05); 
}

Answers to the Questions

1. In your own words, please explain the difference between having your for loop from Step 2 in setup() as opposed to in draw().

In the setup(), the code provides one image with 100 random snowflakes on the screen. It is because that code in the setup() would be processed only once.

While when putting the loop in the draw(), the code produces an animation with snowflakes appearing with different positions and colors all the time on the screen. Since the processing will run codes in the draw() all the time, the loop would assign different positions and colors to dots every time draw() is processed. So, the snowflakes are having random data all the time and shown as strange animations.

2.What is the benefit of using arrays? How might you use arrays in a potential project?

By using arrays in processing, I can deal with a large amount of data at same time without manually assign data to every variable. Arrays make it convenient to copy and present similar shapes with slight differences.

For the project, I might face the situation where I have to input a large amount of information or assign various of data to different variables for a visual presentation. In these cases, using arrays can greatly reduce my time in coding as well as  make the codes tidy and easy to read.

Inter Lab | Final Project Research

Two Interactive Projects

Weather Thingy

This interactive project by Adrien Kaeser is about playing music using real time climate-related events, the climate changes would modify the settings of musical instruments. This device contains a weather station that has a rain gauge, a wind vane and an anemometer. The user can control a brightness sensor as well as buttons to modify the value received from the different sensors.

I regard this as a great interactive project because it contains not only the interaction between the user and device, but also takes the climate surrounding in to consideration. According to Ernest Edmonds, this project contains “responding” and also “influencing”, which can be canned is “Dynamic-Interactive (Influencing) “. With the introduce of the climate, the project widens the range of interaction it provides. The Weather Thingy involves both the interaction between users and devices and the interaction between users and the whole environment.

Soundmachines

This Soundmachines is a custom-built instrument for performing electronic music by visual pattens on record-sized discs. By moving the pin into different pattens on the discs, music would changes its speed and rhythm. With several different discs at the same time, various music can be performed only by moving around the pin.

This project actually only has limit interaction with the users and audiences. Since the amount of discs and the pattens on them can’t change, the user have limited options when interacting with the device. But just as the producers said in their reflection, they intended to improve by using “easily changeable or even paintable discs”. Also they were thinking about using cameras to detect the audience and let the audience become part of the performs, too. By having such improvements, I think this Soundmachines can have further interactions with the users. If the users can make their own discs to play and the audience can involve in the music, this could also be a “Dynamic-Interactive (Influencing)” rather than only responding to the user in limited ways.

About “Interaction”

My own definition about “interaction” actually changed a lot since the beginning of the class. At first, after reading The Art of Interactive Design, my definition is about two objects having input, processing and output. But after having the group research project and the midterm project, I noticed that interaction can involve not only the user and the device, the outside environment can also be one crucial part of interaction.

This idea of having device, user and environment together goes further after I read  Art, Interaction and Engagement by Ernest Edmonds. As he mentioned different levels of interaction, from responding, varying, influencing to communicating. A lot of more are involved and taken into consideration besides the device and user. We can have the elements of time, environment and internal changes within the interaction. So now I would think interaction with a boarder range, not only the device and the user, everything else surrounding may be used as part of the interactive process.

I researched in the field of sound, since my midterm project is about sound pollution, I want to do some further research and find out whether my final project would continue focus on the sound and noice. The two projects above are both interactive, but I would think the Weather Thingy fits my definition of interaction more as it contains the environment as part of the interactive process. For the second one, the Soundmachines, this project also focuses on sound, but I would think it as restricted since the user own has limited options with the device and no surrounding element is involved. With the improvements that the producers said to make, I think this project would be more interactive and fits my definition of interaction more.

Work Cited

Crawford, Chris. The Art of Interactive Design. No Starch Press, 2002.

Edmonds, Ernest. “Art, Interaction And Engagement”. 2011 15Th International Conference On Information Visualisation, 2011. IEEE, doi:10.1109/iv.2011.73. Accessed 12 Nov 2020.

Scholz, Alexander. “Soundmachines [Arduino, Processing, Objects]”. Creativeapplications.Net, 2012, https://www.creativeapplications.net/processing/soundmachines-objects-sound/.

Visnjic, Filip. “Weather Thingy – Real Time Climate Sound Controller”. Creativeapplications.Net, 2018, https://www.creativeapplications.net/sound/weather-thingy-real-time-climate-sound-controller/.

Inter Lab | Recitation 6

Processing Documentations

In this recitation, I built on the work before, adding interactions to the work I did last recitation. With the keyboard and mouse functions learnt this week, I use these elements in the interactive animation.

 Wherever the mouse goes, rectangles with different size would appear around the mouse. And by pressing “c” on the keyboard, rectangles will have random colors. Also, the “b” can clear the whole canvas. Thus, this animation produces similar drawings as the work last week, but now users can interact and create their own drawing using mouse and keyboard.

color c;
float x;
float y;
float sx;
float sy;
void setup(){
  
  size(800, 800);
  background(255);
  rectMode(CENTER);
  noFill();
  strokeWeight(1);
}

void draw(){
  if (keyPressed && key == 'c'){
    c = color(random(255), random(255), random(255));
  }
  
  sx = (width / 100) * int(random(1, 11));
  sy = (height / 100) * int(random(1, 11));
  x = (width / 20) + (width / 10) * int(random(0, 10));
  y = (height / 20) + (height / 10) * int(random(0, 10));
  if (dist(mouseX, mouseY, x, y) <= width / 5){
    
  stroke(c);
  rect(x, y, sx, sx);
  }
}

void keyPressed(){
  if (key == 'b'){
    background(255);
  }
}

Homework Documentations

float R = width / 2.5;
float r = R / 2;
float x;
float c;
float y;
float X;
float Y;

void setup(){
  size(600, 600);
  background(255);
  strokeWeight(15);
  colorMode(HSB);
}

void draw(){
  
  background(255);
  if (R > width / 2){
    x = width / -300;
  }
  else if (R < width / 5){
    x = width / 300;
  }
  if (c >= 255){
    y = -1;
  }
  if (c <= 0){
    y = 1;
  }
  R += x;
  c += y;
  stroke(c, 255, 220);
  X = mouseX;
  Y = mouseY;
  r = R / 2;
  if (mouseX < r) {
     X = r;
  }else if ( mouseX > width - r) {
     X = width - r;
   }
  if (mouseY < r) {
     Y = r;
   }else if ( mouseY > height - r) {
     Y = height - r;
   }
   
  ellipse(X, Y, R, R);
}

In this recitation, I practiced a lot with the animation. Some functions I found especially interesting are:

mouseX  mouseY

ifkeyPressed && key == ‘c’ ){  }

colorModeHSB ),  stroke( c, 255, 220 )

Inter Lab | Recitation 5

Processing Documentations

In this recitation, I found one picture from the websites given to us.

This is one picture created by Vera Molnar in 1973, using computer graphic and ink on paper. This artifact is now in Courtesy of Senior & Shopmaker Gallery in New York.

I choose this picture for it looks cool to me and I think processing is able to draw something similar. And it turns out to be an easy task but super time consuming. The code for this is too long, so I would attach it at the very bottom of this documentation.

This drawing looks similar to the original artifact, since it consists only rectangles, it’s not difficult to imitate it, however, creating the rectangles one by one has no fun at all. It took me a huge amount of time to copy each rectangles and made small changes to each of them.

So, after Tuesday’s class about the animation. I used the draw() loop to create this drawing again. Using draw() and random(), the code can do the repeating tasks for me. Only using several minutes, I wrote the new code that is a lot tidy and short, and more interesting.

Here is the code for the second drawing.

float x = 0;
float y = 0;
float size = 0;
color c;
void setup(){
  size(800, 800);
  background(255, 255, 255);
  rectMode(CENTER);
  strokeWeight(2);
  noFill();
}

void draw(){
  if (millis() > 5000) {
    noLoop();
  }
  c = color(random(0, 256), random(0, 256), random(0, 256));
  x = 70 + 110 * int(random(0, 7));
  y = 70 + 110 * int(random(0, 7));
  size = 10 * int(random(1, 11));
  stroke(c);
  rect(x, y, size, size);
}

Below is the long and boring code for the first drawing.

size(800, 800);
background(255, 255, 255);

rectMode(CENTER);
strokeWeight(2);
//1, 1
stroke(#7896FF);
rect(70, 70, 100, 100);
stroke(#789600);
rect(70, 70, 80, 80);
stroke(#FF9619);
rect(70, 70, 20, 20);
//1, 2
stroke(100, 185, 123);
rect(180, 70, 100, 100);
stroke(#E5F2AB);
rect(180, 70, 90, 90);
//1, 3
stroke(#62DCE8);
rect(290, 70, 100, 100);
stroke(#EBB9F5);
rect(290, 70, 10, 10);
//1, 4
rect(400, 70, 100, 100);
//1, 5
stroke(#FFCD90);
rect(510, 70, 100, 100);
stroke(#7896FF);
rect(510, 70, 50, 50);
//1, 6
stroke(#D4FF79);
rect(620, 70, 100, 100);
stroke(#E5F2AB);
rect(620, 70, 80, 80);
stroke(#FFCD90);
rect(620, 70, 40, 40);
stroke(#FF8B79);
rect(620, 70, 5, 5);
//1, 7
stroke(#EBB9F5);
rect(730, 70, 100, 100);
stroke(#EBB9F5);
rect(730, 70, 70, 70);

//2, 1
stroke(#A78989);
rect(70, 180, 80, 80);
//2, 3
stroke(#FAFF79);
rect(290, 180, 80, 80);
stroke(#D4FF79);
rect(290, 180, 30, 30);
//2, 5
rect(510, 180, 80, 80);
stroke(#FFCD90);
rect(510, 180, 60, 60);
//2, 6
stroke(#FF8B79);
rect(620, 180, 80, 80);
//2, 7
stroke(#EBB9F5);
rect(730, 180, 80, 80);
stroke(#7896FF);
rect(730, 180, 5, 5);

//3, 1
stroke(#789600);
rect(70, 290, 60, 60);
stroke(#FFCD90);
rect(70, 290, 50, 50);
//3, 3
stroke(#869CAA);
rect(290, 290, 60, 60);
//3, 5
stroke(#7896FF);
rect(510, 290, 60, 60);
stroke(#869CAA);
rect(510, 290, 5, 5);
//3, 7
stroke(#FFCD90);
rect(730, 290, 60, 60);
stroke(#EBB9F5);
rect(730, 290, 50, 50);
stroke(#FFCD90);
rect(730, 290, 20, 20);
//4, 1
stroke(#7896FF);
rect(70, 400, 40, 40);
//4, 5
stroke(#869CAA);
rect(510, 400, 40, 40);
//4, 6
stroke(#EBB9F5);
rect(620, 400, 40, 40);
stroke(#789600);
rect(620, 400, 20, 20);
//4, 7
stroke(#7896FF);
rect(730, 400, 40, 40);

//5, 1
stroke(#EBB9F5);
rect(70, 510, 20, 20);
//5, 3
stroke(#789600);
rect(290, 510, 20, 20);
//5, 5
stroke(#FFCD90);
rect(510, 510, 20, 20);
//5, 6
stroke(#7896FF);
rect(730, 510, 20, 20);

//6, 1
stroke(#FF8B79);
rect(70, 620, 60, 60);
//6, 3
stroke(#789600);
rect(290, 620, 60, 60);
stroke(#FFCD90);
rect(290, 620, 10, 10);
//6, 5
stroke(#62DCE8);
rect(510, 620, 60, 60);
stroke(#FF8B79);
rect(510, 620, 20, 20);
//6, 7
stroke(#A78989);
rect(730, 620, 60, 60);

//7, 1
stroke(#FAFF79);
rect(70, 730, 80, 80);
stroke(#869CAA);
rect(70, 730, 30, 30);
//7, 2
stroke(#8FD3CF);
rect(180, 730, 80, 80);
stroke(#A78989);
rect(180, 730, 50, 50);
//7, 3
stroke(#869CAA);
rect(290, 730, 80, 80);
stroke(#FFCD90);
rect(290, 730, 70, 70);
stroke(#FAFF79);
rect(290, 730, 50, 50);
//7, 4
stroke(#789600);
rect(400, 730, 80, 80);
stroke(#FFCD90);
rect(400, 730, 30, 30);
stroke(#7896FF);
rect(400, 730, 20, 20);
//7, 5
stroke(#EBB9F5);
rect(510, 730, 80, 80);
//7, 6
stroke(#7896FF);
rect(620, 730, 80, 80);
stroke(#62DCE8);
rect(620, 730, 60, 60);
stroke(#7896FF);
rect(620, 730, 20, 20);
//7, 7
stroke(#8FD3CF);
rect(730, 730, 80, 80);

Work Cited

Molnar, Vera. Carrés. 1973, https://the-adaa.tumblr.com/post/11778802063 6/vera-     molnar-early-pioneer-of-computer-art. Accessed 5 Nov 2020.