Skip navigation

… code

In the prototype data are taken from the plants, they pass through the first Arduino board and go in  the server computer.
Then data are trasmitted via wireless to the client computer, where they are processed to generate sounds in Pure Data and, at the same time, they are sent to the second Arduino that sets the brightness of leds in the cube.
To realize all this, we developed two Arduino sketches, to send and to receive data, and two Processing sketches to set appropriately the communications between the server and the client computer. Finally, we did five Pure Data patchs to generate sounds.

You need to a flashplayer enabled browser to view this YouTube video

This is a screenshot video, you can see how a basil play music. Sorry for the quality of the video. If you don’t see well the command’s strings on the programs’ windows, you can download the original video (approximately 30 MB) in the downolad page.

See the explaination of all sketches and patches.
Arduino and Processing sketches:

Arduino_send
This sketch must to be uploaded to the first Arduino.
It takes the values from the plant and the soil moisture sensor, then it sends the data to Processing in the server computer.

/////////////////////////////ARDUINO_SEND/////////////////////////////

//set pins to receive analog inputs from soil moisture sensors
int SoilP1 = 1;
int SoilP3 = 3;

//set pins to receive analog inputs from plants
int PlantP0 = 0;
int PlantPin2 = 2;

//data values from soil moisture sensors
int SoilV1 = 0;
int SoilV3 = 0;

//data values thath Arduino will send to Processing
int send_S_Val1 = 0;
int send_S_Val3 = 0;

//data values from plants. They will be sended to Processing directly
int send_P_Val0;
int send_P_Val2;

void setup() {
//open serial port, set data rate to 9600 bps
Serial.begin(9600);
}

void loop(){
//first plant
//read data from the first soil moisture sensor
SoilV1 = analogRead(SoilP1);

//the max data’s range, taked by analog pins, is reduced from 1024 values to 256 values
//this new range will become the brightness of RGB leds in the cube
send_S_Val1 = 255 – (map(SoilV1, 0, 1023, 0, 255));

//send data to Processing
Serial.println(send_S_Val1,DEC);
// delay(7);

//read data from the first plant
send_P_Val0 = analogRead(PlantP0);
// Serial.println(send_P_Val0);

//values from plants are reduced in only five values (zero to four)
//these values will become the notes in Pure Data
for(send_P_Val0 < 1024; send_P_Val0 >= 0; send_P_Val0 = send_P_Val0 – 5){
if(send_P_Val0 < 5){
if(send_P_Val0 == 0){Serial.println(“a”); delay(5);}
else if(send_P_Val0 == 1){Serial.println(“b”); delay(5);}
else if(send_P_Val0 == 2){Serial.println(“c”); delay(5);}
else if(send_P_Val0 == 3){Serial.println(“d”); delay(5);}
else if(send_P_Val0 == 4){Serial.println(“e”); delay(5);}

// Serial.println(send_P_Val0,DEC); //send data to Processing
}
}
// delay (7);

//second plant, same process.
//data from soil moisture sensor
SoilV3 = analogRead(SoilP3);
send_S_Val3 = 255 – (map(SoilV3, 0, 1023, 0, 255));
Serial.println(send_S_Val3,DEC);
//delay(7);

//data from plant
send_P_Val2 = analogRead(PlantPin2);
//values from plants are reduced in only five values (five to nine)
for(send_P_Val2 < 1024; send_P_Val2 >= 5; send_P_Val2 = send_P_Val2 – 5){
if(send_P_Val2 > 4 && send_P_Val2 < 10){
if(send_P_Val2 == 5){Serial.println(“f”); delay(5);}
else if(send_P_Val2 == 6){Serial.println(“g”); delay(5);}
else if(send_P_Val2 == 7){Serial.println(“h”); delay(5);}
else if(send_P_Val2 == 8){Serial.println(“i”); delay(5);}
else if(send_P_Val2 == 9){Serial.println(“j”); delay(5);}

// Serial.println(send_P_Val2,DEC);
}
}
//delay(7);
}

Processing_server
You must run this sketch on the server computer.
This sketch takes the data from the first Arduino board, then sets all the ports of server and client connections. The data taken from the first Arduino board (leaf-to-root and soil moisture values) are sent directly to Processing and Pure Data on the client computer.

/////////////////////////////PROCESSING_SERVER/////////////////////////////

//call the Processing net library
import processing.net.*;

//call the Processing serial library
import processing.serial.*;

//declaration of port as Serial object that connect Arduino to rocessing
Serial port;

//declaration client and server as object for the communication between server and client
Client greenone;
Client greentwo;
Client greenthree;
Client greenfour;
Server myServer;

//the char letterval will be compiled with the data sended by Arduino
char letterval;

//the string numval will be compiled with the data sended by Arduino
String val;
int lf = 10;

