Página principal
Arduino
Medidor temperatura, servidor WEB, reloj.
xsetaseta@gmail.com

Este montaje es una mezcla de varios de los anteriores proyectos, es un medidor de temperatura de dos sensores interior y exterior, un pequeño servidor de web en modo texto, y un pequeño reloj funcionando mediante interrupciones internas.
Utiliza la tarjeta Arduino Ethernet Shieldb con lectora de tarjetas micro SD.

-El medidor de temperatura se basa en dos sensores DS18S20 colocados en un cable de dos hilos utilizando la librería OneWire.
Para mas detalles recomiendo mi anterior montaje ardusd.html
La lectura de la temperatura se efectúa  dos veces por minuto, en el segundo 5 y en el 30.

Esquema de los sensores de temperatura.

-Para el servidor de web en modo texto,  utilizo un fichero llamado html.txt almacenado en una tarjeta micro SD.
Aquí se puede poner el texto que se desee visualizar en el servidor, debe tener formato html, demás he añadido un pequeño script hecho en JavaScript para ver la fecha y la hora del navegador.
Ya que vivo en Palencia, he puesto un texto sacado de Wikipedia sobre la ciudad.
int LeerSD()
{
 File midataFile;
  midataFile=SD.open("html.txt", FILE_READ);
  if(midataFile)
   {   
     while (midataFile.available())
       {
        client.write(midataFile.read());
       }     
     midataFile.close();
   }
    else
   {
    Serial.println("Error read SD ");  
   }
}

Código del volcado del fichero html.txt en la página web

-El reloj de tiempo real se basa en interrupciones internas.
Cuando el Timer1 llega a  la cifra 15624, genera una interrupción y se pone a cero el contador volviendo a contar otra vez.
Este numero se saca de la siguiente forma:
 Frecuencia del procesador 16Mhz dividido por el prescaler puesto a 1024 nos da una frecuencia de 15625, y a esta cifra le debemos restar 1, con lo cual nos da la el numero 15624.
ISR(TIMER1_COMPA_vect)
{
  bandera=1;
  segundos++;
  if(segundos>59)
    {
     segundos=0;
     minutos++;
     if(minutos>59)
         {
          minutos=0;
          horas++;
            if(horas>23)
              {              
               segundos=0;
               minutos=0;
               horas=0;
              }
         }
    }    
}

Código de la interrupción que realiza la cuenta de segundo, minutos y horas.


Esquema del circuito.


Montaje del circuito.


Visualización de la página web.

// SETA43
// Modificacion 5-01-2012
//servidor web_ficheros


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


#include <LiquidCrystal.h>
LiquidCrystal lcd(18, 19, 14, 15, 16, 17);

char horas,minutos,segundos;
char bandera=1;
char VARI[30]="0";

