sábado, 29 de diciembre de 2012

Arduino Registrador de temperatura en SD DS18S20

Página principal


Arduino
Registrador de temperatura en SD
DS18S20

xsetaseta@gmail.com


Este montaje utiliza la tarjeta Arduino Ethernet Shieldb como lectora de tarjetas micro SD para almacenar la temperatura de dos sensores DS18S20 colocados en un cable de dos hilos utilizando la librería OneWire.
Lo primero recomiendo leer varios tutoriales sobre el funcionamiento del sistema de comunicaciones OneWire, http://en.wikipedia.org/wiki/1-Wire .
También es fundamental ver la descripción del DS18S20, un medidor de temperaturas desde -55ºC a +125ºC y con un margen de +\- 0,5ºC.
Si queremos más resolución  podemos emplear los registros COUNT REMAIN y  COUNT PER °C, pero en este montaje no se va emplear. Si alguno desea saber como hacerlo, recomiendo la lectura del manual del CI, no es difícil su realización.
Este integrado posee la cualidad de poder alimentarse desde la propia línea de datos al poseer un condensador interno. Esto nos posibilita el poder utilizar un simple cable de dos hilos. Además podemos colocar varios DS18S20 a lo largo del cable para de esta forma poder medir diferentes temperaturas.

Esquema del circuito.


Circuito montado y funcionando.
 Los datos se almacenan en la SD y se mandan a través del puerto serie.
Como vemos en la imagen hemos colocado un led a modo de piloto para indicar si funciona la microSD y cuando podemos extraer la tarjeta microSD. Este led se coloca junto con una resistencia en serie de 1k al pin 3 del arduino.


Sonda exterior colocada en la calle mediante un cable de dos hilos.
Si queremos dejarla fija, deberiamos sellarla con silicona para impedir que se moje.


Vemos mediante la consola la temperatura de los dos sensores.
He colocado un contador para seguir cada serie de lecturas.



El programa crea un fichero de texto TEMPE.TXT donde se registra la temperatura de los distintos sensores.
Las lecturas en la SD se van acumulando.
Para conseguir temperaturas negativas he tenido que meter la sonda al frigorífico.



// Programa hecho por JUAN GALAZ
//29/12/2012
//con ideas de David Alvarez Medina para tallerarduino.wordpress.com
//y manejo de 18s20 de http://bildr.org/2011/07/ds18b20-arduino/
// Pagina sobre OneWire http://owfs.org/index.php?page=ds18s20

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


File dataFile;
String temperatura;
static char valor[10];
int contador=0;
int espera=1;

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

void setup()
{
  Serial.begin(9600); // Establecemos comunicacion serie
  Serial.println("Lectura de sensores cada 10seg. y almacenar en SD");
  Serial.println("Iniciando tarjeta SD"); // Texto informativo
  pinMode(3, OUTPUT); //piloto para sacar la SD
  
  pinMode(4, OUTPUT); // Declaramos el pin ChipSelect como salida
  if(!SD.begin(4)){ // Si no hay tarjeta o esta mal...
    Serial.println("Tarjeta erronea o no insertada"); // Texto informativo
    return;
  }
  Serial.println("Tarjeta OK"); // Texto informativo
}

void loop()
{
  digitalWrite(3, LOW);
  dataFile=SD.open("tempe.txt", FILE_WRITE); // Creamos archivo de texto
  if(dataFile)
   { 
    if(contador==0)
      {
        dataFile.println("Inicio lecturas");
        contador++;
      }
        
    if(0==getTemp())
      {
        dataFile.print(contador);
        Serial.print(contador);
        dataFile.println(",");
        Serial.println(" , Fin de sensores");
        espera=8000;
        contador++;
      }
      else
      {       
       dataFile.print(temperatura);
       dataFile.print(",");
       Serial.print(temperatura);
       Serial.print(", ");
       espera=1;   
      }
    dataFile.close(); // Cerramos la escritura dentro del archivo
   }
   else
   {
    Serial.println("Error write SD ");
   }
   
  digitalWrite(3, HIGH);
  delay(espera); // Espera entre lecturas
}


int getTemp()
{

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

  if ( !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++)
      { // we need 9 bytes
        data[i] = ds.read();
      }

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

    temperatura="";
i=LSB>>1;
    if(MSB & 128)
      {
       temperatura=temperatura + "-";
i=128-i;
      }
      else
      {
        temperatura=temperatura + "+";
      }    
    
    sprintf(valor, "%i", i);
    temperatura=temperatura+valor;
    
    if(LSB & 1)
        temperatura=temperatura + ".5";
      else
        temperatura=temperatura + ".0";
 
  return 1;
}


