Temperature and Humidity Datalogger + Webserver

 by javacasm
dht11.png
2011-10-28 00.20.46_peque.jpg
In this instructable (my first instructable) we will create a temperature and humidity datalogger adding the posibility to access the data by web.

The new arduino ethernet makes everything sooooooo easy that it looks like magic. In the same board you get: an ATMega 328, ethernet conectivity, sd card

Only need a RTC (Real Time Clock) in order to have a full datalogger. I will plan to make another instructable about how to conect a RTC to this board.

You can connect to my own arduino server in order to see my server room temperature.
 
Remove these adsRemove these ads by Signing Up

Step 1: The basic stuff

dht11.png

Lets me show how easy is to make a datalogger that saves sensor data in a SD card and allow remote access by web using any browser.

We will use three DHT11 sensor as source of data. Every DHT11 give us temperature and humidity data. They are really cheap (2€ iin ebay) and more or less acurrate ;-) : 2 Celsius degree and 5% of humidity. In the case you want more acurrate data, the DHT22 could be your election.

I apologize for using Celsius degrees. That is because I radicate in Spain. Changing the units to Fahrenheit degrees it is really easy.
mmo6 says: Dec 14, 2012. 7:54 AM
is there a way that file savings are made to different files and max size ~1M?
javacasm (author) says: Dec 14, 2012. 7:34 AM
I'm it almost worked. The delay could be due to some config or hardwareissues. Please, check the ip and the ethernet wire.
mmo6 says: Dec 14, 2012. 5:25 AM
thnx now its working:) i added to the end some sd card lines , now its saving data to sd card but web browsing is very very slow or noting at all.. , where should i put some delay s for that browser can makes connections in time ?




// close the connection:
client.stop();
}
else

{
//if(nFiles>=0 && file)
{
file= SD.open("datalog.txt", FILE_WRITE);
}
String data="";
for(int i=0;i
}


if(file)
{
file.println(data);
Serial.println(data);
file.close();
nFilas++;
}
delay(1000);

for(int i=0;i getdataDHT(i);
delay(1000);
getdataOneWire();
}
}
javacasm (author) says: Dec 8, 2012. 7:32 AM
I'll try to reproduce again the circuit and test again the code.
This is the code I'm using now in a bit more complex project. You can remove the OneWire part
I hope this helps

#include <SPI.h>
#include <Ethernet.h>
#include <OneWire.h>
#include <dht11.h>  // Descargamos la librería desde http://arduino-info.wikispaces.com/DHT11-Humidity-TempSensor

dht11 DHT11; 
#define nSensoresDHT 6
#define nSensoresOneWire 3
int puertosDHT[]={2,3,5,6,7,8}; // ¿Por qué nos saltamos el 4?
int puertoOneWire=9;
OneWire  ds(puertoOneWire); 

float fHumedades[nSensoresDHT];
float fTemperaturas[nSensoresDHT+nSensoresOneWire];

int iNVisitas=0;

// Enter a MAC address and IP address for your controller below.
// The IP address will be dependent on your local network:
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xEE, 0xEE };
byte ip[] = { 192,168,1, 177 };

// Initialize the Ethernet server library
// with the IP address and port you want to use
// (port 80 is default for HTTP):
EthernetServer server(666);
void setup()
{
  // start the Ethernet connection and the server:
  Ethernet.begin(mac, ip);
  server.begin();

  Serial.begin(115200);


}
float tMin=100;
float tMax=0;
float tMedia=0;
int contador=0;
void getdataOneWire()
{
  byte i;
  byte present = 0;
  byte type_s;
  byte data[12];
  byte addr[8];
  float celsius;
 
  if ( !ds.search(addr)) {
    Serial.print(contador);
    Serial.println(" DS18x20 encontrados");
    Serial.print("Tmax=");
    Serial.print(tMax);
    Serial.print(" Tmin=");
    Serial.print(tMin);
    Serial.print(" tmedia=");
    Serial.println( tMedia/contador);
    ds.reset_search();
    contador=0;
    tMedia=0;
    delay(250);
    return;
  }

  Serial.print("ROM =");
  for( i = 0; i < 8; i++) {
   
    if(addr[i]<16)
      Serial.print(" 0");
    else
      Serial.write(' ');
    Serial.print(addr[i], HEX);
  }

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

  // the first ROM byte indicates which chip
  switch (addr[0]) {
    case 0x10:
      Serial.print(" DS18S20");  // or old DS1820
      type_s = 1;
      break;
    case 0x28:
      Serial.print(" DS18B20");
      type_s = 0;
      break;
    case 0x22:
      Serial.print(" DS1822");
      type_s = 0;
      break;
    default:
      Serial.print("Not a DS18x20");
      return;
  }

  ds.reset();
  ds.select(addr);
  ds.write(0x44,1);         // start conversion, with parasite power on at the end
 
  delay(1000);     // maybe 750ms is enough, maybe not
  // we might do a ds.depower() here, but the reset will take care of it.
 
  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();

  }


  // convert the data to actual temperature

  unsigned int raw = (data[1] << 8) | data[0];
  if (type_s) {
    raw = raw << 3; // 9 bit resolution default
    if (data[7] == 0x10) {
      // count remain gives full 12 bit resolution
      raw = (raw & 0xFFF0) + 12 - data[6];
    }
  } else {
    byte cfg = (data[4] & 0x60);
    if (cfg == 0x00) raw = raw << 3;  // 9 bit resolution, 93.75 ms
    else if (cfg == 0x20) raw = raw << 2; // 10 bit res, 187.5 ms
    else if (cfg == 0x40) raw = raw << 1; // 11 bit res, 375 ms
    // default is 12 bit resolution, 750 ms conversion time
  }
  celsius = (float)raw / 16.0;
  fTemperaturas[nSensoresDHT+contador]=celsius;
  if(tMin>celsius)
    tMin=celsius;
  if(tMax<celsius)
    tMax=celsius;
  tMedia+=celsius;
  Serial.print("  Temp.= ");
  Serial.print(celsius);
  Serial.println("C");
  contador++;
}


