機械玩具DIY - 互動藝術系列最終章

This is a workshop organized by the Art Promotion Office in the Hong Kong Visual Arts Centre.

The workshop is the final session. The first one was the mechanical workshop where participants learnt to build simple robotic structures from daily appliances. The second one was a Processing workshop doing simple audio visual treatment. Justin and I work on the third one, with a hope to combine the hardware and software parts using both Arduino micro-controller and the Processing environment.

Approach
Although computers are so pervasive in our daily lives but to learn how a computer works or how to instruct a computer to work, i.e. programming, seem to be a very distant and abstract experience. This workshop aims to bring the abstract ideas/concepts back to the concrete/tangible experience.

Reference
Arduino programming notebook by Brian W. Evans

There are other choices besides the Arduino.

Parallax products, e.g. Basic Stamp, Javelin Stamp, Hong Kong distributor, 智凌科技
EZIO
Phidget products
ActiveWire
I-CubeX

25 May 2008

Exercise 1 – Flash Light – Processing version

boolean light;

void setup() {
  size(200,200);
  smooth();
  light = false;
  fill(255,255,0);
  frameRate(2);
}

void draw() {
  background(0);
  if (light) {
    ellipse(width/2,height/2,80,80);
  }
  light = !light;
}

Exercise 2 – Flash Light – Arduino version

int LED = 12;

void setup() {
  pinMode(LED,OUTPUT);
}

void loop() {
  digitalWrite(LED,HIGH);
  delay(500);
  digitalWrite(LED,LOW);
  delay(500);
}

Exercise 3 – Mouse On/Off – Processing version

boolean light;

void setup() {
  size(200,200);
  smooth();
  light = false;
  fill(255,255,0);
}

void draw() {
  background(0);
  if (light) {
    ellipse(width/2,height/2,80,80);
  }
}

void mousePressed() {
  light = true;
}

void mouseReleased() {
  light = false;
}

Exercise 4 – Switch On/Off – Arduino version

int inPin = 4;
int ledPin = 12;

void setup() {
  pinMode(inPin,INPUT);
  pinMode(ledPin,OUTPUT);
}

void loop() {
  int i = digitalRead(inPin);
  if (i==1) {
    digitalWrite(ledPin,HIGH);
  } else if (i==0) {
    digitalWrite(ledPin,LOW);
  }
}

31 May 2008

Exercise 5 – Continuous Input – Processing version

int col;

void setup() {
  size(200,200);
  smooth();
  col = 0;
  fill(col);
}

void draw() {
  background(0);
  fill(col);
  ellipse(width/2,height/2,80,80);
}

void mouseDragged() {
  col = mouseX*256/width;
}

Exercise 6 – Analog Output – Arduino version

int ledPin = 3;
int val = 0;
int del = 1;

void setup() {
  pinMode(ledPin,OUTPUT);
}

void loop() {
  analogWrite(ledPin,val);
  val = val + del;
  if (val>=256) {
    del = -1;
  } else if (val<=0) {
    del = 1;
  }
  delay(10);
}

Exercise 7 – Analog Input – Arduino version

int inPin = 5;

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

void loop() {
  int i = analogRead(inPin);
  Serial.println(i,DEC);
  delay(500);
}

We are going to explain the Serial communication later in the class.

Exercise 8 – Analog In/Out – Arduino version

int inPin = 5;
int ledPin = 3;
int val;

void setup() {
  pinMode(inPin,INPUT);
  pinMode(ledPin,OUTPUT);
}

void loop() {
  val = analogRead(inPin);
  val = val*256/1024;
  analogWrite(ledPin,val);
  delay(50);
}

Exercise 9 – Making Sound – Arduino version

int sndPin = 2;

void setup() {
  pinMode(sndPin,OUTPUT);
}

void loop() {
  for (int i=0;i<50;i++) {
    digitalWrite(sndPin,HIGH);
    delayMicroseconds(1000);
    digitalWrite(sndPin,LOW);
    delayMicroseconds(1000);
  }
  delay(100);
}

Exercise 10 – Change the Sound with Potentiometer – Arduino version

int sndPin = 2;
int inPin = 5;
int val;

void setup() {
  pinMode(sndPin,OUTPUT);
}

void loop() {
  val = analogRead(inPin);
  digitalWrite(sndPin,HIGH);
  delayMicroseconds(val+100);
  digitalWrite(sndPin,LOW);
  delayMicroseconds(val+100);
}

Exercise 11 – Light Sensor – Arduino version
The code is the same as the potentiometer.

int sensorPin = 5;
int val;

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

void loop() {
  val = analogRead(sensorPin);
  Serial.println(val);
  delay(500);
}

Exercise 12 – Making Sound with Light Sensor – Arduino version
Combine the last 2 exercises to create interesting effect.

int sensorPin = 5;
int sndPin = 2;
int val;

void setup() {
  pinMode(sndPin,OUTPUT);
}

void loop() {
  val = analogRead(sensorPin);
  digitalWrite(sndPin,HIGH);
  delayMicroseconds(val*2);
  digitalWrite(sndPin,LOW);
  delayMicroseconds(val*2);
}