Programa del arduino.
Como se puede observar el código para determinar la temperatura es un tanto particular, es debido a que no quiero utilizar float.


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

miércoles, 19 de diciembre de 2012

Arduino-red-webserver 6 entradas analógicas y 7 salidas digitales.

Página principal


Arduino-red-webserver
6 entradas analógicas y 7 salidas digitales.

xsetaseta@gmail.com

Este segundo montaje con la tarjeta de red para arduino, tiene como finalidad controlar 7 salidas digitales y 6 entradas analógicas.
La tarjeta Arduino Ethernet Shield se puede encontrar en el mercado entre 9€ y 25€ depende del suministrador.
Para mas detalles visitar la página oficial http://www.arduino.cc/en/Main/ArduinoEthernetShield.
La comunicación con el chip W5100 y con la tarjeta SD se hace a través del bus SPI.
La activación del chip de red se efectúa con el pin 10 del arduino, y la activación tarjeta SD se realiza con el pin 4.
He realizado dos programas, el primero es más fácil de comprender. El segundo esta optimizado para ocupar menos memoria, se intenta reducir lo mas posible la repetición de funciones iguales. El resultado es 1k menos de memoria, pero menos comprensible su estudio.
Si se quiere controlar desde fuera de tu red interna, debes de modificar en el router los el direccionamiento del puerto, para que si tu arduino  tiene la dirección 192,168,2, 177  y con el puerto 80, las peticiones al puerto 80 se dirijan a la dirección  IP del arduino.


Controlando el encendido de led mediante una tableta android.


Visualización del control de circuito en un navegador.


// SETA43
// Modificacion 19-12-2012
// webserver

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

//numero de MAC
//numero de ip, depende de tu red

byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
IPAddress ip(192,168,2, 177);

String readString = String(20);
byte bandera=0;
byte z;
char c;
int sensorReading;

EthernetServer server(80);

void setup() {
  Serial.begin(9600);
   while (!Serial) {  }

  Ethernet.begin(mac, ip);
  server.begin();
  Serial.print("server is at ");
  Serial.println(Ethernet.localIP());
  
  pinMode(2,OUTPUT);
  pinMode(3,OUTPUT);
  pinMode(5,OUTPUT);
  pinMode(6,OUTPUT);
  pinMode(7,OUTPUT);
  pinMode(8,OUTPUT);
  pinMode(9,OUTPUT);  
}

void loop() {
  // listen for incoming clients
  EthernetClient client = server.available();
  if (client) {
    Serial.println("new client");

    boolean currentLineIsBlank = true;
    while (client.connected()) {
      if (client.available()) {
        c = client.read();
        Serial.write(c);
        if(c=='?' && bandera==0)
          {
           readString="";
           for(z=0;z<14;z++)  
             {
               c = client.read();
               readString +=c;
             }
           Serial.println(readString);
           colocar();
           bandera=1;
          }
                      
        if (c == '\n' && currentLineIsBlank) {

          // Manda la cabecera del http
          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>");
          // Refresca cada 3 segundos
          client.println("<meta http-equiv=\"refresh\" content=\"3\">");
          client.println("<big><b>Seta43_Arduino</b></big><br>");
          client.print("xsetaseta@gmail.com <br>");
          client.print("Control de LEDS <br>");
          client.println("<hr>");

          client.print("<form method=get><input type=submit name=valor value=Encender_Todos>");
          client.println("<input type=submit  name=valor value=Apagar_todos></form>");    
          client.println("<hr>");             
          client.print("<form method=get><input type=submit name=valor value=1DIG2>");
          client.println("<input type=submit  name=valor value=0DIG2> DIG2=");
          client.println(digitalRead(2));
          client.println("</form>");
          client.print("<form method=get><input type=submit name=valor value=1DIG3>");
          client.println("<input type=submit  name=valor value=0DIG3> DIG3=");
          client.println(digitalRead(3));
          client.println("</form>");
          client.print("<form method=get><input type=submit name=valor value=1DIG5>");
          client.println("<input type=submit  name=valor value=0DIG5> DIG5=");
          client.println(digitalRead(5));
          client.println("</form>");   
          client.print("<form method=get><input type=submit name=valor value=1DIG6>");
          client.println("<input type=submit  name=valor value=0DIG6> DIG6=");
          client.println(digitalRead(6));
          client.println("</form>");   
          client.print("<form method=get><input type=submit name=valor value=1DIG7>");
          client.println("<input type=submit  name=valor value=0DIG7> DIG7=");
          client.println(digitalRead(7));
          client.println("</form>");    
          client.print("<form method=get><input type=submit name=valor value=1DIG8>");
          client.println("<input type=submit  name=valor value=0DIG8> DIG8=");
          client.println(digitalRead(8));
          client.println("</form>");    
          client.print("<form method=get><input type=submit name=valor value=1DIG9>");
          client.println("<input type=submit  name=valor value=0DIG9> DIG9=");
          client.println(digitalRead(9));
          client.println("</form>");            
          client.println("<hr>");   
                    
          for ( z = 0; z < 6; z++) {
            sensorReading = analogRead(z);                     
            client.print("Analog input ");            
            client.print("<font color=red>");
            client.print(z);
            client.print("</font>");            
            client.print(" is ");            
            client.print("<font color=blue>");   
            client.print(sensorReading);
            client.print("</font>");            
            client.println("<br />");       
          }
          
           client.println("<hr>");          
          
          client.println("</html>");
          break;
         }
        if (c == '\n') {
          // you're starting a new line
          currentLineIsBlank = true;
          }
        else if (c != '\r') {
          // you've gotten a character on the current line
          currentLineIsBlank = false;
          }
      }
    }
    // give the web browser time to receive the data
    delay(1);
    // close the connection:
    client.stop();
    Serial.println("client disonnected");
            
  }
     bandera=0;  
}


