DHT11 + LCD weather station

Hello, I am quite new to whole electronics and I have been given an assignment in school to do a project with arduino. I selected DHT11 sensor because it was cheap and reliable as I read on the Internet. I have no trouble with getting readings from DHT11 to Arduino software alone or hooking up LCD and displaying something on it. Trouble comes in when I try to display DHT11 readings on the LCD and get readings to computer at the same time. I´m sure this has been done before but I could not find anything on the Internet. Maybe someone of you could try and help me out a little bit?

Martin

Maybe someone of you could try and help me out a little bit?

Sure. Which way did you some in?

Seriously, you need to give us something more to go on than "Trouble comes in when I try to display DHT11 readings on the LCD and get readings to computer at the same time.". Something like what the trouble is would be extremely helpful.

Some code that causes the trouble will be necessary, too.

display DHT11 readings on the LCD and get readings to computer at the same time

How is the computer connected to the Arduino?
What software captures the data from Arduino?

If it is the serial monitor of the IDE a statement like Serial.println(reading); in the right place should be enough

BTW there are many DHT 11 sketches on this forum, you can search for them in the upper right corner but be patient as it is not that fast.

Hello and thank you for your fast replies.

I am using arduino uno board, potentiometer, lcd display and arduino connects to pc through usb port. For DHT11 readings I am using this code:

// 
//   FILE:  dht11_test1.pde
// PURPOSE: DHT11 library test sketch for Arduino
//

//Celsius to Fahrenheit conversion
double Fahrenheit(double celsius)
{
	return 1.8 * celsius + 32;
}

//Celsius to Kelvin conversion
double Kelvin(double celsius)
{
	return celsius + 273.15;
}

// dewPoint function NOAA
// reference: http://wahiduddin.net/calc/density_algorithms.htm 
double dewPoint(double celsius, double humidity)
{
	double A0= 373.15/(273.15 + celsius);
	double SUM = -7.90298 * (A0-1);
	SUM += 5.02808 * log10(A0);
	SUM += -1.3816e-7 * (pow(10, (11.344*(1-1/A0)))-1) ;
	SUM += 8.1328e-3 * (pow(10,(-3.49149*(A0-1)))-1) ;
	SUM += log10(1013.246);
	double VP = pow(10, SUM-3) * humidity;
	double T = log(VP/0.61078);   // temp var
	return (241.88 * T) / (17.558-T);
}

// delta max = 0.6544 wrt dewPoint()
// 5x faster than dewPoint()
// reference: http://en.wikipedia.org/wiki/Dew_point
double dewPointFast(double celsius, double humidity)
{
	double a = 17.271;
	double b = 237.7;
	double temp = (a * celsius) / (b + celsius) + log(humidity/100);
	double Td = (b * temp) / (a - temp);
	return Td;
}


#include <dht11.h>

dht11 DHT11;

#define DHT11PIN 8

void setup()
{
  Serial.begin(9600);
  Serial.println("DHT11 TEST PROGRAM ");
  Serial.print("LIBRARY VERSION: ");
  Serial.println(DHT11LIB_VERSION);
  Serial.println();
}

void loop()
{
  Serial.println("\n");

  int chk = DHT11.read(DHT11PIN);

  Serial.print("Read sensor: ");
  switch (chk)
  {
    case 0: Serial.println("OK"); break;
    case -1: Serial.println("Checksum error"); break;
    case -2: Serial.println("Time out error"); break;
    default: Serial.println("Unknown error"); break;
  }

  Serial.print("Humidity (%): ");
  Serial.println((float)DHT11.humidity, 2);

  Serial.print("Temperature (oC): ");
  Serial.println((float)DHT11.temperature, 2);

  Serial.print("Temperature (oF): ");
  Serial.println(Fahrenheit(DHT11.temperature), 2);

  Serial.print("Temperature (K): ");
  Serial.println(Kelvin(DHT11.temperature), 2);

  Serial.print("Dew Point (oC): ");
  Serial.println(dewPoint(DHT11.temperature, DHT11.humidity));

  Serial.print("Dew PointFast (oC): ");
  Serial.println(dewPointFast(DHT11.temperature, DHT11.humidity));

  delay(20000);
}
//
// END OF FILE
//

