Processing Introduction

From Interaction Station Wiki
Jump to navigation Jump to search

Processing

Processing 3 logo.png

Processing is a free graphical library and integrated development environment built for the electronic arts, new media art,

and visual design communities with the purpose of teaching non-programmers the fundamentals of computer programming in a visual context.

Currently, Processing uses the Java language, p5.js (JavaScript), and Processing.py (Python).


https://processing.org/download/


Say Hello

setup()

only run once.

draw()

will continuously repeat the action inside of the {}


1void setup(){
2size(400,400);
3println("Hello!Nan");
4
5}
6void draw(){
7println("welcome to interaction station!");
8}

copy-paste the code above and observe the message from the console.


Now, let's try to draw something

 1void setup(){
 2size(400,400);
 3//println("hello!Nan");
 4background(30,50,80);
 5
 6}
 7void draw(){
 8//println("welcome to nteraction station!");
 9//RGB Value
10stroke(30,150,140);
11line(width/2, height/2, mouseX, mouseY);
12}


Sketch --> Run

Sketch --> Tweak

Sketch --> Present


Full screen!

 1void setup(){
 2//size(400,400);
 3//println("hello!Nan");
 4fullScreen();
 5background(30,50,80);
 6
 7}
 8void draw(){
 9//println("welcome to nteraction station!");
10//RGB Value
11stroke(30,150,140);
12line(width/2, height/2, mouseX, mouseY);
13}

Draw

 1void setup(){
 2//size(400,400);
 3//println("hello!Nan");
 4fullScreen();
 5background(30,50,80);
 6 
 7}
 8void draw(){
 9//println("welcome to interaction station!");
10//RGB Value
11noStroke();
12fill(0,200,0);
13
14ellipse(width/2,height/2,150,150);
15stroke(30,150,140);
16strokeWeight(2);
17line(width/2, height/2, mouseX, mouseY);
18println("mouseX:",mouseX);
19println("mouseY:",mouseY);
20if(mousePressed){
21background(30,50,80);
22}
23}

Communication with Arduino

there are two ways to get processing sketches communicating with microcontrollers.

1. the first one is to use the microcontroller as an HID (Human Interface Device), like a mouse or keyboard.


in this case, we only need to change some code in Arduino IDE.

now. we will use the X and Y values from the motion sensor on CPX to control the position of the nouse.

and left button on CPX to work as mouse left click.

Arduino HID:

 1#include "Mouse.h"
 2#include <Adafruit_CircuitPlayground.h>
 3float X, Y, Z;
 4//int leftButton;
 5bool mouseIsActive = false; 
 6int slideSwitch;
 7
 8void setup() {
 9  // put your setup code here, to run once:
10  CircuitPlayground.begin();
11  Mouse.begin();
12}
13
14void loop() {
15  //read slide switch from cpx.
16  slideSwitch = CircuitPlayground.slideSwitch();
17  // if the switch is on the CPX mouse is active, 
18  if(slideSwitch ==HIGH){
19    mouseIsActive=true;
20    }else{
21      //if the slide switch is off, the cpx mouse will be off
22      mouseIsActive=false;
23      }
24
25  //read the leftButton from cpx
26  int leftButton = CircuitPlayground.leftButton();
27  //x and y position from motion sensor
28  X = CircuitPlayground.motionX();
29  Y = CircuitPlayground.motionY();
30
31  //int xReading=map(x,-1,1,0,100);
32   // if the mouse control state is active, move the mouse with motion sensor X and Y value.
33  if (mouseIsActive) {
34    Mouse.move(X*2, Y*2, 0);
35  }
36
37 // if the mouse is not pressed, press it:
38  if (leftButton==HIGH){
39    if (!Mouse.isPressed(MOUSE_LEFT)) {
40      Mouse.press(MOUSE_LEFT);
41     }
42    }else{  // else the mouse button is not pressed:
43      if (Mouse.isPressed(MOUSE_LEFT)) {
44      Mouse.release(MOUSE_LEFT);
45    }
46      }
47  delay(5);
48}

2. however, sometimes, you want to send data directly from a microcontroller to processing.

in this case, we need to do write few lines of code in both Arduino and processing.