//Declaration of ports for net communication
int portd = 5216; //this port will recall in Pure Data (client computer)
int porte = 5217; //this port will recall in Pure Data (client computer)
int portf = 5218; //this port will recall in Pure Data (client computer)
int portg = 5219; //this port will recall in Pure Data (client computer)
int portS = 10002; //this port will recall in Processing (client computer)

void setup() {
size(200, 200);

// port 0 (zero) are the Arduino serial port that sends data to computer
// 9600 as baudrate (bps). It must to be the same as the baudrate declared in the first Arduino sketch
port = new Serial (this, Serial.list()[0], 9600);

//adresses and ports of server and client
greenone = new Client(this, “192.168.1.1″, portd); //plant 1: first sound’s pattern, it sounds happy
greentwo = new Client(this, “192.168.1.1″, porte); //plant 1: second sound’s pattern, it sounds sad
greenthree = new Client(this, “192.168.1.1″, portf); //plant 2: first sound’s pattern, it sounds happy
greenfour = new Client(this, “192.168.1.1″, portg); //plant 2: second sound’s pattern, it sounds sad

myServer = new Server(this, portS); // all plants: values for cube’s leds
}

void draw() {
background(0);

//check if the serial port are available
if (0 < port.available()) {

int numval = port.read();
val = port.readStringUntil(lf);
letterval = port.readChar();

//if the values from soil moisture sensor in the first plant are good, (the soil is wetted) data are sended to Pure Data to make the first sound’s pattern, it sounds happy.

//set the soil moisture “wet’s threshold”,
//you must change the value depending on the kind of your plant.
if(numval <127){

//plant 1: first sound’s pattern, it sounds happy
if (letterval == ‘a’){
greenone.write(str(0)); //first note
greenone.write(’;’);
delay(100);
}
else if (letterval == ‘b’){
greenone.write(str(1)); //second note
greenone.write(’;’);
delay(100);
}
else if (letterval == ‘c’){
greenone.write(str(2)); //third note
greenone.write(’;’);
delay(100);
}
else if (letterval == ‘d’){
greenone.write(str(3)); //fourt note
greenone.write(’;’);
delay(100);
}
else if (letterval == ‘e’){
greenone.write(str(4)); //fifth note
greenone.write(’;’);
delay(100);
}
}

//if the values from soil moisture sensor in the first plant are bad, (the soil is dry) data are sended to Pure Data to make the first sound’s pattern, it sounds sad.

//set the soil moisture “wet’s threshold”,
//you must change the value depending on the kind of your plant.
if(numval>126){

//plant 1: second sound’s pattern, it sounds sad
if (letterval == ‘a’){
greentwo.write(str(0)); //first note
greentwo.write(’;’);
delay(200);
}
else if (letterval == ‘b’){
greentwo.write(str(1)); //second note
greentwo.write(’;’);
delay(200);
}
else if (letterval == ‘c’){
greentwo.write(str(2)); //third note
greentwo.write(’;’);
delay(200);
}
else if (letterval == ‘d’){
greentwo.write(str(3)); //fourt note
greentwo.write(’;’);
delay(200);
}
else if (letterval == ‘e’){
greentwo.write(str(4)); //fifth note
greentwo.write(’;’);
delay(200);
}
}

//if the values from soil moisture sensor in the second plant are good (the soil is wetted), data are sended to Pure Data to make the first sound’s pattern, it sounds happy.

//set the soil moisture “wet’s threshold”,
//you must change the value depending on the kind of your plant.
if(numval<127){

//plant 2: first sound’s pattern, it sounds happy
if (letterval == ‘f’){
greenthree.write(str(5)); //first note
greenthree.write(’;’);
delay(100);
}
if (letterval == ‘g’){
greenthree.write(str(6)); //second note
greenthree.write(’;’);
delay(100);
}
if (letterval == ‘h’){
greenthree.write(str(7)); //third note
greenthree.write(’;’);
delay(100);
}
if (letterval == ‘i’){
greenthree.write(str(8)); //fourt note
greenthree.write(’;’);
delay(100);
}
if (letterval == ‘j’){
greenthree.write(str(9)); //fifth note
greenthree.write(’;’);
delay(100);
}
}

//if the values from soil moisture sensor in the second plant are bad (the soil is dry) data are sended to Pure Data to make the first sound’s pattern, it sounds sad

//set the soil moisture “wet’s threshold”,
//you must change the value depending on the kind of your plant.
if(numval<127){

//plant 2: second sound’s pattern, it sounds sad
if (letterval == ‘f’){
greenfour.write(str(5)); //first note
greenfour.write(’;’);
delay(200);
}
if (letterval == ‘g’){
greenfour.write(str(6)); //second note
greenfour.write(’;’);
delay(200);
}
if (letterval == ‘h’){
greenfour.write(str(7)); //third note
greenfour.write(’;’);
delay(200);
}
if (letterval == ‘i’){
greenfour.write(str(8)); //fourt note
greenfour.write(’;’);
delay(200);
}
if (letterval == ‘j’){
greenfour.write(str(9)); //fifth note
greenfour.write(’;’);
delay(200);
}
}

myServer.write(numval); // all plants: values for cube’s leds
myServer.write(’;’);

println(”soilONE__” + numval);
println(”plantONE_” + letterval);
println(”plantTWO_” + letterval);
}
}