I have also wired up the default (at least the default that is in the examples of Arduino software to connect the LCD to arduino, which is:

/*
  LiquidCrystal Library - scrollDisplayLeft() and scrollDisplayRight()
 
 Demonstrates the use a 16x2 LCD display.  The LiquidCrystal
 library works with all LCD displays that are compatible with the 
 Hitachi HD44780 driver. There are many of them out there, and you
 can usually tell them by the 16-pin interface.
 
 This sketch prints "Hello World!" to the LCD and uses the
 scrollDisplayLeft() and scrollDisplayRight() methods to scroll
 the text.
 
  The circuit:
 * LCD RS pin to digital pin 12
 * LCD Enable pin to digital pin 11
 * LCD D4 pin to digital pin 5
 * LCD D5 pin to digital pin 4
 * LCD D6 pin to digital pin 3
 * LCD D7 pin to digital pin 2
 * LCD R/W pin to ground
 * 10K resistor:
 * ends to +5V and ground
 * wiper to LCD VO pin (pin 3)
 
 Library originally added 18 Apr 2008
 by David A. Mellis
 library modified 5 Jul 2009
 by Limor Fried (http://www.ladyada.net)
 example added 9 Jul 2009
 by Tom Igoe 
 modified 22 Nov 2010
 by Tom Igoe
 
 This example code is in the public domain.
 
 http://arduino.cc/en/Tutorial/LiquidCrystalScroll

 */

// include the library code:
#include <LiquidCrystal.h>

// initialize the library with the numbers of the interface pins
LiquidCrystal lcd(12, 11, 5, 4, 3, 2);

void setup() {
  // set up the LCD's number of columns and rows: 
  lcd.begin(16, 2);
  // Print a message to the LCD.
  lcd.print("hello, world!");
  delay(1000);
}

void loop() {
  // scroll 13 positions (string length) to the left 
  // to move it offscreen left:
  for (int positionCounter = 0; positionCounter < 13; positionCounter++) {
    // scroll one position left:
    lcd.scrollDisplayLeft(); 
    // wait a bit:
    delay(150);
  }

  // scroll 29 positions (string length + display length) to the right
  // to move it offscreen right:
  for (int positionCounter = 0; positionCounter < 29; positionCounter++) {
    // scroll one position right:
    lcd.scrollDisplayRight(); 
    // wait a bit:
    delay(150);
  }
  
    // scroll 16 positions (display length + string length) to the left
    // to move it back to center:
  for (int positionCounter = 0; positionCounter < 16; positionCounter++) {
    // scroll one position left:
    lcd.scrollDisplayLeft(); 
    // wait a bit:
    delay(150);
  }
  
  // delay at the end of the full loop:
  delay(1000);

}

And for getting DHT11 reading on LCD I used:

//ReadHumTturDHT11alternate2
//ver 19Jly10

//This is a re-written DHT11/ DHT22 reading code.
//DHT stuff in subroutines.

//See for more information....
//http://sheepdogguides.som/arduino/ar3ne1humDHT11.htm

//N.B. "bit" is used in the narrow, computer "1 or 0"
//   sense throughout.

//"DHT" from sensor's names: DHT11, DHT22.
//DHT aka Aosong AM2302, and there's an AM2303 which
//seems to be in the same family.

//Comments on this based on Aosong AM2302, aka DHT22, datasheet.
//Believed to generally apply to DHT11 as well, except in the
//case of the DHT11, I believe the second and fourth bytes are
//always zero.

//***N.B.****
//The code WORKS... the comments may not yet be EXACTLY right.
//See the web-page cited above for latest news.

//This code works with a DHT11 humidity/ temperature sensing module
//from nuelectronics.com, complied with ver 0018 of the Arduino environment
//Sensor attached to P4 (nuelectonics shield)/ analog 0, aka digital 14.

//That "module", according to the
//nuelectronics site, and visual inspection simply provides for easy
//connection of an Aosong DHT11 unit to the nuelectronics datalogging
//shield. Only 3 wires are involved: Vcc, ground, and a single data
//line. One of the DHT11's 4 pins goes nowhere.

//You should not need to change anything except the next line to use
//the software with the sensor on a different line, or for a DHT22.

//Just "huffing" on the sensor from deeply filled lungs should show
//a near instant rise in humidity

//#define dht_PIN 0      //no ; here. deprecate ADC0...
//even though we are using it as a digital pin.
//Other parts of code restrict us to using
//ADC0-5, aka D14-19
#define dht_dpin 14 //no ; here. Set equal to channel sensor is on,
//where if dht_dpin is 14, sensor is on digital line 14, aka analog 0

#define LIGHT_SENSOR_PIN 1
// include the library code:
#include <LiquidCrystal.h>

// initialize the library with the numbers of the interface pins
LiquidCrystal lcd(0, 1, 2, 3, 4, 5);

byte bGlobalErr; //for passing error code back from complex functions.
byte dht_dat[4]; //Array to hold the bytes sent from sensor.
int light_intensity = 0;
unsigned int flip = 0;

void setup(){
        //Blink LED to detect hangs
        pinMode(13, OUTPUT);
        // set up the LCD's number of columns and rows:
        lcd.begin(16, 2);
        lcd.print("hello, world!");
        InitDHT(); //Do what's necessary to prepare for reading DHT
        //Serial.begin(9600);
        delay(300); //Let system settle
        //Serial.println("Humidity and temperature\n\n");
        delay(700); //Wait rest of 1000ms recommended delay before
        //accessing sensor
} //end "setup()"

void loop(){
        // set the cursor to column 0, line 1
        // (note: line 1 is the second row, since counting begins with 0):
        //lcd.setCursor(0, 1);
        // print the number of seconds since reset:
        //lcd.print("100");
        //lcd.print(millis()/1000);
        if ( flip & 1 )
        {
                digitalWrite(13, HIGH);
        } else {
                digitalWrite(13, LOW);
        }
       flip++;

        light_intensity=analogRead(LIGHT_SENSOR_PIN);

        ReadDHT(); //This is the "heart" of the program.
        //Fills global array dht_dpin[], and bGlobalErr, which
        //will hold zero if ReadDHT went okay.
        //Must call InitDHT once (in "setup()" is usual) before
        //calling ReadDHT.
        //Following: Display what was seen...
        switch (bGlobalErr) {
        case 0:
                lcd.setCursor(0, 0);
                // Serial.print("humdity = ");
                lcd.print("temp =       ");
                lcd.setCursor(7, 0);
                lcd.print( dht_dat[2], DEC);

                //Serial.print(dht_dat[0], DEC);
                //Serial.print(".");
                //Serial.print(dht_dat[1], DEC);
                //Serial.print("%  ");
                lcd.setCursor(0, 1);
                //Every 7 out of 15 times we show humidity, rest temp
                if ((flip % 15) > 7 )
                {
                        lcd.print("humidity = ");
                        lcd.setCursor(11, 1);
                        lcd.print( dht_dat[0], DEC);
                } else {
                        lcd.print("Light =         ");
                        lcd.setCursor(8, 1);
                        lcd.print( light_intensity, DEC);
                }
                //Serial.print("temperature = ");
                //Serial.print(dht_dat[2], DEC);
                //Serial.print(".");
                //Serial.print(dht_dat[3], DEC);
                //Serial.println("C  ");
                break;
        case 1:
                //Serial.println("Error 1: DHT start condition 1 not met.");
                break;
        case 2:
                //Serial.println("Error 2: DHT start condition 2 not met.");
                break;
        case 3:
                //Serial.println("Error 3: DHT checksum error.");
                break;
        default:
                //Serial.println("Error: Unrecognized code encountered.");
                break;
        } //end "switch"
        delay(800); //Don't try to access too frequently... in theory
        //should be once per two seconds, fastest,
        //but seems to work after 0.8 second.

} // end loop()

/*Below here: Only "black box" elements which can just be plugged unchanged
   unchanged into programs. Provide InitDHT() and ReadDHT(), and a function
   one of them uses.*/

void InitDHT(){
        //DDRC |= _BV(dht_PIN);//set data pin... for now... as output
        //DDRC is data direction register for pins A0-5 are on
        //PORTC |= _BV(dht_PIN);//Set line high
        //PORTC relates to the pins A0-5 are on.
        //Alternative code...
//        if (dht_dpin-14 != dht_PIN){Serial.println("ERROR- dht_dpin must be 14 more than dht_PIN");};//end InitDHT
        pinMode(dht_dpin,OUTPUT); // replaces DDRC... as long as dht_dpin=14->19
        digitalWrite(dht_dpin,HIGH); //Replaces PORTC |= if dht_pin=14->19
} //end InitDHT

void ReadDHT(){
/*Uses global variables dht_dat[0-4], and bGlobalErr to pass
   "answer" back. bGlobalErr=0 if read went okay.
   Depends on global dht_PIN for where to look for sensor.*/
        bGlobalErr=0;
        byte dht_in;
        byte i;
        // Send "start read and report" command to sensor....
        // First: pull-down i/o pin for 18ms
        digitalWrite(dht_dpin,LOW); //Was: PORTC &= ~_BV(dht_PIN);
        delay(18);
        delayMicroseconds(600);//TKB, frm Quine at Arduino forum
/*aosong.com datasheet for DHT22 says pin should be low at least
   500us. I infer it can be low longer without any]
   penalty apart from making "read sensor" process take
   longer. */
//Next line: Brings line high again,
//   second step in giving "start read..." command
        digitalWrite(dht_dpin,HIGH); //Was: PORTC |= _BV(dht_PIN);
        delayMicroseconds(40); //DHT22 datasheet says host should
        //keep line high 20-40us, then watch for sensor taking line
        //low. That low should last 80us. Acknowledges "start read
        //and report" command.

//Next: Change Arduino pin to an input, to
//watch for the 80us low explained a moment ago.
        pinMode(dht_dpin,INPUT); //Was: DDRC &= ~_BV(dht_PIN);
        delayMicroseconds(40);

        dht_in=digitalRead(dht_dpin); //Was: dht_in = PINC & _BV(dht_PIN);

        if(dht_in) {
                bGlobalErr=1; //Was: Serial.println("dht11 start condition 1 not met");
                return;
        } //end "if..."
        delayMicroseconds(80);

        dht_in=digitalRead(dht_dpin); //Was: dht_in = PINC & _BV(dht_PIN);

        if(!dht_in) {
                bGlobalErr=2; //Was: Serial.println("dht11 start condition 2 not met");
                return;
        } //end "if..."

/*After 80us low, the line should be taken high for 80us by the
   sensor. The low following that high is the start of the first
   bit of the forty to come. The routine "read_dht_dat()"
   expects to be called with the system already into this low.*/
        delayMicroseconds(70);
//now ready for data reception... pick up the 5 bytes coming from
//   the sensor
        for (i=0; i<5; i++)
                dht_dat[i] = read_dht_dat();

//Next: restore pin to output duties
        pinMode(dht_dpin,OUTPUT); //Was: DDRC |= _BV(dht_PIN);
//N.B.: Using DDRC put restrictions on value of dht_pin

//Next: Make data line high again, as output from Arduino
        digitalWrite(dht_dpin,HIGH); //Was: PORTC |= _BV(dht_PIN);
//N.B.: Using PORTC put restrictions on value of dht_pin

//Next see if data received consistent with checksum received
        byte dht_check_sum =
                dht_dat[0]+dht_dat[1]+dht_dat[2]+dht_dat[3];
/*Condition in following "if" says "if fifth byte from sensor
       not the same as the sum of the first four..."*/
        if(dht_dat[4]!= dht_check_sum)
        {bGlobalErr=3; } //Was: Serial.println("DHT11 checksum error");
}; //end ReadDHT()

byte read_dht_dat(){
//Collect 8 bits from datastream, return them interpreted
//as a byte. I.e. if 0000.0101 is sent, return decimal 5.

//Code expects the system to have recently entered the
//dataline low condition at the start of every data bit's
//transmission BEFORE this function is called.

        byte i = 0;
        byte result=0;
        for(i=0; i< 8; i++) {
                //We enter this during the first start bit (low for 50uS) of the byte
                //Next: wait until pin goes high
                while(digitalRead(dht_dpin)==LOW) ;  //Was: while(!(PINC & _BV(dht_PIN)));
                //signalling end of start of bit's transmission.

                //Dataline will now stay high for 27 or 70 uS, depending on
                //whether a 0 or a 1 is being sent, respectively.
                delayMicroseconds(30); //AFTER pin is high, wait further period, to be
                //into the part of the timing diagram where a 0 or a 1 denotes
                //the datum being send. The "further period" was 30uS in the software
                //that this has been created from. I believe that a higher number
                //(45?) would be more appropriate.

                //Next: Wait while pin still high
                if (digitalRead(dht_dpin)==HIGH) //Was: if(PINC & _BV(dht_PIN))
                        result |=(1<<(7-i));  // "add" (not just addition) the 1
                //to the growing byte
                //Next wait until pin goes low again, which signals the START
                //of the NEXT bit's transmission.
                while (digitalRead(dht_dpin)==HIGH) ;  //Was: while((PINC & _BV(dht_PIN)));
        } //end of "for.."
        return result;
} //end of "read_dht_dat()"

... and they all work, but I would love to be able to use the last script but get the readings on the arduino software port monitor as well so I could have data readings saved all throught night.. I have never been programming or anything alike, but I do enjoy the wiring part and making something myself.. Thanks alot to everyone who want to help me.

Martin

please please please use the # button when posting code, it provides tags to present the code in a better readable format.

  • you can modify old posts easily, select the code part and press the # button just above the smileys :slight_smile:

Thank you..

Noted with thanks, I did not know that :slight_smile:

thanks,

sometimes code contains parts that resemble smileys like this one

if (x == 8)
{
bool b =( a & b );
}

if (x == 8) 
{
  bool b =( a & b );
}

Have you got any ideas how to merge pc data logging to this script?

Yes, but I do not know what you want.

YOu can use serial communication or ethernet or ... to send the data to the PC.
On the PC there are many applications to represent the data in a graph.

I propose you check out - www.processing.org - it works quite well together with Arduino. There are many examples to be found.

Just an output to arduino´s software port monitor would be enough for a start ...

The posted script has a number of commented out Serial.print() statements. Remove the '//' from the beginning of each, and from the Serial.begin().

First, your schematic generate your problem.

You connect LCD display pins to serial ports pins, which is O.K. if you dont use Serial communication at all. You need to free pins 0,1 moving that connection to some other digital pins.

Are you trying to use the code posted in replies #17 and #18? It has all the serial calls commented out.

Like this:

...
        //Serial.begin(9600);
...
                //Serial.print(dht_dat[0], DEC);
                //Serial.print(".");
                //Serial.print(dht_dat[1], DEC);
                //Serial.print("%  ");
...

You need to uncomment it, by removing the '//'s.

Thank you for helping I sorted the problem out, it was the uncommenting all along..

Hi guys.

I would like to display the weather in my city on an LCD using either google API or yahoo API.

At the moment I have an arduino uno, ethernet shield and an LCD.

Is it possible for this to be implemented without any addition sensors? Or if there is a better way of doing it can you please recommend?

Thanks for your time