Menu

Interface and Application Programming.

I began this week's assignment by immersing myself in Processing, a program I've long been eager to learn. To facilitate my learning process, I found several helpful resources. The official website of Processing is a treasure trove of information for beginners. I found the Processing examples and tutorials particularly beneficial. Additionally, Jose Sanchez, the founding principal of Plethora Project LLC, has published a series of excellent Processing tutorials that greatly aided my understanding.

Self Learning and Practicing the Processing

Processing is a user-friendly, versatile platform that bridges the gap between programming and visual arts. Its straightforward approach to coding, and excels in its ability to handle graphics and interactivity. It provides a wide range of functions that can be used to draw shapes, manipulate images, and create animations. 2D and 3D graphics can be created, making it a great tool for visualizing data, creating art installations, or even developing simple games. Also It has a strong community support, makes it an ideal tool for artists, designers, and anyone interested in exploring the creative possibilities of code. This community support makes it easier to learn and experiment, as you can often find answers to your questions or inspiration for your projects from others who have shared their experiences and creations.

Here is the first trial I have made by using drawRipple tool. This Processing code creates a visual ripple effect activated by a mouse click. It initializes a canvas and uses variables to track the ripple's center, touch status, and radius. The draw() function continuously refreshes the background and, upon detecting a click, triggers drawRipple(), which displays a growing circle to simulate a ripple. This ripple expands until reaching a maximum size, then ends with a final red circle. The mouseClicked() function sets the ripple's origin to the mouse position, starting the effect anew with each click.


// Ripple Effect in Processing

int rippleX, rippleY;  // Coordinates of the ripple
boolean isTouched = false; // Touch status
boolean rippleEffect = false; // Ripple effect status
int rippleRadius = 0; // Initial radius of the ripple
int maxRippleRadius = 100; // Maximum radius of the ripple

void setup() {
  size(1920, 1080);
  background(255);
}

void draw() {
  background(255);
  // Check if there is a touch
  if (isTouched) {
    if (rippleEffect) {
      drawRipple();
    }
  }
}

void drawRipple() {
  noFill();
  stroke(0);
  circle(rippleX, rippleY, rippleRadius * 2);
  rippleRadius += 2; // Increase the radius
  if (rippleRadius > maxRippleRadius) {
    rippleEffect = false;
    fill(255, 0, 0);
    noStroke();
    circle(rippleX, rippleY, maxRippleRadius * 2); // Draw the last circle in red
  }
}

// Simulate a touch event
void mouseClicked() {
  rippleX = mouseX;
  rippleY = mouseY;
  isTouched = true;
  rippleEffect = true;
  rippleRadius = 0;
}

Processing Code Reacting to Capacitive Touch Sensor

For this week's assignment, I chose to develop an interface that interacts with the capacitive touch sensor I previously employed for generating sounds in the LM4871 amplifier circuit in Networking and Communication week. My plan involves creating 24 horizontal lines, with every set of four lines responding to one of the pads (0-5) on the MPR121. Initially, I aim to experiment with altering the color of these lines based on touch input.

This Processing sketch, designed for visualizing touch inputs from a capacitive sensor with six pads, begins by importing the necessary serial library to facilitate communication with an Arduino. It declares a Serial object, myPort, for the serial communication port and an array, padTouched, to track the touch status of each of the six pads.

In the setup function, the sketch sets the window size to 600x480 pixels and initializes myPort with the appropriate serial port and a baud rate of 9600. The draw function, which continuously runs, sets the background to white and checks for incoming serial data, processing it to update the touch status of the pads.

It uses nested loops to draw lines corresponding to each pad, coloring them green when touched and black otherwise. The updatePadStatus function interprets the serial messages to ascertain which pads are touched, updating the padTouched array accordingly; if no pads are touched, it resets all values in the array to false, ensuring an accurate and dynamic visual representation of the touch sensor inputs.


import processing.serial.*;

Serial myPort;  // Create object from Serial class
boolean[] padTouched = new boolean[6];  // Array to hold the state of each pad (0 to 5)
int linesPerPad = 4;  // Number of lines per pad
int lineHeight = 10;  // Height of each line

void setup() {
  size(600, 480);  // Set the size of the window
  String portName = Serial.list()[0];  // Change this to match your Arduino port
  myPort = new Serial(this, portName, 9600);
}

void draw() {
  background(255);  // Set background to white
  if (myPort.available() > 0) {
    String val = myPort.readStringUntil('\n');
    if (val != null) {
      val = trim(val);  // Trim whitespace
      updatePadStatus(val);  // Update pad status based on the serial data
    }
  }

  for (int i = 0; i < padTouched.length; i++) {
    for (int j = 0; j < linesPerPad; j++) {
      int y = i * linesPerPad * lineHeight + j * lineHeight;
      if (padTouched[i]) {  // Check if the pad is touched
        stroke(0, 255, 0);  // Set line color to green
      } else {
        stroke(0);  // Set line color to black
      }
      line(0, y, width, y);  // Draw the line
    }
  }
}

// Function to update the pad status based on the serial message
void updatePadStatus(String message) {
  boolean touchDetected = false;
  for (int i = 0; i < padTouched.length; i++) {
    if (message.contains("Pad " + i + " touched")) {
      padTouched[i] = true;
      touchDetected = true;
    }
  }

  // Reset all pads if none are currently touched
  if (!touchDetected) {
    for (int i = 0; i < padTouched.length; i++) {
      padTouched[i] = false;
    }
  }
}

Adjusting the location and colour

So I made some little corrections in colour, positioning and tremor movement of the lines. In the code below; the lines corresponding to the touched sensor pads are rendered in red and exhibit a trembling effect achieved by randomizing their x-coordinates. This snippet also includes an additional vertical padding (topPadding), which shifts the starting position of the lines downwards, creating a gap at the top of the window.