//numero de MAC
//numero de ip, depende de tu red
byte mac[] = {   0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
IPAddress ip(192,168,2, 177);

EthernetClient client;


static char valor[10];
float ftempe;
float sensor1;
float sensor2;

byte LedPin=8; //Led

OneWire ds(2); // pin utilizado para el bus Onewire

// Inicializa la libreria  Ethernet 
// Selecciona el puerto 80, por defecto HTTP):
EthernetServer server(80);

void setup() 
{
  pinMode(18, OUTPUT);
  pinMode(19, OUTPUT);
  pinMode(14, OUTPUT);
  pinMode(15, OUTPUT);
  pinMode(16, OUTPUT);
  pinMode(17, OUTPUT);  
  lcd.begin(16, 2);
  
  pinMode(LedPin, OUTPUT); //Led
  
  pinMode(4, OUTPUT);    // Declaramos el pin ChipSelect como salida
  Serial.begin(9600);
  Serial.println("Servidor WEB almacenada en SD");
  Serial.println("Iniciando tarjeta SD");    // Texto informativo
  if(!SD.begin(4))
    {  
    Serial.println("Tarjeta erronea o no insertada");
    return;
    }
  Serial.println("Tarjeta OK");    // Texto informativo

  Ethernet.begin(mac, ip);
  server.begin();
  Serial.print("Servidor en ");
  Serial.println(Ethernet.localIP());
  
  pinMode(6, INPUT);
  pinMode(7, INPUT);
  
  cli();
  TCCR1A=0;
  TCCR1B=0;
  OCR1A=15624;
  TCCR1B |= (1<<WGM12);
  TCCR1B |= (1<<CS10);
  TCCR1B |= (1<<CS12);
  TIMSK1=(1<<OCIE1A);
  sei();  
}

ISR(TIMER1_COMPA_vect)
{
  bandera=1;
  segundos++;
  if(segundos>59)
    {
     segundos=0;
     minutos++;
     if(minutos>59)
         {
          minutos=0;
          horas++;
            if(horas>23)
              {               
               segundos=0;
               minutos=0;
               horas=0;
              }
         } 
    }     
}

void loop() 
{
  if(segundos==5  || segundos==30 )
    {
     LeerSensores(); 
     Serial.println(VARI);    
     lcd.setCursor(0, 1);
     lcd.print("A-");
     lcd.print(sensor1);
     lcd.print(" B-");
     lcd.print(sensor2);
     lcd.print("  ");     
    }
    
if(bandera)
    {
     bandera=0;
     sprintf(VARI,"%02d:%02d:%02d",horas,minutos,segundos); 
     lcd.setCursor(0, 0);
     lcd.print(VARI); 
     digitalWrite(LedPin, !digitalRead(LedPin)); 
    }    

if(!digitalRead(7))
       {
         minutos++;
         segundos=0;
         if(minutos==60)minutos=0;
         bandera=1;
         while(!digitalRead(7));
       }
   if(!digitalRead(6))
       {
        horas++;
        if(horas==24)horas=0;
        bandera=1;
        while(!digitalRead(6));
       }    
    
  client = server.available();
  if (client) {
    Serial.println("new client");

    boolean currentLineIsBlank = true;
    while (client.connected()) {
      if (client.available()) {
        char c = client.read();
        Serial.write(c);
        
        if (c == '\n' && currentLineIsBlank) {
          client.println("HTTP/1.1 200 OK");
          client.println("Content-Type: text/html");
          client.println("Connnection: close");
          client.println();
          client.println("<!DOCTYPE HTML>");
          client.println("<html>");
 
          client.println("<hr>");
          client.print("<h4>Temperatura en Palencia</h4>"); 
          client.print("<table border=\"1\">");
          client.print("<tr><td>Sensor1<br>Exterior</td><td >Sensor2<br>Interior</td></tr>"); 
          client.print("<tr>");        
          client.print("<td><h1><font color=\"#cc0000\">");
          client.print(sensor1); 
          client.println("&ordm;C");
          client.print("</font></h1></td>"); 
          client.print("<td><h1><font color=\"#cc0000\">");
          client.print(sensor2); 
          client.println("&ordm;C");
          client.print("</font></h1></td>");
          client.print("</tr>");
          client.print("</table>");
          client.println("Hora Arduino ");
          client.println(VARI); 
          client.println("<hr>"); 
          LeerSD();            
          client.println("</html>");
          break;
        }
        if (c == '\n') currentLineIsBlank = true;
          else if (c != '\r')  currentLineIsBlank = false;
      }
    }
    delay(1);
    client.stop();
    Serial.println("client disonnected");
  }
}



int LeerSD()
{ 
 File midataFile;
  midataFile=SD.open("html.txt", FILE_READ); 
  if(midataFile)
   {    
     while (midataFile.available())
       {
        client.write(midataFile.read());
       }      
     midataFile.close(); 
   }
    else
   {
    Serial.println("Error read SD ");   
   }
}

int LeerSensores()
{
         getTemp(1);
         sensor1=ftempe;
         getTemp(1);
         sensor2=ftempe; 
         getTemp(0);
         Serial.print(sensor1);
         Serial.print(","); 
         Serial.print(sensor2);
         Serial.println(" "); 
}

int getTemp(char x)
{

byte data[12];
byte addr[8];
char i;
byte MSB;
byte LSB;

  if ( x==0 || !ds.search(addr)) 
    {
      ds.reset_search();
      return 0;
    }

  if ( OneWire::crc8( addr, 7) != addr[7])
    {
      Serial.println("CRC is not valid!");
      return -1;
    }

  if ( addr[0] != 0x10 && addr[0] != 0x28)
    {
      Serial.print("Device is not recognized");
      return -1;
    }

  ds.reset();
  ds.select(addr);
  ds.write(0x44,1); // start conversion, with parasite power on at the end
  delay(1000);  // espera para que carge la tension el IC

  byte present = ds.reset();
  ds.select(addr);
  ds.write(0xBE); // Read Scratchpad

  for ( i = 0; i < 9; i++) data[i] = ds.read();

    MSB = data[1];
    LSB = data[0];

   float tempRead = ((MSB << 8) | LSB); //using two's compliment
   ftempe = tempRead / 2;
  return 1;
}
Programa del arduino.

Comento que la mezcla de las interrupciones con algunas librerías me ha vuelto loco, creo que se debe a que algunas librerías utilizan interrupciones por lo cual algunas veces se solapan. En cualquier caso tal como está escrito el programa funciona bien.
He de señalar que el consumo total del circuito es de 169mA, y he notado que el chip de red se calienta algo.
Otra de las cosas que me sorprendió, es que después de estar sin alimentación el circuito, debo realizar un reset para que funcione el servidor web. Mi teoría es que el tiempo en que se alimenta y se hace el auto reset no es suficiente para todos los chip, se podría solucionar colocando un condensador de mas valor en el reset.

Un saludo.
JUAN GALAZ

Bibliografía:
    http://en.wikipedia.org/wiki/1-Wire .
    tallerarduino.wordpress.com David Alvarez Medina
    http://bildr.org/2011/07/ds18b20-arduino/
    http://owfs.org/index.php?page=ds18s20
    http://www.bairesrobotics.com/2012/08/ansi-c-arduino-parte-3-timers-interrupts/
    http://tallerarduino.wordpress.com/2012/03/15/arduino-tutorials-cap-5-interrupciones-internas/
    http://www.pjrc.com/teensy/td_libs_LiquidCrystal.html