void colocar()
{         
    if(readString.indexOf("1DIG2") >0){ digitalWrite(2, HIGH); goto salir;}
    if(readString.indexOf("0DIG2") >0){ digitalWrite(2, LOW); goto salir;}
    
    if(readString.indexOf("1DIG3") >0){ digitalWrite(3, HIGH);goto salir;}
    if(readString.indexOf("0DIG3") >0){ digitalWrite(3, LOW);goto salir;}
  
    if(readString.indexOf("1DIG5") >0){ digitalWrite(5, HIGH);goto salir;}
    if(readString.indexOf("0DIG5") >0){ digitalWrite(5, LOW);goto salir;}
    
    if(readString.indexOf("1DIG6") >0){ digitalWrite(6, HIGH);goto salir;}
    if(readString.indexOf("0DIG6") >0){ digitalWrite(6, LOW);goto salir;}
    
    if(readString.indexOf("1DIG7") >0){ digitalWrite(7, HIGH);goto salir;}
    if(readString.indexOf("0DIG7") >0){ digitalWrite(7, LOW);goto salir;}
    
    if(readString.indexOf("1DIG8") >0){ digitalWrite(8, HIGH);goto salir;}
    if(readString.indexOf("0DIG8") >0){ digitalWrite(8, LOW);goto salir;}
    
    if(readString.indexOf("1DIG9") >0){ digitalWrite(9, HIGH);goto salir;}
    if(readString.indexOf("0DIG9") >0){ digitalWrite(9, LOW);goto salir;}
    
    if(readString.indexOf("Encende") >0){ encender(); goto salir;}
    if(readString.indexOf("Apagar") >0){ apagar();goto salir;}
salir:
;
}


void encender()
{
  digitalWrite(2, HIGH); digitalWrite(3, HIGH); digitalWrite(5, HIGH);digitalWrite(6, HIGH);
  digitalWrite(7, HIGH);digitalWrite(8, HIGH);digitalWrite(9, HIGH);
}

void apagar()
{
  digitalWrite(2, LOW);digitalWrite(3, LOW);digitalWrite(5, LOW);digitalWrite(6, LOW);
  digitalWrite(7, LOW);digitalWrite(8, LOW);digitalWrite(9, LOW);
}
Programa sin optimizar.


// SETA43
// Modificacion 19-12-2012
//webserver v2mini

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

//numero de MAC
//numero de ip, depende de tu red

byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
IPAddress ip(192,168,2, 177);


String readString = String(20);
byte bandera=0;
byte z;
char c;
int sensorReading;
EthernetClient client;

const byte PinOut[] = { 2, 3, 5, 6, 7, 8, 9};


EthernetServer server(80);

void setup() {
  Serial.begin(9600);
   while (!Serial) {  }

  Ethernet.begin(mac, ip);
  server.begin();
  Serial.print("server is at ");
  Serial.println(Ethernet.localIP());
  for(z=0;z<7;z++) pinMode(PinOut[z],OUTPUT);
}

