Go Down

Topic: DHT11 + LCD weather station (Read 5731 times) previous topic - next topic

WiredMeUp

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

PaulS

Quote
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.

robtillaart

Quote
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.

Rob Tillaart

Nederlandse sectie - http://arduino.cc/forum/index.php/board,77.0.html -
(Please do not PM for private consultancy)

WiredMeUp

#3
May 27, 2012, 04:43 pm Last Edit: May 27, 2012, 05:08 pm by WiredMeUp Reason: 1
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:
Code: [Select]

//
//   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:

WiredMeUp

#4
May 27, 2012, 04:44 pm Last Edit: May 27, 2012, 05:07 pm by WiredMeUp Reason: 1
Code: [Select]

/*
 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);
       }


WiredMeUp

#5
May 27, 2012, 04:44 pm Last Edit: May 27, 2012, 05:07 pm by WiredMeUp Reason: 1
Code: [Select]

       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

robtillaart


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 :)

Thank you..
Rob Tillaart

Nederlandse sectie - http://arduino.cc/forum/index.php/board,77.0.html -
(Please do not PM for private consultancy)

WiredMeUp

Noted with thanks, I did not know that :)

robtillaart

thanks,

sometimes code contains parts that resemble smileys like this one   

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

Code: [Select]

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

Nederlandse sectie - http://arduino.cc/forum/index.php/board,77.0.html -
(Please do not PM for private consultancy)

WiredMeUp

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

robtillaart

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.
Rob Tillaart

Nederlandse sectie - http://arduino.cc/forum/index.php/board,77.0.html -
(Please do not PM for private consultancy)

WiredMeUp

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

dxw00d

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

SnJDK

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.


dxw00d

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

Like this:
Code: [Select]
...
        //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.

Go Up