Skip navigation

… code & physical computing

In order to control physical mechanics movements and software managed communications and feeds, we wrote the code for an Arduino board, controlling motors, lights and switches, and for a computer running Processing, recording audio from an external microphone and givig the output to a couple of speakers.

To be able to reset the installation and to enable special functions, we wrote also the code for a mobile phone remote controller in Mobile Processing.

Tested one by one all the single features, the bigger amount of work was the syncronization of these three controllers and the communication to each other. The solution to this issue has been reached dividing the work in smaller steps (or applications) and keeping the code clean and, where possible, well commented.

We’ll give now an overview to the code.

Arduino Code

The Arduino board is connected through USB wiring to a computer, that manages the sounds for the installation’s messages and the input from the remote controller. It gives the prototype electricity and makes it possible to read or write serial communications, in wich each information is vehiculated one bit at one time.

Serial.begin(9600);
(…)
valA = digitalRead(switchAPin);
if (valA == HIGH){
Serial.println(valA);
}

We didn’t had enough time to retrieve a servo-motor, so we had to write a particoular code to control a simple 12V DC motor through an H-Bridge, an integrated electronic circuit which enables a voltage to be applied across a load in either direction. For example, to produce waves on the water surface, we let the motor work for ten steps in one direction, intervealed with ten milliseconds breaks, and then we reverse the direction for the same number of steps. The fin connected to the motor arm will so describe an angle of 40° on the water surface, producing long enough waves.

void makeWaves(){
int i = 0;
for(i = 0; i < 10; i++){ // could be made also with millis
digitalWrite(motor3Pin, LOW); // set leg 1 of the H-bridge low
digitalWrite(motor4Pin, HIGH); // set leg 2 of the H-bridge high
delay(10);
digitalWrite(motor3Pin, LOW); // set leg 1 of the H-bridge low
digitalWrite(motor4Pin, LOW); // set leg 2 of the H-bridge low
delay(10);
}
delay(100);
for(i = 10; i > 0; i–){
digitalWrite(motor3Pin, HIGH); // set leg 1 of the H-bridge low
digitalWrite(motor4Pin, LOW); // set leg 2 of the H-bridge high
delay(10);
digitalWrite(motor3Pin, HIGH); // set leg 1 of the H-bridge low
digitalWrite(motor4Pin, HIGH); // set leg 2 of the H-bridge low
delay(10);
}
delay(100);
}

In the same way we control the magnetic slider hidden below the water basin driving the message above, using a couple of swiches to know when it reaches the end of his path and stop it.

case 3: // wait until the message reaches the end and stop the motors

makeWaves();
valB = digitalRead(switchBPin);
if (valB == HIGH){
Serial.println(‘H’);
digitalWrite(motor1Pin, LOW); // set leg 1 of the H-bridge low
digitalWrite(motor2Pin, LOW); // set leg 2 of the H-bridge low
digitalWrite(motor3Pin, LOW); // set leg 3 of the H-bridge low
digitalWrite(motor4Pin, LOW); // set leg 4 of the H-bridge low
mode++;
}
break;

Processing Code

To be able to register and play sounds, we use the Sonia library by Amit Pitaru. We also need the Processing core Serial library and the bluethootDesktop library by Patrick Meister to communicate with the Arduino and a bluetooth enabled mobile phone.

import pitaru.sonia_v2_9.*;
import processing.serial.*;
import bluetoothDesktop.*;

As seen with the Arduino code above, we split the code in different status modes, in order to easily operate in the different logical installation times. In each of them it’s always a good thing to put a debug print line to retrieve possible errors. In the two cases below you can see how is possible to register and save a message from an audio stream.

// switch between the installation status modes
switch(mode) {
(…)
case 2: // set the time and start recording

if (millis() > time){
time = millis() + 10500;
LiveInput.startRec(mySampleObj); // Record LiveInput data into the Sample object.
println(“mode ” + mode + ” ok”);
mode++;
}
break;

case 3: // record for tot secs and save the message file

if (millis() > time){
LiveInput.stopRec(mySampleObj);
message = nomeSnd + numSnd;
mySampleObj.saveFile(message);
numSnd++;
val = 0;
println(“mode ” + mode + ” ok”);
mode++;
}
break;

And below you see how to listen to it.

case 8: // start playback

if (millis() > time){
Sample mySample;
mySample = new Sample(message + “.wav”);
mySample.play();
mode++;
}
break

Mobile Processing Code

We used a bluetooth enabled mobile phone as remote controller to reset the installation, sending serial strings to Processing, importing the Mobile Processing bluetooth core library.

import processing.bluetooth.*;

The code written below shows how to discover client connected to the application specific bluetooth service called “vyasaService” and how to easily send text message to them with the function “writeUTF” when a key is pressed.

final String SERVICE_NAME = “vyasaService”;
bt = new Bluetooth(this, 0×0003); // RFCOMM

bt.start(SERVICE_NAME);
(…)
// gets called by BT if something happens
void libraryEvent(Object library, int event, Object data) {
if (library == bt) {
if (event == Bluetooth.EVENT_CLIENT_CONNECTED) {
// a new client is connected.
c = (Client)data;
clients = (String[]) append(clients, ((Client) data).device.name);
msg = clients.length + ” Clients connected:”;
c.writeUTF(“connection message confirmation to the client”);
c.flush();
connected = true;
}
}
}

// send message to processing to change status modes
void keyPressed() {
if (connected == true) {
c.writeUTF(“ciao”);
c.flush();
msg = “sent ” + e;
e++;
}
}

<< Previous | Next >>

Vyasa | concept | early experiments | how it works | prototyping | final prototype | code & physical computing | learning by going | possible improvements | credits | downloads