Processing Introduction
Processing
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.write('\t');
19 Serial.print(yVal);
20 Serial.write('\t');
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(20);
10 final String[] ports = Serial.list();
11 printArray(ports);
12 new Serial(this, ports[PORT_INDEX], BAUDS).bufferUntil(ENTER);
13
14
15}
16
17void draw(){
18
19 print("x=");
20 println(vals[0]);
21 print("Y=");
22 println(vals[1]);
23 print("Button=");
24 println(vals[2]);
25
26 }
27
28void serialEvent(final Serial s) {
29 vals = int(splitTokens(s.readString()));
30 redraw = true;
31}
Add the lines back in the code:
1import processing.serial.Serial;
2static final int PORT_INDEX=6,BAUDS=9600;
3int[] vals= {};
4
5void setup(){
6 noLoop();
7 frameRate(20);
8 final String[] ports = Serial.list();
9 printArray(ports);
10 new Serial(this, ports[PORT_INDEX], BAUDS).bufferUntil(ENTER);
11
12 fullScreen();
13 background(30,50,130);
14}
15
16void draw(){
17
18 /* print("x=");
19 println(vals[0]);
20 print("Y=");
21 println(vals[1]);
22 print("Button=");
23 println(vals[2]); */
24
25 noStroke();
26 fill(255,255,0);
27 ellipse(width/2,height/2,150,150);
28 stroke(30,170,160);
29 strokeWeight(4);
30 line(width/2, height/2, vals[0], vals[1]);
31 if(vals[2]==1){
32 background(30,50,130);
33 }
34
35 }
36
37void serialEvent(final Serial s) {
38 vals = int(splitTokens(s.readString()));
39 redraw = true;
40}
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
13
14}
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??
chose different 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:
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:
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 sequnce
1. use the light sensor from CPX to animated the image sequences.
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}
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}
2. use if condiction and sound sensor to trigger the image sequence to play.
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}
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
30if (vals[0]>400){
31imgInSeq= (imgInSeq+1) % numImages;
32}else{
33 imgInSeq = (int)map(vals[0], 0, 400, 0, numImages - 1);
34}
35
36image(images[imgInSeq],0,0,images[imgInSeq].width,images[imgInSeq].height);
37
38}
39
40void serialEvent(final Serial s) {
41 vals = int(splitTokens(s.readString()));
42 redraw = true;
43}