Send out data Arduino IDE:

 1#include <Adafruit_CircuitPlayground.h>
 2float X, Y, Z;
 3void setup() {
 4 Serial.begin(9600);
 5 CircuitPlayground.begin();
 6}
 7 
 8void loop() {
 9 
10  int leftButton = CircuitPlayground.leftButton();
11  X = CircuitPlayground.motionX();
12  Y = CircuitPlayground.motionY();
13  Z = CircuitPlayground.motionZ();
14  int xVal=map(X,-9,10,0,1920);
15  int yVal=map(Y,-9,10,0,1080);
16 
17  Serial.print(xVal);
18  Serial.print("\t"); //instert a tap in between
19  Serial.print(yVal);
20  Serial.print("\t");//instert a tap in between
21  Serial.println(leftButton);
22 
23  delay(10);
24 
25}

Receive the value in Processing:

 1import processing.serial.Serial;
 2//select serial port and set bauds rate
 3static final int PORT_INDEX=6,BAUDS=9600;
 4// create an array, a list of data will be used to store values from snesors.
 5int[] vals= {};
 6 
 7void setup(){
 8  noLoop();
 9  frameRate(18);
10  final String[] ports = Serial.list();
11  printArray(ports);
12  new Serial(this, ports[PORT_INDEX], BAUDS).bufferUntil(ENTER); 
13}
14 
15void draw(){
16 
17   print("x=");
18   println(vals[0]); 
19   print("Y=");
20   println(vals[1]); 
21   print("Button=");
22   println(vals[2]); 
23    }
24void serialEvent(final Serial s) {
25// split the string from the serial port into 3 integers and store it in the list.
26  vals = int(splitTokens(s.readString()));
27  redraw = true;
28}

Add the lines back to this code

Now, please try to add the animated lines back to the code.

and use X and Y values from the motion sensor as mouse positions to draw the line.

and CPX button clicks to clear out the lines.

If you need help, cleck here--> ?! add lines

Draw a image:

Let' try to draw an image with PImage!

https://processing.org/reference/PImage.html

first, we need to create empty processing and save it somewhere on your computer.

in this case, we created a sketch folder, and inside of the sketch folder,

we need to create a new folder called "data" and save an image (jpg, png, gif,tga)in the "data" folder.


 1PImage images;
 2
 3void setup() {
 4
 5 fullScreen();
 6 images=loadImage("run.gif");
 7}
 8
 9void draw() { 
10 // background(0);
11  image(images,0,0, images.width, images.height );  
12}

Image sequence:

Step two:

let's make it move!

in order to do that we need to use a sequence of images.

you can copy the image sequences at the file folder from the physical interfaces@interaction station channel on Teams

 1int numImages=23;
 2int startNumImages=1;
 3PImage[] images= new PImage[numImages];
 4int imgInSeq=1;
 5
 6void setup() {
 7 // size(1920, 1080);
 8 //let's give it a frame rate value so that we can change it later:-))
 9 frameRate(18);
10 fullScreen();
11
12 for (int i = 0; i < numImages; i++) {
13   String imageName = "run-" + nf(i, 5) + ".png";
14   images[i] = loadImage(imageName);
15  }
16}
17
18void draw() { 
19 background(0);
20//we can use % (modulo) to cycle through the images. from 1- to numImages
21imgInSeq= (imgInSeq+1) % numImages;
22image(images[imgInSeq],0,0,images[imgInSeq].width,images[imgInSeq].height);
23
24}


now, let's make it interactive!

remember the first example where we use mouse position to draw lines?

we can also use mouseX position to control the animation.

let's comment out:

1imgInSeq= (imgInSeq+1) % numImages;

and replace it with :

1int imgInSeq = (int)map(mouseX, 0, width, 0, numImages - 1);

now, the images always display from the top left corner. let's move it to the center:

Question Time:

HOW TO DO THAT??

center the image

use other GIFs:

Gifgif-250px.gif Cat-maker-250px.gif Alpaca--hoops-250px.gif


Now, let's try it by search online and find your own GIF and make your own image mouse-controlled animated images.

you can use a free online tool GIF frame extractor to split the gif file in image sequence:

https://ezgif.com/split


About renaming the files in sequence:


if you are using macOS, you can just select all the images and right-click select "rename" and chose "format" to rename all your files in sequence.

like this:

Rename-files.png

However:

if you are using Window 10 after you rename a sequence of files, they might look like this: run-(1).png run-(2).png run-(3).png ...

don't panic, you can change the code from