void loop() {
  client = server.available();
  if (client) {
    Serial.println("new client");

    boolean currentLineIsBlank = true;
    while (client.connected()) {
      if (client.available()) {
        c = client.read();
        Serial.write(c);
        if(c=='?' && bandera==0)
          {
           readString="";
           for(z=0;z<14;z++)  
             {
               c = client.read();
               readString +=c;
             }
           Serial.println(readString);
           colocar();
           bandera=1;
          }
               
        if (c == '\n' && currentLineIsBlank) {

          // Manda la cabecera del http
          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>");
          // Refresca cada 3 segundos
          client.println("<meta http-equiv=\"refresh\" content=\"3\">");
          client.println("<big><b>Seta43_Arduino</b></big><br>");
          client.print("xsetaseta@gmail.com <br>");
          client.print("Control 6 salidas digitales y 6 entradas analogicas <br>");
          client.println("<hr>");

          FormSubmit();  client.print("Encender_Todos>");
          PrintSubmit();    client.println("Apagar_todos></form>");    
          client.println("<hr>");
                 
         for(z=0;z<7;z++)
                        {
                        FormSubmit();  client.print("1DIG");
                        client.print(PinOut[z]);  client.print(">");
                        PrintSubmit();  client.print("0DIG");
                        client.print(PinOut[z]); client.print(">");
                        client.print(" DIG");client.print(PinOut[z]); client.print("=");
                        client.print(digitalRead(PinOut[z]));
                        PrintForm();
                        }

          client.println("<hr>");   
                    
          for ( z = 0; z < 6; z++)
                        {
                        sensorReading = analogRead(z);                     
                        client.print("Analog input ");            
                        client.print("<font color=red>");
                        client.print(z);
                        client.print("</font>");            
                        client.print(" is ");            
                        client.print("<font color=blue>");   
                        client.print(sensorReading);
                        client.print("</font>");            
                        client.println("<br />");       
                        }  
           
          client.println("<hr>");                   
          client.println("</html>");
          break;
         }
        if (c == '\n')       currentLineIsBlank = true;
            else
              if (c != '\r')  currentLineIsBlank = false;
      }
    }
    delay(1);
    client.stop();
    Serial.println("client disonnected");            
  }
  bandera=0;  
}


void FormSubmit()
{
 PrintFormIn();
 PrintSubmit();
}

void PrintSubmit()
{
 client.print("<input type=submit  name=valor value=");  
}

void PrintFormIn()
{
  client.print("<form method=get>");
}  

void PrintForm()
{
  client.println("</form>");
}

void colocar()
{         
    if(readString.indexOf("1DIG2") >0){ digitalWrite(2, HIGH); goto salir;}
    if(readString.indexOf("0DIG2") >0){ digitalWrite(2, LOW); goto salir;}
    
    if(readString.indexOf("1DIG3") >0){ digitalWrite(3, HIGH);goto salir;}
    if(readString.indexOf("0DIG3") >0){ digitalWrite(3, LOW);goto salir;}
  
    if(readString.indexOf("1DIG5") >0){ digitalWrite(5, HIGH);goto salir;}
    if(readString.indexOf("0DIG5") >0){ digitalWrite(5, LOW);goto salir;}
    
    if(readString.indexOf("1DIG6") >0){ digitalWrite(6, HIGH);goto salir;}
    if(readString.indexOf("0DIG6") >0){ digitalWrite(6, LOW);goto salir;}
    
    if(readString.indexOf("1DIG7") >0){ digitalWrite(7, HIGH);goto salir;}
    if(readString.indexOf("0DIG7") >0){ digitalWrite(7, LOW);goto salir;}
    
    if(readString.indexOf("1DIG8") >0){ digitalWrite(8, HIGH);goto salir;}
    if(readString.indexOf("0DIG8") >0){ digitalWrite(8, LOW);goto salir;}
    
    if(readString.indexOf("1DIG9") >0){ digitalWrite(9, HIGH);goto salir;}
    if(readString.indexOf("0DIG9") >0){ digitalWrite(9, LOW);goto salir;}
    
    if(readString.indexOf("Encende") >0){ for(z=0;z<7;z++) digitalWrite(PinOut[z],HIGH);  goto salir; }
    if(readString.indexOf("Apagar") >0) { for(z=0;z<7;z++) digitalWrite(PinOut[z],LOW);   goto salir; }
salir:
;
}


Programa optimizado.


Saludos
Juan Galaz


Bibliografía:

Libro: Arduino Cookbook
http://unicarlos.com/pezazul/index.php?articulo=4
http://blogdoje.com.br/2010/04/11/teste-do-shield-ethernet-seeeduino/
http://www.scienceprog.com/getting-hands-on-arduino-ethernet-shield/
http://rickymoga.blogspot.com.es/search/label/ARDUINO
https://docs.google.com/document/d/1VR8dHVNQ6LbWGyyi4mTJv6mF8QK7xVD_lj4r6pWevZc/edit?pli=1
http://pepechorva.com/wordPress/domotica/
http://www.htmlquick.com/es/reference/tags/input.html#hidden