void getdataDHT(int iIndice)
{
  int chk = DHT11.read(puertosDHT[iIndice]);
  fHumedades[iIndice]=-1;
  fTemperaturas[iIndice]=-1;

  Serial.print("Sensor ");
  Serial.print(iIndice);
  Serial.print(" ");
  switch (chk)
  {
    case 0:
      fHumedades[iIndice]=(float)DHT11.humidity;
      Serial.print(fHumedades[iIndice], 2);
      Serial.print(" % ");
      fTemperaturas[iIndice]=(float)DHT11.temperature;
      Serial.print(fTemperaturas[iIndice], 2);
      Serial.println(" o C");
        break;
    case -1: Serial.println(" Checksum error"); break;
    case -2: Serial.println(" Time out error"); break;
    default: Serial.println(" Unknown error"); break;
  }

}

void loop()
{
  // listen for incoming clients
  EthernetClient client = server.available();
  String sURL;
  if (client) {
    // an http request ends with a blank line
    boolean currentLineIsBlank = true;
    while (client.connected()) {
      if (client.available()) {

        char c = client.read();
        // if you've gotten to the end of the line (received a newline
        // character) and the line is blank, the http request has ended,
        // so you can send a reply
        if (c == '\n' && currentLineIsBlank) {
          sURL=sURL.substring(0,9);
          Serial.println(sURL);
          if(sURL.endsWith("csv "))
          {
            for(int i=0;i<nSensoresDHT;i++){
              client.print(fHumedades[i], 2);
              client.print(";");
              client.print(fTemperaturas[i], 2);
              client.print(";");

            }
            for(int i=0;i<nSensoresOneWire;i++){
              client.print(fTemperaturas[nSensoresDHT+i]);             
              client.print(";");
            }
            client.println("");      
          }
          else
          {
            // send a standard http response header
            client.println("HTTP/1.1 200 OK");
            client.println("Content-Type: text/html");
            client.println();
            // client.println("<meta http-equiv=\"refresh\" content=\"1\" />"); //Autorefresh de la página
            // output the value of each analog input pin
            for(int i=0;i<nSensoresDHT;i++){
              client.print("sensorDHT ");
              client.print(i);
              client.print(": ");
              if(fHumedades[i]==-1)
                client.print(" error leyendo el sensor");
              else
              {
                client.print(fHumedades[i], 2);
                client.print(" % ");
                client.print(fTemperaturas[i], 2);
                client.println(" C");
              }
              client.println("<br />");
            }
            for(int i=0;i<nSensoresOneWire;i++){
              client.print("sensorOneWire ");
              client.print(i);
              client.print(": ");
              client.print(fTemperaturas[nSensoresDHT+i]);
              client.println(" C<br />");
            }         
            client.print((iNVisitas++)/2);
            client.println(" visitas <br />");
          }
          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
          sURL+=c;
          currentLineIsBlank = false;

        }
      }
    }
    // give the web browser time to receive the data
    delay(1);
    // close the connection:
    client.stop();
  }
  else
  {
    for(int i=0;i<nSensoresDHT;i++)
      getdataDHT(i);
    delay(100);
    getdataOneWire();
  }
}

mmo6 says: Dec 7, 2012. 5:49 AM
its ok now in program , no errors but there is no readings from sensors
sensor 0: error leyendo el sensor
sensor 1: error leyendo el sensor
sensor 2: error leyendo el sensor

i think there are much more differences between old and new versions
mmo6 says: Dec 6, 2012. 10:15 AM
i am using newer version yes. there are some other things that must be changed like "Server" is now "EthernetServer" and Client is EthernetClient, but i cant understand what is wrong with this "puertos={2,3,4}; "
javacasm (author) in reply to mmo6Dec 6, 2012. 2:34 PM
I don't know why doesn't work in 1.0 IDE

You can fix it changing the declaration of puertos with this one

int puertos[]={2,3,4};

I hope this helps
mmo6 says: Dec 6, 2012. 7:10 AM
hi
can you say why does line
puertos={2,3,4};
give me an error?
expected primary expression before { token
javacasm (author) in reply to mmo6Dec 6, 2012. 8:29 AM
Which arduino version are you using?
Maybe my code need a revision for arduino 1.0
jabujavi says: Oct 18, 2012. 6:31 AM
Gracias tio! me ha venido de lujo.
No serás forococheros verdad? te encontrarias un monton de cosas en la plataforma...
saraca_92 says: Sep 27, 2012. 8:25 AM
i like it.
so nice.
i can try =)
javacasm (author) says: Nov 14, 2011. 10:52 PM
The code can be downloaded from my blog 
Computothought says: Nov 3, 2011. 6:39 AM
When I put up some asm, my includes were lost also. You may want to include the source code as a download.
Screenshot-0d.png
javacasm (author) in reply to ComputothoughtNov 14, 2011. 9:31 PM
Thanks a lot for your info.

I'll check it
Pro

Get More Out of Instructables

Already have an Account?

close

PDF Downloads
As a Pro member, you will gain access to download any Instructable in the PDF format. You also have the ability to customize your PDF download.

Upgrade to Pro today!