1for (int i = 0; i < numImages; i++) {
2   String imageName = "run-" + nf(i, 5) + ".png";
3   images[i] = loadImage(imageName);
4  }

into

1for (int i = 0; i < numImages; i++) {
2   String imageName = "run-(" + i + ").png";
3   images[i] = loadImage(imageName);
4  }

Sensor controlled image sequence:

let's use higher resolution images and try to control the animation with the light sensor from CPX.

we can use the lego image sequence from the data folder on teams.


1. use the light sensor from CPX to animated the image sequences.

send out light senstor value from Arduino:

 1#include <Adafruit_CircuitPlayground.h>
 2
 3int value;
 4
 5void setup() {
 6  Serial.begin(9600);
 7  CircuitPlayground.begin();
 8}
 9
10void loop() {
11  value = CircuitPlayground.lightSensor();
12  
13 // Serial.print("Light Sensor: ");
14  Serial.println(value);
15  delay(50);
16}

receive and draw in Processing:

 1import processing.serial.Serial;
 2static final int PORT_INDEX=6,BAUDS=9600;
 3int [] vals= {};
 4
 5int numImages=97;
 6int startNumImages=1;
 7PImage[] images= new PImage[numImages];
 8int imgInSeq=1;
 9
10void setup() {
11  noLoop();
12  final String[] ports = Serial.list();
13  printArray(ports);
14  new Serial(this, ports[PORT_INDEX], BAUDS).bufferUntil(ENTER);
15
16 //let's give it a frame rate value so that we can change it later:-))
17 frameRate(18);
18 fullScreen();
19
20 for (int i = 0; i < numImages; i++) {
21   String imageName = "lego" + nf(i, 5) + ".png";
22   images[i] = loadImage(imageName);
23  }
24}
25
26void draw() { 
27  background(0);
28  println(vals[0]);
29
30
31  imgInSeq = (int)map(vals[0], 0, 500, 0, numImages - 1);
32
33  image(images[imgInSeq],0,0,images[imgInSeq].width,images[imgInSeq].height);
34
35}
36
37void serialEvent(final Serial s) {
38  vals = int(splitTokens(s.readString()));
39  redraw = true;
40}

use the "if" statement

Now let's use other sensor values and an "if " statement to control the image sequences.

in this case, we can try to use the sound level value from CPX's mic.

and say: if the sound input is louder than a certain level, play the image sequence. else, pulse and do nothing.

send out sound value from Arduino:

 1#include <Adafruit_CircuitPlayground.h>
 2
 3int value;
 4
 5void setup() {
 6  Serial.begin(9600);
 7  CircuitPlayground.begin();
 8}
 9
10void loop() {
11  // Take 10 milliseconds of sound data to calculate
12  value = CircuitPlayground.mic.soundPressureLevel(10);
13  
14 // Serial.print("Sound Sensor SPL: ");
15  
16  int newVal=map(value,58,102,0,94);
17if (newVal<0){
18  newVal=0;
19    }
20  Serial.println(newVal);
21
22  delay(90);
23}

Receive and draw in Processing:

 1import processing.serial.Serial;
 2static final int PORT_INDEX=6,BAUDS=9600;
 3int [] vals= {};
 4
 5int numImages=97;
 6int startNumImages=1;
 7PImage[] images= new PImage[numImages];
 8int imgInSeq=1;
 9
10void setup() {
11  noLoop();
12  final String[] ports = Serial.list();
13  printArray(ports);
14  new Serial(this, ports[PORT_INDEX], BAUDS).bufferUntil(ENTER);
15
16 //let's give it a frame rate value so that we can change it later:-))
17 frameRate(20);
18 fullScreen();
19
20 for (int i = 0; i < numImages; i++) {
21   String imageName = "lego" + nf(i, 5) + ".png";
22   images[i] = loadImage(imageName);
23  }
24}
25
26void draw() { 
27 background(0);
28 println(vals[0]);
29
30if (vals[0]>40){
31imgInSeq= (imgInSeq+1) % numImages;
32}
33
34image(images[imgInSeq],0,0,images[imgInSeq].width,images[imgInSeq].height);
35
36}
37
38void serialEvent(final Serial s) {
39  vals = int(splitTokens(s.readString()));
40  redraw = true;
41}


Question Time!!

if you want the image sequence to go back to the first frame after each trigger.

what do you need to add to this code?