import processing.serial.*;

Serial myPort;  // Create object from Serial class
boolean[] padTouched = new boolean[6];  // Array to hold the state of each pad (0 to 5)
int linesPerPad = 4;  // Number of lines per pad
int lineHeight = 10;  // Height of each line
int topPadding = 100;  // Padding at the top

void setup() {
  size(600, 480);  // Set the size of the window
  String portName = Serial.list()[2];  // Change this to match your Arduino port
  myPort = new Serial(this, portName, 9600);
}

void draw() {
  background(255);  // Set background to white
  if (myPort.available() > 0) {
    String val = myPort.readStringUntil('\n');
    if (val != null) {
      val = trim(val);  // Trim whitespace
      updatePadStatus(val);  // Update pad status based on the serial data
    }
  }

  for (int i = 0; i < padTouched.length; i++) {
    for (int j = 0; j < linesPerPad; j++) {
      int y = topPadding + i * linesPerPad * lineHeight + j * lineHeight;
      if (padTouched[i]) {  // Check if the pad is touched
        stroke(255, 0, 0);  // Set line color to red
        // Add trembling effect by randomizing the line's x-coordinates
        line(random(-5, 5), y, width + random(-5, 5), y);
      } else {
        stroke(0);  // Set line color to black
        line(0, y, width, y);  // Draw the line normally
      }
    }
  }
}

// Function to update the pad status based on the serial message
void updatePadStatus(String message) {
  boolean touchDetected = false;
  for (int i = 0; i < padTouched.length; i++) {
    if (message.contains("Pad " + i + " touched")) {
      padTouched[i] = true;
      touchDetected = true;
    } else {
      padTouched[i] = false;
    }
  }

  // If no pad is currently touched, reset all pads
  if (!touchDetected) {
    for (int i = 0; i < padTouched.length; i++) {
      padTouched[i] = false;
    }
  }
}

Adujusting the lenght of trembling lines

To create the effect where the lines not only tremble but also shrink towards the middle when a pad is touched, I adjusted the x-coordinates of the line endpoints dynamically based on the touch status by adjusting the draw function.



                                    void draw() {
  background(255);  // Set background to white
  if (myPort.available() > 0) {
    String val = myPort.readStringUntil('\n');
    if (val != null) {
      val = trim(val);  // Trim whitespace
      updatePadStatus(val);  // Update pad status based on the serial data
    }
  }

  for (int i = 0; i < padTouched.length; i++) {
    for (int j = 0; j < linesPerPad; j++) {
      int y = topPadding + i * linesPerPad * lineHeight + j * lineHeight;
      if (padTouched[i]) {  // Check if the pad is touched
        stroke(255, 0, 0);  // Set line color to red

        // Lines tremble and endpoints move towards the middle
        float startX = random(width * 0.25, width * 0.75);
        float endX = random(width * 0.25, width * 0.75);
        line(startX, y, endX, y);
      } else {
        stroke(0);  // Set line color to black
        line(0, y, width, y);  // Draw the line normally
      }
    }
  }
}

Revert to a Steady Status

To ensure the lines in my sketch revert to a steady, black state immediately after removing my hand from the touch pad, it was necessary to accurately update the padTouched array to reflect the current touch status. This update needed to be accurately captured and processed within the draw() function of the sketch. Specifically, when a pad is actively touched (indicated by padTouched[i] being true), the corresponding lines change to a red color and exhibit both a trembling and shrinking effect towards the center. However, once the touch is removed (with padTouched[i] turning to false), the lines instantly revert to their default state – stable, black lines that extend across the full width of the window, thus providing a clear visual indicator of touch interaction.


                                    import processing.serial.*;

Serial myPort;  // Create object from Serial class
boolean[] padTouched = new boolean[6];  // Array to hold the state of each pad (0 to 5)
int linesPerPad = 4;  // Number of lines per pad
int lineHeight = 10;  // Height of each line
int topPadding = 100;  // Padding at the top

void setup() {
  size(600, 480);  // Set the size of the window
  String portName = Serial.list()[2];  // Change this to match your Arduino port
  myPort = new Serial(this, portName, 9600);
}

void draw() {
  background(255);  // Set background to white
  if (myPort.available() > 0) {
    String val = myPort.readStringUntil('\n');
    if (val != null) {
      val = trim(val);  // Trim whitespace
      updatePadStatus(val);  // Update pad status based on the serial data
    }
  }

  for (int i = 0; i < padTouched.length; i++) {
    for (int j = 0; j < linesPerPad; j++) {
      int y = topPadding + i * linesPerPad * lineHeight + j * lineHeight;
      if (padTouched[i]) {  // Check if the pad is touched
        stroke(255, 0, 0);  // Set line color to red
        // Lines tremble and endpoints move towards the middle
        float startX = random(width * 0.25, width * 0.75);
        float endX = random(width * 0.25, width * 0.75);
        line(startX, y, endX, y);
      } else {
        stroke(0);  // Set line color to black
        line(0, y, width, y);  // Draw the line normally
      }
    }
  }
}

// Function to update the pad status based on the serial message
void updatePadStatus(String message) {
  boolean touchDetected = false;
  for (int i = 0; i < padTouched.length; i++) {
    if (message.contains("Pad " + i + " touched")) {
      padTouched[i] = true;
      touchDetected = true;
    } else {
      padTouched[i] = false;
    }
  }

  // If no pad is currently touched, reset all pads
  if (!touchDetected) {
    for (int i = 0; i < padTouched.length; i++) {
      padTouched[i] = false;
    }
  }
}