Skip to content

14. Interface and Application Programming – Group Kuriyama

This is group assignment page of Interface and Application Programming (Kuriyama Student) :

Group assignment

  • Compare as many tool options as possible

What we’ve done this week

  • Processing

  • Eel (Python)

Processing

I found the Generative art tutorial.

Part 1 final code ( Creating stroke)

PGraphics bg;
PGraphics mask;

float x;

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

 bg = createGraphics(width, height);
 mask = createGraphics(width, height);

 x=0;
}

void draw() {
  circle(x, height/2, 25);

  bg.beginDraw();
  bg.noStroke();
  bg.fill(0);
  bg.circle(x, height/2, 25);
  bg.endDraw();

  image(bg, 0,0);

  x++;
  }

Started the programing

float x;

void setup(){
 size(500,500); //canvas size
 background(255); //background color

 x=0;
}

void draw() {
  circle(x, height/2, 25); //x position, y position, diameter size

  x++; //chnging x position
  }

Added the code in void setup

bg = createGraphics(width, height);
mask = createGraphics(width, height);

And in void draw

  bg.beginDraw();
  bg.noStroke();
  bg.fill(0);
  bg.circle(x, height/2, 25);
  bg.endDraw();

  image(bg, 0,0);

You can see the white dot on the top If you don’t add the noStroke and fill

  bg.beginDraw();
  //bg.noStroke();
  //bg.fill(0);
  bg.circle(x, height/2, 25);
  bg.endDraw();

  image(bg, 0,0);

I found the detail of “PGraphics” here. (Japanese)

Part2 final code ( Creating random rectangle)

PGraphics bg;
PGraphics mask;

int count = 10;

float x;

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

  bg = createGraphics(width, height);
  bg.beginDraw();
  bg.background(255);
  bg.noStroke();

  for (int i = 0; i < count; i++) {
  bg.fill(random(255));
    oddRect(bg, random(width), random(height), 100, 200, 10);
 }
  bg.endDraw();
  mask = createGraphics(width, height);


  image(bg, 0, 0);

}

void draw() {

  }

void oddRect(PGraphics g, float x, float y, float w, float h, float off) {
  g.beginShape();
  g.vertex(x + random(-off, off), y + random(-off, off));
  g.vertex(x + w + random(-off, off), y + random(-off, off));
  g.vertex(x + w + random(-off, off), y + h + random(-off, off));
  g.vertex(x + random(-off, off), y + h + random(-off, off));
  g.endShape(CLOSE);
}

Start to draw the line to create a box shape.

PGraphics bg;
PGraphics mask;

float x;

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

  bg = createGraphics(width, height);
  bg.beginDraw();
  bg.background(255);
  oddRect(bg, width/2, height/2, 100, 100, 0);
  bg.endDraw();
  mask = createGraphics(width, height);

  image(bg, 0, 0);

}

void draw() {

  }

void oddRect(PGraphics g, float x, float y, float w, float h, float off) {
  g.beginShape();
  g.vertex(x, y);
  g.vertex(x + w, y);
  g.vertex(x + w, y + h);
  g.endShape();
}

Add more line to come back the box.

g.vertex(x, y + h);

Add “CLOSE”

g.endShape(CLOSE);

Change the 100 to 200 from square shape to rectangle shape.

oddRect(bg, width/2, height/2, 100, 200, 0);

Add “+ random(-off, off)” for all position

g.vertex(x + random(-off, off), y + random(-off, off));
g.vertex(x + w + random(-off, off), y + random(-off, off));
g.vertex(x + w + random(-off, off), y + h + random(-off, off));
g.vertex(x + random(-off, off), y + h + random(-off, off));

And change the number 0 to 20

oddRect(bg, width/2, height/2, 100, 200, 20);

Added the noStroke and random fill in void setup

bg.noStroke();
bg.fill(random(255));

Added this code on the top part

int count = 10;

Change to the random number and shape

for (int i = 0; i < count; i++) {
  bg.fill(random(255));
    oddRect(bg, random(width), random(height), 100, 200, 10);
 }

Part 3 final code (Add the colors)

