Sensors_Socket_Processing


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.

Figure 1: Program developed with Processing





    
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
3 x buttons
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. 


Figure 4: Electric scheme of the “Sensor Shield”

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);
}