Exercise 13 – Knock Sensor – Arduino version
In fact, the piezo speaker can become a simple touch/knock sensor.

int piezoPin = 5;
int ledPin = 12;
int LIMIT1 = 300;
int LIMIT2 = 290;
int val = 0;

void setup() {
  pinMode(ledPin,OUTPUT);
}

void loop() {
  digitalWrite(ledPin,LOW);
  val = analogRead(piezoPin);
  if (val>LIMIT1) {
    digitalWrite(ledPin,HIGH);
    while (analogRead(piezoPin)>LIMIT2) {
    }
  }
}

Exercise 14 – Serial Communication 1 – Arduino version

int ledPin = 12;
int val = 0;

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

void loop() {
  if (Serial.available()>0) {
    val = Serial.read();
    if (val=='0') {
      digitalWrite(ledPin,LOW);
    }
    else if (val=='1') {
      digitalWrite(ledPin,HIGH);
    }
  }
}

Exercise 15 – Serial Communication 1 – Processing version

import processing.serial.*;

Serial port;
boolean light;

void setup() {
  size(200,200);
  println(Serial.list());
  port = new Serial(this,"COM27",9600);
  smooth();
  light = false;
  fill(255,255,0);
}

void draw() {
  background(0);
  if (light) {
    ellipse(width/2,height/2,80,80);
  }
}

void mousePressed() {
  port.write('1');
  light = true;
}

void mouseReleased() {
  port.write('0');
  light = false;
}

Exercise 16 – Serial Communication 2 – Arduino version

int inPin = 5;
int val = 0;

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

void loop() {
  val = analogRead(inPin);
  if (val<10) {
    Serial.print("000");
  } else if (val<100) {
    Serial.print("00");
  } else if (val<1000) {
    Serial.print("0");
  }
  Serial.println(val,DEC);
  delay(100);
}

Exercise 17 – Serial Communication 2 – Processing version

import processing.serial.*;

Serial port;
String buffer;
PFont font;
int eol;

void setup() {
  size(200,200);
  println(Serial.list());
  port = new Serial(this,Serial.list()[0],9600);
  eol = 10;
  font = loadFont("ArialMT-36.vlw");
  textFont(font);
  textAlign(CENTER);
  buffer = "";
  smooth();
  noStroke();
}

void draw() {
  if (port.available()>0) {
    buffer = port.readStringUntil(eol);
  }
  if (buffer!=null && buffer.length()>3) {
    background(0);
    buffer = buffer.substring(0,4);
    int val = int(buffer);
    val = val*width/1024;
    fill(255,255,0);
    ellipse(width/2,height/2,val,val);
    fill(0,100,255);
    text(buffer,width/2,height/2+10);
  }
}

Servo motor control – Arduino version

int SERVO = 11;
int val = 0;
int pulse = 0;

void setup() {
  pinMode(SERVO, OUTPUT);
  val = 0;
  Serial.begin(9600);
}

void loop() {
  if (Serial.available()) {
    val = Serial.read();
    if (val >= '0' && val <= '9') {
      val -= '0';
      val = val*(180/10);
    }
  }
  rotate(val);
  delay(20);
}

void rotate(int _p) {
  pulse = (_p*10)+600;
  digitalWrite(SERVO,HIGH);
  delayMicroseconds(pulse);
  digitalWrite(SERVO,LOW);
  delayMicroseconds(20000-pulse);
}


Servo motor control – Processing version

import processing.serial.*;

Serial port;

void setup() {
  size(200,200);
  println(Serial.list());
  port = new Serial(this,Serial.list()[1],9600);
  frameRate(15);
}

void draw() {
  background(0);
}

void mouseDragged() {
  int val = mouseX*10/width;
  val += 48;
  port.write((char) val);
}

Touch sensor demonstration – Arduino version

int TOUCH = 5;
int val = 0;

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

void loop() {
  val = analogRead(TOUCH);
  Serial.println(val,DEC);
  delay(50);
}

Touch sensor demonstration – Processing version

import processing.serial.*;

Serial port;
int val;
int eol = 10;

void setup() {
  size(200,200);
  println(Serial.list());
  port = new Serial(this,Serial.list()[1],9600);
  frameRate(15);
  val = 0;
  noStroke();
  fill(255,255,0);
  smooth();
}

void draw() {
  background(0);
  int num = val*width/1024;
  ellipse(width/2,height/2,num,num);
}

void serialEvent(Serial _p) {
  String s = _p.readStringUntil(eol);
  if (s!=null) {
    s = trim(s);
    val = int(s);
  }
}

Ultrasonic distance sensor – Arduino version

int RANGE = 2;
unsigned long distance = 0;

void setup() {
  beginSerial(9600);
}

void loop() {
  pinMode(RANGE, OUTPUT);
  digitalWrite(RANGE, LOW);
  delayMicroseconds(2);
  digitalWrite(RANGE, HIGH);
  delayMicroseconds(5);
  digitalWrite(RANGE, LOW); 

  pinMode(RANGE, INPUT);
  distance = pulseIn(RANGE,HIGH);
  Serial.println(distance,DEC);
  delay(500);
}