color[] cols = {#F2BBC9, #4971A6, #02732A, #F2BB16, #F27405, 
#FB0C06, #FFC52C, #A6BD62, #A589E7};

PGraphics bg;
PGraphics mask;

int count = 40; //number of ractangles 

float x;

void setup() {
  size(800, 800);
  background(#fff0dc);

  bg = createGraphics(width, height);
  bg.beginDraw();
  bg.background(255);
  bg.noStroke();

  for (int i = 0; i < count; i++) {
    bg.fill(cols[(int)random(cols.length)], 180); //color randam from color sample, opacity
    oddRect(bg, random(width), random(height), 100, 200, 10);
  }
  bg.endDraw();
  mask = createGraphics(width, height);

  image(bg, 0, 0);

  x=0;
}

void draw() {
}

void oddRect(PGraphics g, float x, float y, float w, float h, float off) {
  g.beginShape();
  g.vertex(x + random(-off, off), y + random(-off, off));
  g.vertex(x + w + random(-off, off), y + random(-off, off));
  g.vertex(x + w + random(-off, off), y + h + random(-off, off));
  g.vertex(x + random(-off, off), y + h + random(-off, off));
  g.endShape(CLOSE);
}

Explain what I added.

I added color sample on the very top

color[] cols = {#F2BBC9, #4971A6, #02732A, #F2BB16, #F27405, 
#FB0C06, #FFC52C, #A6BD62, #A589E7}; 

Color random code in bg.fill

bg.fill(cols[(int)random(cols.length)], 180); //color randam from color sample, opacity

And rectangles became colorful.

I create color sample on illustrator. It is easy to see the colors for me. And change some colors.

Open the color picker

Copy the number here. and you can change the color in Processing too.

This is the color code that I choose.

color[] cols = {#F2BBC9, #6B9ACD, #51BD89, #F2BB16, #F27405, 
#FB0C06, #FF3EBF, #8EC742, #A067AB};

Also I change the opacity 180 to 200.

bg.fill(cols[(int)random(cols.length)], 200);

And this tis the final look

Part 4 final code (send signal from Arduino to Processing)

Processing

//original code by hbyhadeel (https://www.youtube.com/watch?v=6btSLYnf30M), 2021
//modified by Kurumi Shiowaki, Fab Academy 2022
import processing.serial.*; //import processing serial library
Serial kurumiSerial; //create local serial object from serial library
color[] cols = {#F2BBC9, #6B9ACD, #51BD89, #F2BB16, #F27405, 
   #FB0C06, #FF3EBF, #8EC742, #A067AB};
PGraphics bg;
char val;
int count = 40; //number of ractangles
void setup() {
  size(800, 800);
  background(255);
  String kurumiPort = Serial.list()[0]; //zero is the index value of the communication port as it is listed in Arduino IDE
  kurumiSerial = new Serial(this, kurumiPort, 9600); //initialize and configure serial port...match baud rate with arduino
}
void draw() {
  while (kurumiSerial.available() > 0) {
    val = kurumiSerial.readChar(); //set variable 'val' to equal character read from serial port
    if (val == 'k') {
      bg = createGraphics(width, height);
      bg.beginDraw();
      bg.background(150 ,random(100, 255),random(200, 255));//Chnge the back ground color randomly
      bg.noStroke();
      for (int i = 0; i < count; i++) {
        bg.fill(cols[(int)random(cols.length)], 150); //color randam from color sample, opacity
        oddRect(bg, random(width), random(height), 100, 800, 100);//rectangle shape and rondom range

      }
      bg.endDraw();
      image(bg, 0, 0);
    }
  }
}
void oddRect(PGraphics g, float x, float y, float w, float h, float off) {
  g.beginShape();
  g.vertex(x + random(-off, off), y + random(-off, off));
  g.vertex(x + w + random(-off, off), y + random(-off, off));
  g.vertex(x + w + random(-off, off), y + h + random(-off, off));
  g.vertex(x + random(-off, off), y + h + random(-off, off));
  g.endShape(CLOSE);
}

Arduino

//serial blink onboard LED at pin 13
char val;
void setup(){
  Serial.begin(9600); //initiate serial communication at 9600 baud/sec
}
void loop(){
  val = 'k';
  Serial.write(val); //create 'character' datatype variable 'val'
  delay(1000);
}

Arduino constantly send a character of “k” 1sec each.

And it is trigger to run in Processing.

run it.

Eel (Suzuki)

Overview

I created a Button UI that allows the user to control the position of the stepping motor

I created a slider to control the stepping motor on Atsufumi Suzuki week14, and I have created a button that move to the position of the trash dumpster portion of each of the three trash box that is going to create.

I found a python library and used it!

Eel is a little Python library for making simple Electron-like offline HTML/JS GUI apps, with full access to Python capabilities and libraries.

when you use eel, install via pip.

pip install eel

Create main.py directly under the root directory and place HTML, CSS under the web directory

- main.py
- web/
|--  index.html
|--  css/

write the following in main.py

You can easily start a webapp with index.html as its home by writing the following

main.py

import eel
eel.init("web")
eel.start("index.html")

index.html

<!DOCTYPE html>
<html lang="en">
  <head>
      <meta charset="UTF-8">
      <meta http-equiv="X-UA-Compatible" content="IE=edge">
      <meta name="viewport" content="width=device-width, initial-scale=1.0">
      <title>Document</title>
      <link rel="stylesheet" href="css/reset.css">
      <link rel="stylesheet" href="css/style.css">
  </head>
  <body>
      <div class="box">
          <a class="box__button red__button" href="http://192.168.11.12/position1">Position:1</a>
          <a class="box__button blue__button" href="http://192.168.11.12/position2">Position:2</a>
          <a class="box__button green__button" href="http://192.168.11.12/position3">Position:3</a>
      </div>
  </body>
</html>

[IP Address]/[position number] of esp32 is written in the href attribute of the a tag, when clicked, HTTP GET request is sent to the target URL of the esp32 webserver.

  <a class="box__button red__button" href="http://192.168.11.12/position1">Position:1</a>
  <a class="box__button blue__button" href="http://192.168.11.12/position2">Position:2</a>
  <a class="box__button green__button" href="http://192.168.11.12/position3">Position:3</a>

CSS

.box {
  display: flex;
}

.box__button {
  width: 50%;
  margin: 0 auto;
  text-decoration: none;
  text-align: center;
  display: block;
  padding: 20px;
  color: black;
}

.red__button {
  color: white;
  background-color: red;
}

.blue__button {
  color: white;
  background-color: blue;
}

.green__button {
  color: white;
  background-color: green;
}

Arduino language

#include <WiFi.h>
#include <WebServer.h>
#include <ESP32Servo.h>
#include <AccelStepper.h>

#define SSID "Kuriyama-DIY-G"
#define PASS "kuriyama"

#define motorInterfaceType 1

const int dirPin1 = 22;
const int stepPin1 = 23;
const int stepSpeed = 1700;
const int stepsPerRevolution = 200;

AccelStepper myStepper1(motorInterfaceType, stepPin1, dirPin1);

WebServer server(80);

void setup(){
  Serial.begin(115200)

  pinMode(stepPin1, OUTPUT);
  pinMode(dirPin1, OUTPUT);

  connectWiFi();
  server.on("/", handleRoot);
  server.on("/position1", position1);
  server.on("/position2", position2);
  server.on("/position3", position3);
  server.begin();
  Serial.println("HTTP server started");
}

void loop() {
  server.handleClient();
}

void connectWiFi(){
  WiFi.begin(SSID, PASS);
  Serial.println();
  while(WiFi.status() != WL_CONNECTED){
  delay(500);
  Serial.print(".");
}
  Serial.println();
  Serial.println("WiFi connected");
  Serial.println(WiFi.localIP());
}

void handleRoot(){
  server.send(200, "text/plain", "Hello");
}

void position1(){
  Serial.println("position1");

  myStepper1.setMaxSpeed(1000);
  myStepper1.setAcceleration(50);
  myStepper1.setSpeed(200);
  myStepper1.moveTo(300);
  myStepper1.runToPosition();

  myStepper1.setMaxSpeed(1000);
  myStepper1.setAcceleration(50);
  myStepper1.setSpeed(200);
  myStepper1.moveTo(0);
  myStepper1.runToPosition();

  server.send(200, "text/plain", "position1");
}

void position2(){
  Serial.println("position2");

  myStepper1.setMaxSpeed(1000);
  myStepper1.setAcceleration(50);
  myStepper1.setSpeed(200);
  myStepper1.moveTo(1500);
  myStepper1.runToPosition();

  myStepper1.setMaxSpeed(1000);
  myStepper1.setAcceleration(50);
  myStepper1.setSpeed(200);
  myStepper1.moveTo(0);
  myStepper1.runToPosition();

  server.send(200, "text/plain", "position2");
}

void position3(){
  Serial.println("position3");

  myStepper1.setMaxSpeed(1000);
  myStepper1.setAcceleration(50);
  myStepper1.setSpeed(200);
  myStepper1.moveTo(2700);
  myStepper1.runToPosition();

  myStepper1.setMaxSpeed(1000);
  myStepper1.setAcceleration(50);
  myStepper1.setSpeed(200);
  myStepper1.moveTo(0);
  myStepper1.runToPosition();

  server.send(200, "text/plain", "position3");
}

Appendix


Last update: May 12, 2022