Send Data Sensor from Arduino to Processing
ABSTRACT
The project presented here it is a TCP/IP socket system between an Arduino Ethernet Shield and a program running in a laptop elaborated by Processing. To demonstrate a total communication between the client and the server of the TCP/IP socket, I’ve designed a program in which the data sensors are represented in the screen and when a button is pushed, the client or the server respond with a light.
The analog signals captured by Arduino are the signal of a potentiometer, a temperature sensor, a humidity air sensor and a soil moisture sensor. Furthermore, I’ve connected to Arduino three buttons in the digital inputs and three led in the digital outputs. On one hand, the information of the sensors is represented by Processing. When a button is pressed, the lamp of the Processing program changes his color. One button is for the red color, other for the yellow color and another for the green color. On the other hand, there are three buttons in the Processing Program. If you press one of them, you switch on a led for a second on the Sensor Shield.
Figure 2: Sensor shield over Ethernet shield |
MATERIALS
1 x Arduino Uno and USB wire
1 x Arduino Ethernet Shield
1 x Ethernet Cat.5 Crosswire
1 x Humidity Sensor: 808H5V5
1 x Potentiometer: 10kΩ
1 x Temperature Sensor: MCP9700A
1 x Soil Moisture Sensor
Res.: 3 x 330Ω, 3 x 10KΩ
Leds: 1 x Red, 1 x Yellow, 1 x Green
Wires, proto-board, solder lead …
Figure 3: The materials used. The Arduino board, the Ethernet shield and the Sensor Shield. |
Figure 4: Another view of the Arduino board, the Ethernet shield and the Sensor Shield. |
DEVELOPMENT
This project has two parts. The first part corresponds to develop of the hardware for Arduino that I’ve called Sensor Shield and the other part corresponds to the programming of a server in Processing. The Processing code is in the Appendix 1 and the Arduino code is in the Appendix 2.
The Shields are connected to Arduino like a sandwich. The Ethernet Shield is over Arduino and the Sensor Shield is on the top. The assembly is shown in the picture 2. The electric scheme of the Sensor Shield is depicted in the Figure 5.
The sensors have three pins. The left pin is for VCC, the right pin for GND and the central pins are the outputs. The information about the temperature and humidity sensor is in [1]. The soil moisture sensor is deeply described in [2]. The temperature sensor output is connected to the analog input A0, the humidity sensor output to A1, the potentiometer to A2 and finally the soil moisture sensor output to A3. Arduino checks an analog input each 160 milliseconds approximately. After reading the analog inputs and translate de data, Arduino send the data to server.
The green led is connected to the digital output 8, the red led to digital output 7 and the yellow led is connected to the digital output 6. The led bright when they have a high level of tension in the anode. That’s happens when a button of the Processing program is pushed because the server send a message to Arduino (the client of the socket) through the Ethernet wire that it is decoded by Arduino.
The inverse case occurs when a button is pushed on the
Arduino board. The client sends a message to the server and the Processing
program answers changing the color of the lamp. The button for the red lamp is
connected to the digital output 2. The button for the green lamp is connected
to the digital output 3 and the button for the yellow lamp is connected to the
digital output 4.
The Processing code is the server of the TCP/IP socket. This program is continuously checking the data of the port 2000 and then, these data is represented in the screen.
Figure 6: The Processing program at the left and the debugging screen of Arduino at the right |
RESULTS
The results are shown in the next video.
REFERENCE
[1] http://www.libelium.com/documentation/waspmote/gases-sensor-board_esp.pdf
[2] http://www.elecfreaks.com/3162.html
[3] Programming Interactivity. Joshua Noble. O’Reilly
APPENDIX 1
Processing code
//Libraries???
import java.applet.*;
import java.awt.*;
import java.awt.event.*;
import java.awt.image.*;
import java.text.*;
import processing.net.*;
PFont font, font2, font3;
PImage bombilla; // Declare variable "bombilla" of type PImage
Server myServer;
Client thisClient;
//Global variables
boolean circleYellow = false;
boolean circleGreen = false;
boolean circleRed = false;
boolean circleOver = false;
color colorRed=color(255, 0, 0);
color colorGreen=color(0, 255, 0);
color colorYellow=color(255, 255, 0);
color colorGrey=color(150);
int circleRedX=100, circleRedY=360, circleGreenX=400, circleGreenY=360, circleYellowX=250, circleYellowY=360, circleSize = 100; // Position of circle button
int m=-10, n=0, i, a=260, b=160, radio=255, commaPosition;
int port=2000,tempInt=0,humInt=0,potInt=0,moiInt=0;
float angulo;
String whatClientSaid,tempString="0",humString="0",potString="0",moiString="0";
String dataRed="RED",dataYellow="YELLOW",dataGreen="GREEN";
void setup()
{
size(700, 480);
background(150); // Dark grey color
// Starts a myServer on port 2000
myServer = new Server(this, 2000);
font = loadFont("Univers-Bold-12.vlw");
font3 = loadFont("AndaleMono-36.vlw");
font2 = loadFont("CourierNew-12.vlw");
//In this part I want to draw a thermometer
strokeWeight(2); // Stroke weight to 8 pixels
fill(255, 255, 255); // White color
arc(50, 40, 32, 32, PI, TWO_PI);
ellipse(50, 260, 60, 60);
line(34, 40, 34, 236);
line(66, 40, 66, 236);
noStroke();
rect(35, 40, 30, 220);
fill(255, 0, 0); // Red color
ellipse(50, 260, 58, 58); // Red circle
rect(35, 231, 30, 10);
//Here I write the titles, the letters and numbers
stroke(0);
strokeWeight(3);
smooth();
fill(0);
textFont(font);
textSize(14);
text("TERMÓMETRO", 6, 20);
text("POTENCIÓMETRO", 200, 20);
text("HIGRÓMETRO", 500, 20);
text("BOMBILLA", 560, 160);
text("HUMEDAD DE LA TIERRA",20,450);
textSize(12);
do
{
if (n%2==0)
{
line(65, 229-n, 55, 229-n);
text(m, 70, 232-n);
}
else
{
line(65, 229-n, 60, 229-n);
text(m, 70, 232-n);
}
n+=15;
m+=5;
}
while ( n<190);
//In this part I want to draw a kilometer-counter
strokeWeight(3);
fill(255);
ellipse(a, b, radio, radio); // Red circle
strokeWeight(2);
n=0;
for (int i =0; i < 360; i+=PI)
{
n++;
float x=a+((radio-3)/2)*sin(i);
float y=b+((radio-3)/2)*cos(i);
if (n%3==0) stroke(colorRed);
else stroke(0);
line(x, y, a, b);
}
noStroke();
fill(255);
ellipse(a, b, radio-40, radio-40);
arc(a, b, radio-2, radio-2, radians(30), radians(145));
stroke(0);
strokeWeight(12);
point(a, b);
//In this part I want to draw the box of humidity information
strokeWeight(3);
fill(255);
rect(450, 30, 223, 70);
fill(0);
smooth();
textFont(font2);
textSize(80);
text("%", 620, 90);
//Here I load bombilla.bmp
stroke(0);
strokeWeight(3);
noFill();
bombilla = loadImage("bombilla.bmp");
image(bombilla, 520, 170, bombilla.width/2, bombilla.height/2);
rect(518, 168, bombilla.width/2, bombilla.height/2);
//Here I draw the box of the text of Soil Humidity Sensor
strokeWeight(3);
fill(255);
rect(200, 430, 473, 40);
fill(0);
smooth();
textFont(font2);
textSize(40);
text("Soil", 560, 463);
}
void draw()
{
color CRed, CYellow, CGreen;
update(mouseX, mouseY);
//In this part I read the data received by the client,
thisClient = myServer.available();
if (thisClient !=null)
{
whatClientSaid = thisClient.readString();
if (whatClientSaid != null)
{
println(whatClientSaid); //for debugging
int longitud = whatClientSaid.length(); //for debugging
print("Longitud de la cadena: "); println(longitud); //for debugging
//If the data received are "RED","YELLOW","GREEN"
if (whatClientSaid.equals(dataRed)==true)
{
bombilla = loadImage("bombillaRoja.bmp");
}
else if (whatClientSaid.equals(dataGreen)==true)
{
bombilla = loadImage("bombillaVerde.bmp");
}
else if(whatClientSaid.equals(dataYellow)==true)
{
bombilla = loadImage("bombillaAmarilla.bmp");
}
else
{
//then I split the chain of characters to separate the data of the sensors
String[] lista=whatClientSaid.split(",");
if(lista.length==4)
{
tempString=lista[0];
humString=lista[1];
potString=lista[2];
moiString=lista[3];
}
int[] valor=int(whatClientSaid.split(","));
if (valor.length==4)
{
tempInt=valor[0];
humInt=valor[1];
potInt=valor[2];
moiInt=valor[3];
}
print(tempString); print(","); print(humString); print(","); println(potString); print(","); println(moiString);//For debbugging
}
image(bombilla, 520, 170, bombilla.width/2, bombilla.height/2);
noFill();
rect(518, 168, bombilla.width/2, bombilla.height/2);//Bombilla Blanca
}
}
//This part is code for the rollover
if (circleRed)
{
if (mousePressed)
{
CRed=colorRed;
CYellow=colorGrey;
CGreen=colorGrey;
if (thisClient !=null) thisClient.write("RED");
}
else
{
CRed=colorGrey;
CYellow=colorGrey;
CGreen=colorGrey;
}
}
else if (circleYellow)
{
if (mousePressed)
{
CRed=colorGrey;
CYellow=colorYellow;
CGreen=colorGrey;
if (thisClient !=null) thisClient.write("YELLOW");
}
else
{
CRed=colorGrey;
CYellow=colorGrey;
CGreen=colorGrey;
}
}
else if (circleGreen)
{
if (mousePressed)
{
CRed=colorGrey;
CYellow=colorGrey;
CGreen=colorGreen;
if (thisClient !=null) thisClient.write("GREEN");
}
else
{
CRed=colorGrey;
CYellow=colorGrey;
CGreen=colorGrey;
}
}
else
{
CRed=colorGrey;
CYellow=colorGrey;
CGreen=colorGrey;
}
//In this part I draw the the circles
strokeWeight(5);
fill(CRed);
ellipse(circleRedX, circleRedY, circleSize, circleSize); // Red circle
fill(CYellow);
ellipse(circleYellowX, circleYellowY, circleSize, circleSize); // Orange circle
fill(CGreen);
ellipse(circleGreenX, circleGreenY, circleSize, circleSize); // Green circle
strokeWeight(3);
smooth();
fill(0);
textSize(14);
textFont(font);
text("LED ROJO ", circleRedX-29, circleRedY+4);
text("LED AMARILLO", circleYellowX-42, circleYellowY+4);
text("LED VERDE", circleGreenX-33, circleGreenY+4);
//In this part I recompound the thermometer
noStroke();
fill(255);
rect(35, 40, 30, 194);
fill(colorRed);
if (whatClientSaid != null)
{
fill(colorRed); // Red color
ellipse(50, 260, 50, 50); // Red circle
int tope=(-tempInt*3)-36;
if(tope<=-194) tope=-194;
rect(35, 234, 30,tope );
stroke(0);
fill(0);
text(tempString+"ºC", 39, 265);
}
else rect(35, 234, 30, -36);
stroke(0);
strokeWeight(3);
smooth();
fill(0);
n=0;
do
{
if (n%2==0)
{
line(65, 229-n, 55, 229-n);
}
else
{
line(65, 229-n, 60, 229-n);
}
n+=15;
}
while ( n<190);
//In this part I recompound the counter-kilometer
noStroke();
fill(255);
ellipse(a, b, radio-32, radio-32);
stroke(0);
strokeWeight(12);
point(a, b);
strokeWeight(2);
fill(0);
angulo = map(potInt,0,1023,radians(145), radians(390));
line(a, b, cos(angulo) * (radio/2-18) + a, sin(angulo) *(radio/2-18) + b);
strokeWeight(3);
if (whatClientSaid != null)
{
textFont(font3);
textSize(30);
if(potInt>=100) text(potString, 235, 250);
else text(potString, 242, 250);
}
//In this part I recompound the box of humidity information
strokeWeight(3);
fill(255);
rect(450, 30, 222, 70);
fill(0);
smooth();
textFont(font2);
textSize(80);
if (whatClientSaid != null) text(humString, 500, 90);
text("%", 600, 90);
//In this part I recompound the box of Soil Moisture information
strokeWeight(3);
fill(255);
rect(200, 430, 473, 40);
fill(0);
smooth();
textSize(40);
if (whatClientSaid != null)
{
if(moiInt<300) text("Dry", 360, 463);
else if(300<moiInt&&moiInt<600) text("Humid", 350, 463);
else text("In water", 300, 463);
}
text("Soil", 520, 463);
//This lines are for debugging and to know the coordinates of the mouse
//print("(");print(mouseX);print(",");print(mouseY);println(")");
}
void update(int x, int y)
{
if ( overCircle(circleRedX, circleRedY, circleSize) )
{
circleRed = true;
}
else if ( overCircle(circleYellowX, circleYellowY, circleSize) )
{
circleYellow = true;
}
else if ( overCircle(circleGreenX, circleGreenY, circleSize) )
{
circleGreen = true;
}
else
{
circleRed = circleYellow = circleGreen = false;
}
}
boolean overCircle(int x, int y, int diameter)
{
float disX = x - mouseX;
float disY = y - mouseY;
if (sqrt(sq(disX) + sq(disY)) < diameter/2 )
{
return true;
}
else
{
return false;
}
}
APPENDIX 2
Arduino code:
/*
It reads the sensor signals of the analog inputs and send the data to the server through ethernet wires.
The comunication is full-duplex and both devices can send data. In this example Arduino send the data of the sensor
to the touch screen. also, The touch screen can also send chain of characters to Arduino. If this happens, the microcontroller
will switch on the RGB led connected to the digital outputs 7,8,9.
*/
#include <SPI.h>
#include <Ethernet.h>
#include <Bounce.h>
static int temperaturePin = 0;//Analog input
static int potenciometroPin = 1;//Analog input
static int humidityPin=2;//Analog input
static int moisturePin=3;//Analog input
const int redButton=2;//Digital input
const int greenButton=3;//Digital input
const int yellowButton=4;//Digital input
const int greenPin=7;//Digital output
const int redPin=8;//Digital output
const int yellowPin=9;//Digital output
static int valueRed=0;
static int valueGreen=0;
static int valueYellow=0;
// Enter a MAC address for your controller below.
// Newer Ethernet shields have a MAC address printed on a sticker on the shield
byte mac[] = {0x90, 0xA2, 0xDA, 0x0D, 0x21, 0x08};
byte ipclient[] ={169,254,1,8};
byte gateway[]={169,254,1,4};
byte subnet[]={255,255,0,0};
unsigned int port=2000;
IPAddress server(169,254,1,4); //PC
// Initialize the Ethernet client library with the IP address and port of the server
EthernetClient client;
// Instantiate a Bounce object with a 5 millisecond debounce time
Bounce bouncerRed = Bounce( redButton,5 );
Bounce bouncerGreen = Bounce( greenButton,5 );
Bounce bouncerYellow = Bounce( yellowButton,5 );
float Temperatura(void);
float Potenciometro (void);
float Humedad(void);
int SoilMoisture(void);
void RED(void);
void GREEN(void);
void YELLOW(void);
void LedOff(void);
void setup()
{
Serial.begin(9600);
pinMode(redButton,INPUT);//Pin 2 as a digital input
pinMode(greenButton,INPUT);//Pin 3 as a digital input
pinMode(yellowButton,INPUT);//Pin 4 as a digital input
pinMode(redPin, OUTPUT); //Pin 7 as a digital output
pinMode(yellowPin, OUTPUT); //Pin 9 as a digital output
pinMode(greenPin, OUTPUT); //Pin 8 as a digital output
LedOff();//Led off
Ethernet.begin(mac,ipclient,server,gateway,subnet);
// give the Ethernet shield a second to initialize:
delay(1000);
Serial.println("connecting...");
// if you get a connection, report back via serial:
if (client.connect(server,2000))
{
Serial.println("connected");
// Make a HTTP request:
client.println("Connecting with Arduino Ethernet");
client.println();
}
else
{
// if you didn't get a connection to the server:
Serial.println("connection failed");
}
delay(500);
Serial.println("\n Press Reset to restart \n");
delay(500);
}
void loop()
{
String color,red="RED",yellow="YELLOW",green="GREEN";//The data received is save here
char c=0;
LedOff();//Led off
//if one button is push, Arduino will send a string with the name of a color
bouncerRed.update( );// Update the debouncer
valueRed = bouncerRed.read();// Get the update value
bouncerGreen.update ( );
valueGreen = bouncerGreen.read();
bouncerYellow.update( );
valueYellow = bouncerYellow.read();
if (valueRed)
{
client.print(red);
Serial.println(red);
}
else if (valueGreen)
{
client.print(green);
Serial.println(green);
}
else if (valueYellow)
{
client.print(yellow);
Serial.println(yellow);
}
float temp=Temperatura();
float pot=Potenciometro();
float hum=Humedad();
int moi=SoilMoisture();
Serial.println(" ");
client.print(temp,0);
client.print(",");
client.print(hum,0);
client.print(",");
client.print(pot,0);
client.print(",");
client.print(moi);
delay(150);
// if there are incoming bytes available from the server, read them and print them:
if(client.available())
{
Serial.print("Data received: ");
while(client.available())
{
c = client.read();
Serial.print(c);
if(c == '\n')
break;
color.concat(c);//Concatenates the two strings of characters
}
if (color.equals(red)==true)
{
Serial.println("\nThe led bright with the color red.\n");
RED();
}
else if (color.equals(green)==true)
{
Serial.println("\nThe led bright with the color green.\n");
GREEN();
}
else if(color.equals(yellow)==true)
{
Serial.println("\nThe led bright with the color yellow.\n");
YELLOW();
}
else
{
Serial.println("\nData received is unknown.\n");
LedOff();//Led off
}
}
// if the server's disconnected, stop the client:
if (!client.connected())
{
Serial.println();
Serial.println("disconnecting.");
client.stop();
// do nothing forevermore:
LedOff();//Led off
while(1);
}
delay(10);
}
float Temperatura(void)
{
//the analog pin the TMP36's Vout (sense) pin is connected to the resolution is 10 mV / degree centigrade.
//(500 mV offset) to make negative temperatures an option
float temperature=analogRead(temperaturePin) * .004882814;//converting from a 0 to 1023 digital range
// to 0 to 5 volts (each 1 reading equals ~ 5 millivolts.Example: 5:1024=0.004882814
temperature = (temperature - .5) * 100;//0 degree begins in 500mV
Serial.print("Temperatura: ");
Serial.print(temperature,2);
Serial.println("\260C");
delay(150);
return(temperature);
}
float Potenciometro (void)
{
//Función que muestra el valor de tensión de la entrada analogica, que depende del valor del potenciometro
float Vout=analogRead(potenciometroPin);
Serial.print("Valor del potenciometro: ");
Serial.println(Vout);
delay(150);
return(Vout);
}
/*
En el caso del sesor de humedad 808H5V5, la ecuación sufrirá modificaciones en función de la señal de referencia, dado que en uno de los casos utilizamos un divisor de tensión.
En la versión a 5V, comprobando las hojas de características vemos que el sensor entrega 0,8V para un 0% de HR y 3,9V para el 100%. Por lo tanto, a la señal medida en mV le restamos 800mV,
y para obtener el dato en porcentaje, dividimos el resultado entre 31 (3900 - 800=3100):
*/
float Humedad (void)
{
//5V=1024;5000mV/1024=4.882814mv por unidad
float humidity=analogRead(humidityPin)* 4.882814;
humidity=(humidity-800)/31;//Conversion of milivolts to humidity
Serial.print("Humedad: ");
Serial.print(humidity,0);
Serial.println("%");
delay(150);
return(humidity);
}
/*The sensor value description:
# 0 ~300 dry soil
# 300~700 humid soil
# 700~950 in water
Octopus Soil Moisture Sensor Brick can read the amount of moisture present in the soil surrounding it.
It’s a low tech sensor, but ideal for monitoring an urban garden, or your pet plant’s water level.
This sensor uses the two probes to pass current through the soil, and then it reads that resistance to get the moisture level.
More water makes the soil conduct electricity more easily (less resistance), while dry soil conducts electricity poorly (more resistance).
*/
int SoilMoisture(void)
{
int moisture=analogRead(moisturePin);
Serial.print("Humedad de la tierra: ");
Serial.println(moisture);
delay(150);
return(moisture);
}
void RED(void)
{
analogWrite(redPin,255);
analogWrite(greenPin,0);
analogWrite(yellowPin,0);
delay(1000);
}
void GREEN(void)
{
analogWrite(redPin,0);
analogWrite(greenPin,255);
analogWrite(yellowPin,0);
delay(1000);
}
void YELLOW(void)
{
analogWrite(redPin,0);
analogWrite(greenPin,0);
analogWrite(yellowPin,255);
delay(1000);
}
void LedOff(void)
{
analogWrite(redPin,0);
analogWrite(greenPin,0);
analogWrite(yellowPin,0);
delay(500);
}