Processing_client
You must run this sketch on the client computer.
Data taken from the server computer are sent directly to the second Arduino board.

/////////////////////////////PROCESSING_CLIENT/////////////////////////////

//call the Processing net library
import processing.net.*;

//call the Processing serial library
import processing.serial.*;

//declaration client as object for receive data from server computer
Client myClient;

//Declaration of port for net communication
int portC = 10002; //setted in the Processing_server sketch

//declaration of port as Serial object that connect Processing to Arduino
Serial portIN;
Serial portOUT;

//listen for input until it gets a linefeed character,
//and puts the bytes it gets into a byte[] buffer
int byteCount;

byte[] byteBuffer = new byte[12];
byte interesting = 10;

void setup() {
// port 1 (one) are the Arduino’s serial port that receive data from computer
// 9600 as baudrate (bps). It must to be the same as the baudrate declared in the second Arduino sketch
portOUT = new Serial (this, Serial.list()[1], 9600);

//adress and port of server computer
myClient = new Client(this, “192.168.1.2″, portC);
}

void draw() {
//check if the net port are available
if (myClient.available() > 0) {

//if background are black, the net communication works
background(0);

// Read until we get a linefeed
byteCount = myClient.readBytesUntil(interesting, byteBuffer);

//check if the serial port are available
// if (portOUT.available() > 0) { //I set off this command because the sketch doesn’t work (brobably there are a bug on my computer, sorry)

//send to Arduino board the values for cube’s leds
portOUT.write(byteCount);
println(byteCount);

// }
}
}

Arduino_receive
This sketch must to be uploaded to the second Arduino.
It takes the values from Processing, in the client computer and turn on/off cube’s leds depending on the values from soil moisture sensors. Arduino board has only three pins that work as analog output, so we could make only three leds fading (the other three are either completely on or off).

/////////////////////////////ARDUINO_RECEIVE/////////////////////////////

//set pins
int ledPin5 = 5; //digital pin
int ledPin6 = 6; //digital pin
int ledPin7 = 7; //digital pin
int ledPin11 = 11; //analog pin
int ledPin10 = 10; //analog pin
int ledPin9 = 9; //analog pin

//set integer variables for analog pins
int receiveVal_1 = 0;
int receiveVal_2 = 0;

void setup() {
//open serial port, set data rate to 9600 bps
Serial.begin(9600);

//set pins as output
pinMode(ledPin5, OUTPUT);
pinMode(ledPin6, OUTPUT);
pinMode(ledPin7, OUTPUT);
pinMode(ledPin11, OUTPUT);
pinMode(ledPin10, OUTPUT);
pinMode(ledPin9, OUTPUT);
}

void loop() {

// check if serial port send data from Processing
if (Serial.available() > 0) {

// set the leds on: these leds work as a fake “cube face linked to a plant”
digitalWrite(ledPin5, HIGH);
digitalWrite(ledPin6, HIGH);
digitalWrite(ledPin7, HIGH);
analogWrite(ledPin9, 255);

// read values from the first plant
receiveVal_1 = Serial.read();
// set the brightness of first led
analogWrite(ledPin10, 255-(receiveVal_1));

// read values from the second plant
receiveVal_2 = Serial.read();
// set the brightness of second led
analogWrite(ledPin11, 255-(receiveVal_2));

delay(1000); //the delay works to eliminate a led’s flick
}

}

Pure Data patches:


 
 
 
ard_proc_PD
This is the principal Pure Data patch.
It takes data sent from server computer and “filters” them, sending them to the four patches that generate sounds.


 
 
 
plant1_happy
Pure Data plays this patch when the first plant feels good (the soil is wet).
It assigns one note to each numeric value it receives. The patch makes a combination of notes to generate a happy sound melody.


 
 
 
plant1_sad
Pure Data plays this patch when the first plant feels bad (the soil is dry).
It assigns one note to each numeric value that is received. The patch makes a combination of notes to generate a sad sound melody.

plant2_happy
Pure Data plays this patch when the second plant feels good (the soil is wet).
It assigns one note to each numeric value it receives. The patch makes a combination of notes to generate a happy sound melody.

plant2_sad
Pure Data plays this patch when the second plant fills bad (the soil is dry).
It assigns one note to each numeric value that is received. The patch makes a combination of notes to generate a sad sound melody.
 
 
 
linfabeat | user experience | plants talk | how it looks like | how it works | first experiment | design: first concepts | design: final | prototype | code | credits | final consideration | downloads | research |