14 - Conectividad en red ethernet con Arduino

Volver al curso

Servidor HTTP sobre MCU Arduino

Así sería un automatismo industrial con servidor web:

Y así sería la planta industrial anterior adaptada a una maqueta Arduino:

El automatismo Arduino consiste en una casita de Lego que se conectará al router del aula mediante Arduino Ethernet Shield:

Se trata de un automatismo simple para control de temperatura.

Salidas:

Entradas:

Protocolo SPI

Ethernet Shield se conecta a Arduino usando un “HAT” o “shield” apilable que emplea protocolo SPI (Serial Peripheral Interface).

Estos son los pines que usa el Ethernet shield:

Para usar el shield ethernet hace falta incluir la librería “ethernet.h”. Este periférico también incluye un lector de tarjetas SD, cuyo código se incluye en “SD.h”.

 Código servidor web

Este es el código del programa. Está comentado:

#include <SPI.h>
#include <Ethernet.h>

byte mac[] = {0xDE, 0xAD, 0xBE, 0xEF, 0xED}; // Declaro mi direccion mac
IPAddress ip(192,168,1,200); // Declaro mi IP separada por comas //IP TELO5:69,57,70,102
EthernetServer server(80);
int lecturasensor = 0;
int temperaturaactual = 0;
int temperaturadeseada = 20;  // Valor de temperatura DESEADA
int potenciamotor = 0; //porcentaje de potencia que se manda al motor
int potenciamotoranalog = 0; // mapeado de variable anterior


void setup() {
  Serial.begin(9600);
  Ethernet.begin(mac, ip);
  pinMode(12, OUTPUT); //LED rojo (calefactor)
}

void loop() {
  // MI ZONA DE CÁLCULOS EMPIEZA AQUÍ
  lecturasensor = analogRead(A5);
  temperaturaactual = map(lecturasensor, 0, 1023, -50, 450); // Mapeo el sensor TMP36GZ
  Serial.println(temperaturaactual);

  if(temperaturadeseada - temperaturaactual > 5)
    {
      potenciamotor = 0;
      digitalWrite(12, HIGH); // Enciendo calefactor
    }
  else
    {
      digitalWrite(12, LOW); // Apago calefactor y enciendo ventilador a diferentes potencias:
      if(temperaturaactual < 1.05 * temperaturadeseada) potenciamotor = 0;
      if(temperaturaactual > 1.5 * temperaturadeseada) potenciamotor = 50;
      if(temperaturaactual > 4 * temperaturadeseada) potenciamotor = 100;
    }
  potenciamotoranalog = map(potenciamotor, 0, 100, 0, 255);
  analogWrite(3, potenciamotoranalog);

  Serial.print("Temperatura actual: ");
  Serial.print(temperaturaactual);
  Serial.print(", temperatura deseada: ");
  Serial.print(temperaturadeseada);
  Serial.print(", motor (%): ");
  Serial.println(potenciamotor);
  // MI ZONA DE CÁLCULOS TERMINA AQUÍ
  
  EthernetClient client = server.available();
  if (client) {
    Serial.println("Novo cliente!");
    // Codigo HTML para detectar peticion de datos
    boolean currentLineIsBlank = true;
    while (client.connected()) {
      if (client.available()) {
        char c = client.read();
        Serial.write(c);
        
        if (c == '\n' && currentLineIsBlank) {
          // Envia cabeceira HTTP estandar
          client.println("HTTP/1.1 200 OK");
          client.println("Content-Type: text/html");
          client.println("Connnection: close");
          client.println();
          client.println("<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd\">");
          client.println("<html xmlns=\"http://www.w3.org/1999/xhtml\" lang=\"es\" xml:lang=\"es\">");
         // Forza que o navegador refresque a paxina automaticamente cada 5 segundos:
          client.println("<meta http-equiv=\"refresh\" content=\"5\">");
          client.println("<head>");
          client.println("<title>Control de casita Arduino</title>");
          client.println("</head>");

          client.println("<body>");
          
          // MI CÓDIGO HTML EMPIEZA AQUÍ           
          client.print("Temperatura actual: ");
          client.print(temperaturaactual);
          client.println(" grados celsius.");
          // MI CÓDIGO HTML TERMINA AQUÍ


          client.println("</body>");

          client.println("</html>");
          break;
        }
        if (c == '\n') {
          currentLineIsBlank = true;
        } 
        else if (c != '\r') {
          currentLineIsBlank = false;
        }
      }
    }
    // Tempo para qua o cliente reciba os datos...
    delay(1);
    client.stop();
    Serial.println("Cliente desconetado (");
  }
}

A continuación sólo la parte HTML. En el Arduino cada línea tiene que ir envuelta en client.println(); Es muy sencilla:

HTTP/1.1 200 OK
Content-Type: text/html
Connnection: close

<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Strict//EN" http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd\">
<html xmlns=\"http://www.w3.org/1999/xhtml\" lang=\"es\" xml:lang=\"es\">
// Forza que o navegador refresque a paxina automaticamente cada 5 segundos:
<meta http-equiv=\"refresh\" content=\"5\">

<head>
<title>Control de casita Arduino</title>
</head>

<body>        
Temperatura actual: 
temperaturaactual
grados celsius.
</body>

</html>

Así luce:

Tarea 14.1 - Servidor web mejorado

Mejora el automatismo de la casa de Lego y tu puntuación haciendo alguna de las siguientes tareas:

  1. Sensor de apertura de puerta (pulsador final de carrera) que haga saltar un aviso de puerta abierta en la página web.
  2. LEDs de alumbrado en cada planta que se activen mediante pulsador físico y mediante pulsador en la página web.
  3. Hacer que la temperatura deseada se elija por potenciómetro, se muestre en la página web y por serial.
  4. Añadir control analógico mediante slider para el motor DC desde el servidor web. Instrucciones y código HTML de ejemplo.

 Tarea 14.2 - Botones dentro del servidor web

Prueba el siguiente programa y modifícalo para tener más actuadores: subir y bajar una persiana con un motor DC, etc.

#include <SPI.h>
#include <Ethernet.h>
//Declaración de direccionss MAC e IP.
byte mac[]={0xDE,0xAD,0xBE,0xEF,0xFE,0xED}; //MAC
IPAddress ip(192,168,1,177); //IP
EthernetServer servidor(80);
int ledPin=8;  
String readString=String(30);
String state=String(3);    //String para almacenar o estado

void setup()
{
  Ethernet.begin(mac, ip);
  servidor.begin();
  pinMode(ledPin,OUTPUT);
  digitalWrite(ledPin,LOW);
  state="OFF";   // Inicialmente apagada
}

void loop()
{
  EthernetClient cliente= servidor.available();
  
  if(cliente)
  {
    boolean lineaenblanco=true;
    while(cliente.connected())//Cliente conectado
    {
      if(cliente.available())
      {
        char c=cliente.read();
        if(readString.length()<30)//Lemos petición HTTP caracter a caracter
        {
          readString.concat(c); //Almacenar os caracteres na variable readString
        }
        if(c=='\n' && lineaenblanco)//Se a petición HTTP finalizou
        {
          int LED = readString.indexOf("LED=");
          
          if(readString.substring(LED,LED+5)=="LED=T")  // Se na web se manda True...
          {
            digitalWrite(ledPin ,HIGH);
            state="ON";
            
          } else if (readString.substring(LED,LED+5)=="LED=F") //Se na web se manda False...
          {
            digitalWrite(ledPin,LOW);
            state="OFF";
          }
                    
          //Cabeceira HTTP estándar
          cliente.println("HTTP/1.1 200 OK");
          cliente.println("Content-Type: text/html");
          cliente.println();        
          cliente.println("<html>");
          cliente.println("<head>");
          //Título da páxina
          cliente.println("<title>LAMPADA ON/OFF</title>"); 
          cliente.println("</head>");
          cliente.println("<body width=100% height=100%>");
          //Texto na paxina (centrado):
          cliente.println("<center>");
          cliente.println("<h1>LAMPADA ON/OFF</h1>");
          cliente.print("<br><br>");
          //Liñas para indicar o estado da lampada
          cliente.print("Estado da lampada: ");  
          cliente.print(state);
          //Botóns para accionar os comandos HTML:
          cliente.print("<br><br><br><br>");
          cliente.println("<input type=submit value=ON style=width:200px;height:75px onClick=location.href='./?LED=T\'>");
          cliente.println("<input type=submit value=OFF style=width:200px;height:75px onClick=location.href='./?LED=F\'>");
          cliente.println("</center>");
          cliente.println("</body>");
          cliente.println("</html>");
          cliente.stop(); //Pêcho conexión co cliente
          readString="";
        }
      }
    }
  }
}

Fuente: “Introducción ao Arduino” - David Touceda Bugallo, 2014


Volver al curso