Wednesday, February 13, 2013

Reading Temperature and Humidity on AVR Atmega using DHT11 or DHT22/AM2302 library

Updated to version 03

The DHT11/22 are a basic, low-cost digital temperature and humidity sensors. They uses a capacitive humidity sensor and a thermistor to measure the surrounding
air, and spits out a digital signal on the data pin (no analog input pins needed). Compared to the DHT11, DHT22 is more precise, more accurate and works in a bigger
range of temperature/humidity.


This library use DHT11/22 sensor to read temperature and humidity on Atmega micro.
Setup the data port connected to the micro pin in file dht.h
This library was developed on Eclipse, built with avr-gcc on Atmega8 @ 1MHz.


DHT11
  • Power supply 3.5/5.5V DC
  • Measuring range Humidity: 20/90 %RH
  • Measuring range Temperature: 0/50 Celsius.

DHT22
  • Power supply 3.5/5.5V DC
  • Measuring range Humidity: 0/100 %RH
  • Measuring range Temperature: -40/80 Celsius.

Changelog
  • 03: prevent blocking if something goes wrong
  • 02: first release

Code

Notes
  • read risk disclaimer
  • excuse my bad english

112 comments:

  1. DHT22 has a temperature range of -40~80 (according to the datasheet), not -40~125.

    ReplyDelete
    Replies
    1. Thanks for your feedback, it was my copy and paste mistake. Now is correct.

      Delete
  2. i need schema this project,, and what dht11 like dht22,, thank.s very much your answers

    ReplyDelete
  3. Excellent! Thank you Davide.

    Peter, USA

    ReplyDelete
  4. Hello!
    I need the results will be show on LCD. Could you tell me what should I change on your library?

    ReplyDelete
    Replies
    1. You need to add an lcd driver, which will depends on the lcd you chose, for example if you chose a HD44780 base, you will find a lot of library, like the Fleury one. Then you have to transform values you get from this library to ascii value using dtostrf, sprintf, or ltoa for example. Then you can output value to your LCD. Talking about LCD, take a look to AVR Freaks, it's a good starting point.

      Delete
    2. Could I send to you my code to check (I'm begginer)

      Delete
    3. Hello, i'm sorry but actually i'm involved in a project... what i can do is point you to a solution, but you have to code it out.. that's the fun part also ;)
      If you are really a beginner, Arduino could be easier for you to enter electronics. Arduino framework is much more easier than writing plain avrgcc code.

      Delete
    4. Ok, thank You. Sht works, but I have question: is this code works with minus temperature for dht22 sensor?

      Delete
    5. It should, never tryed it but it should, let me know. :)

      Delete
    6. Hi again! I try, code works with minus temperature for dht22 sensor :)

      Delete
  5. Hey I need code for interfacing dht11 with atmega32...........I have connected port B with LCD (PB0-PB3 for data pins of LCD , PB4 for enable signal , PD3 for RS and PD6 for RW) and PD0 and PD1 for RX and TX of GSM modem............so how can I do it..........thanks in advance

    ReplyDelete
    Replies
    1. You have to change the port depending on the microcontroller you use. Check the datasheet of the microcontroller.
      Also setup this library to work on DHT11, look at the header file attached to the code.

      Delete
  6. Hi, I am using your library with atmega 324PA and dht11 to print the data on LCD. I have working LCD, but I can't get the program to put the data on it. I changed the ports and sensor type in header file and checked the wiring, so this should not be a problem. What else do I need to change to get things work?
    Thanks in advance

    ReplyDelete
    Replies
    1. Check that your hardware (dht11), works on other microcontroller. Check if and where the code stop working.
      If you have a logic analizer, check the comunication bus, if not, simply use uart to debug your code.
      In a first stage i should use uart to debug the code.

      Delete
    2. This comment has been removed by a blog administrator.

      Delete
  7. Thansk for really fast answer! The hardware is OK, checked on arduino and worked fine. I am quite a beginner, so I am not so good in debugging, but when I go step by step, it gets stuck in _delay_loop_1(delay_basic.h).

    ReplyDelete
    Replies
    1. There is any _delay_loop_1, and delay_basic direct call in my code. It is called by the _delay_ms and _delay_us. Compile your code with avrgcc. Checked you ATmega fuses, and your ATmega F_CPU. Also try to investigate where and if in the dht library the code stops.

      Delete
  8. Hello, I tried the dht library code on atmega8 @ 1MZ internal RC, but only get "error" printed out. Any ideas? It is a DHT22 from adafruit.

    ReplyDelete
    Replies
    1. If you are using the place code provided as example here, "error" means dht_gettemperaturehumidity return -1, so it can get any data from the DHT22.
      That code was written and checked using avrgcc as compiler.
      There are a few think you could do: check that your hardware is properly wired, check that your DHT22 works on other microcontroller, try on arduino as example. debug your bus from micro to sensor with a logic analyzer, or use a simpler uart method for debugging, just put some output to your uart to expose to you preferred serial terminal the content of registers on the sensor. In a few words, check where is the "error", and try to fix it :)

      Delete
    2. There is a wide variation in the DHT22 level timings, as reported also by others. For instance, my sensor aware signal is 180us instead of the advertised 20-40us. Therefore, I modified your code to WAIT for the sensor aware high level rather than DELAY 40us and test the level. This works fine for my sensor. Apart from this glitch, grazie mille for publishing your code :)

      Delete
    3. Well done!
      Also thanks for your feedback, it may be usefull for other users.

      Delete
  9. Hey can someone please provide me the code for measuring the temperature from dht22 through atmega16 and display it on lcd using Davide Gironi's lib provided above on this page. Please if somebody can help me, send me the code on my email id, as I can't seem to get it working, Please help
    Thanks in advance

    ReplyDelete
    Replies
    1. Could you try to do some effort first so that someone can point you in the right direction? what have you tried and did not work? any error? did you even had a time reading through the code and try understanding what could be the problem in your case?

      Delete
  10. This comment has been removed by a blog administrator.

    ReplyDelete
  11. Works with atmega 32 adnd DHT 11. Thanks

    ReplyDelete
    Replies
    1. Hey artineo, can you please send me the code for the working of atmega32 with dht11, my email id is nkhlvjy@gmail.com. Thanks in advance

      Delete
  12. Hello! I write my own c code to read DHT11 sensor. I realize the timing diagrams and create functions for decoding logical levels. Could you please tell me the order of the bytes? My intention is to save each bits coming trough the dataline to 5pcs of arrays and then read only humidity datas and put on LCD. I'd need to know which 8bits come first after i've triggered the sensor. If you have any doubt of my idea please tell me. Cheers: Balázs

    ReplyDelete
    Replies
    1. Hello, you can found the byte order in the dht_getdata function in file dht.c

      Delete
    2. What's worng with my code? I get -1 shown on my LCD instead of actual humidity value.
      http://pastebin.com/kL7ty79f

      Delete
    3. It could be a timing problem. Double check your FCU. Check that you have properly set fuse for your 3.6864 crystal. Also check the code using the internal 1Mhz crystal.

      Delete
    4. I tested it in ISIS first, but now it is running on my MCU. So it works fine thanks for you help and congrats for your source code.

      Delete
    5. Good! Thanks for that feedback.

      Delete
  13. Hi davide, I have written a code for the Thermo hygro series of sensors. The problem after using the ATMEGA 32 is that the code is working in DHT 11 but it is nto working in the DHT 22. I see the timing diagrams are the same for the communication. Not able to figure out where the problem seems to be. Could you elaborate on the exact difference in the way the bits are read.

    ReplyDelete
    Replies
    1. Hello, you can find the difference in the code source. Look at the DHT_TYPE and DHT_FLOAT definition.

      Delete
    2. Oh thanks a lot Mr Gironi. Had overlooked that one :)

      Delete
    3. Hey Sujith, can you please send me the code for the working of atmega32 with dht11, my email id is nkhlvjy@gmail.com. Thanks in advance

      Delete
  14. hello Davide, i am going to display the real time tempr and humidity value in lcd . To do this, how can i pass the parameter in main function to call the function :
    "int8_t dht_getdata(int8_t *temperature, int8_t *humidity) " to get the sensor values.. please give me some hint..

    ReplyDelete
    Replies
    1. Hello, there are many way to solve your problem, it's depend on how you would act.
      You can simply get temperature and humidy, and then display it using you lcdprint function.
      int8_t temperature = 0;
      int8_t humidity = 0;
      if(dht_gettemperaturehumidity(&temperature, &humidity) != -1) {
      itoa(temperature, printbuff, 10);
      lcd_puts(printbuff);
      itoa(humidity, printbuff, 10);
      lcd_puts(printbuff);
      }

      Delete
  15. thank you Davide.. Its working... yeah...:D thank u so much..

    ReplyDelete
    Replies
    1. thanks for your help and quick response... its working 100%.. but one question.."Is the decimal part of both temp and humidity always zero??" i got the decimal part always constant ( i.e. 0 ) in LCD..

      Delete
    2. itoa is the integer to string conversion function.
      to convert from double to string you should use dtostrf.
      So it will be
      double temperature = 0;
      double humidity = 0;
      ...
      dtostrf(temperature, 3, 3, printbuff);
      ...
      dtostrf(humidity, 3, 3, printbuff);
      ...

      Delete
  16. I have problem with DHT11/Atmega32 .(
    my code:

    char printbuff[10];
    int8_t temperature = 0;
    int8_t humidity = 0;
    if(dht_gettemperaturehumidity(&temperature, &humidity) != -1) {
    itoa(temperature, printbuff, 10);
    lcd_clrscr();
    lcd_gotoxy(1, 2); //znak,radek
    lcd_puts(printbuff);
    itoa(humidity, printbuff, 10);
    lcd_puts(printbuff);
    }
    I changed only:

    //setup port
    #define DHT_DDR DDRD
    #define DHT_PORT PORTD
    #define DHT_PIN PIND
    #define DHT_INPUTPIN PD7

    //sensor type
    #define DHT_DHT11 1
    //#define DHT_DHT22 2
    //#define DHT_TYPE DHT_DHT22

    LCD show temp and humidity = 0

    ReplyDelete
    Replies
    1. Hello,
      Anyway double check your wiring, also check your fuse. Check that the sensor works with other hardware. At a first step, use the sample mail file and output to uart, That way you will be shure if it is the LCD library or the DHT one that does not work.

      Delete
    2. I tried it with uart.... Atmega still send error..
      I changed only this part of code : (dht.h)

      //sensor type
      #define DHT_DHT11 1
      //#define DHT_DHT22 2
      #define DHT_TYPE DHT_DHT11 //there was DHT22

      fuses:
      BOOTSZ0
      BOOTSZ1
      EESAVE
      CKOPT
      SPIEN
      JTAGEN
      => PROGRAMMED (0), other UNPROGRAMMED (1)

      I have Atmega32P ...I hope "P" is not a problem...

      Delete
    3. Thanks for quick reply!!

      Its OK!

      Problem was in F_CPU. I forgot include .h file with defined F_CPU...and other libraries set default wrong F_CPU..

      Delete
  17. This comment has been removed by the author.

    ReplyDelete
  18. Hello Davide,
    i'm a beginer in AVR project,
    Can you tell me what must i do with this library ?
    I wat to make a project to display temperature and humidity in lcd using DHT11 and Atmega8
    Please help me Davide...

    ReplyDelete
    Replies
    1. Hello, you have to compile this library with avrgcc. You can found a lot of tutorial on how to compile avrgcc. Then you have to find an lcd library. First make a uart library work, because you will need it for simple debugging. Then, test the DHT11 library, then test the LCD library. When you have got all tested, make a single project with the DHT11 and LCD library togheter. If you are really a beginnner, consider to take a look at the Arduino project. it is farily simple then avrgcc compile, and it comes with a great community forum, and many libraries.

      Delete
    2. Thank you David for your fast respon, but i'm sorry David i make the project using code vision avr and there is an error with the library when i try to compile. Can i stay use the cvavr compiler with some change of te library ?

      Delete
    3. I do not use code vision, so i does not know which change you have to do in order to make this code compile.

      Delete
  19. How could I use your source code to implement DHT 11 to display on JX 128 ? Regards,

    ReplyDelete
    Replies
    1. Hello, I suppose you mean the JX-Mega128 board. If so, you have to compile this code for ATmega128, then you could use this code.

      Delete
    2. Thanks for your fast response, I got a problem about your header files. There are errors if "DHD_DDR undeclared", "undefined reference to uart_init" and etc. I spend plenty of time to solve this but it won't work
      How to solve this ?

      PS I use avr studio4
      Regards,
      Mix

      Delete
    3. It's sounds like a compiler problem to me, it seems you haven't added the header files to you complier environment. Check that.

      Delete
  20. hello Davide, I have problem with DHT11/Atmega32
    my code

    int main(void)
    {
    char printbuff[100];

    lcd_init(LCD_DISP_ON); // initialize LCD


    //init interrupt
    sei();

    int8_t temperature = 0;
    int8_t humidity = 0;

    for (;;)
    {
    humidity = dht11_gethumidity();
    temperature = dht11_gettemperature();
    lcd_puts("temperature: ");
    itoa(temperature, printbuff, 10);

    lcd_puts(printbuff);
    lcd_puts("C");
    lcd_puts("\r\n");
    lcd_puts("humidity: ");
    itoa(humidity, printbuff, 10);
    lcd_puts(printbuff);
    lcd_puts("%");
    lcd_puts("\r\n");

    //lcd_puts("\r\n");

    _delay_ms(1500);
    }

    return 0;
    }

    it display -1 values for temperature and humidity. Please help me Davide...thanks..

    ReplyDelete
    Replies
    1. Hello, doublecheck your wiring. Check your fuse, most of the time it's a timing iussue. If you have a logic analyzer you can see what's happen on the ATmega to DHT11 bus.

      Delete
  21. Hello! and thanks for your tutorial! Im actually using ATmega8 and atmel studio 7. when i build the firmware it shows this kind of error: attempt to use poisoned "SIG_UART_RECV"

    Someone know what its mean?

    Thanks

    ReplyDelete
    Replies
    1. Hello, and thank you for your feedback.
      It's an error from the usart lib. You are using an out of date interrupt name, see you compiler documentation for the updated register name (as example, for avr-libc you can look here: http://www.nongnu.org/avr-libc/user-manual/group__avr__interrupts.html)
      Note: this project it is written and tested using avrgcc and the Eclipse AVR plugin.

      Delete
  22. This comment has been removed by the author.

    ReplyDelete
  23. Hello Davide!
    Thanks for your contribution.
    And I need a big help from you.
    I want to save the temperature and humidity results on a text document.How can i do this, I am using Atmega32A MCU.
    Please help me!!

    ReplyDelete
    Replies
    1. Hello, thank you for your feedback. Do you mean save to a text document using a SD card, or save to a text document using the ATmega32 connected to a PC?

      Delete
    2. Thanks for your quick response.
      Yes, we need to save temperature and humidity readings on to SD card embedded in a raspberyPI.
      Thanks agin!

      Delete
    3. You can just output data to uart, and then read it back with the serial port of the Raspberry, you just need to setup a small serial protocol. A simple one could be just sending temperature and humidity in ASCII forma. Each line splitted by a comma (,) and terminated by a Line Feed (\10).
      dtostrf could be your friend here for humidity and temperature to ascii convertion. Or event the sprintf function.

      Delete
    4. Thank you david.
      Could you show me an example code for this purpose.
      If it possible,it will be a great favour for me..

      Delete
    5. Hello, on ATmega side, something like this should do the work: http://pastebin.com/T5BA0n1e
      I let you write the Raspberry code by you, it shouldn't be so difficult, you have just to read until "end of line" character, then split by ";" to an array on array[0] you get temperatur, on array[1] humidity.

      Delete
  24. what this library can be use in code vision AVR or C language?

    ReplyDelete
    Replies
    1. Hello, this library is developed and tested with avrgcc. You have to port it in order to make it works on the CodeVision AVR compiler.

      Delete
  25. This comment has been removed by the author.

    ReplyDelete
    Replies
    1. This comment has been removed by the author.

      Delete
  26. I'm getting error I read the comments but I didn't understand What should I do , please help me I tried the code with atmega16 and DHT11 I get either error or zero values for both temp and humidity, please help me I can't understand where the problem comes from :( I'm trying this code for 5 days for now !

    ReplyDelete
    Replies
    1. Hello, my suggestion is to use a logic analizer to debug the DATA cable, just look at it, see if it matches the DHT11 datasheet protocol.

      Delete
  27. can i use this code with ATmega32????

    ReplyDelete
    Replies
    1. Hello, it should work. "vladan vesý" write a comment above there. He said he works on ATmega32.

      Delete
  28. thanks to reply....


    but how to show text on disply 16*2 ??

    what i do changing in code?

    ReplyDelete
    Replies
    1. If you are using the sample code here, you have to change the uart_puts in the main.c file, with your LCD library output functions. You can find a good LCD library on the Peter Fleury AVR-Software web page.

      Delete
  29. #include
    #include
    #define F_CPU 1000000
    #include
    #include

    #define enable 5
    #define registerselection 6

    void send_a_command(unsigned char command);
    void send_a_character(unsigned char character);
    void send_a_string(char *string_of_characters);


    int main(void)
    {
    DDRB = 0xFF;
    DDRD = 0b11111011;
    _delay_ms(50);

    GICR|=(1< 0)
    {
    send_a_character(*string_of_characters++);
    }
    }


    ReplyDelete
  30. thanks for your suport...
    above is my full coding of ultrasonic sensor .

    and sir i have to interface the sensor(dht11/22) this sensor is interface in portA i have to include the code of sensor in above
    program

    ReplyDelete
    Replies
    1. Hello, I do not know about your sensor library, or your uart (send_ library), so this may not work, anyway, try something like this http://pastebin.com/rzujVpRn (expires in 2 weeks),debug it if it does not works. Also remember to include libmath (-lm ) to your linker.

      Delete
  31. thank u very much sir, u modify code is ok... but i debugging in avr studio only one error is occurs that "dht/dht.h no such file or directory" . i am trying add "dht22.h" . so, how to add this file? and which particular file to add in library?

    ReplyDelete
    Replies
    1. In AVRStudio, you just have to add that files to your project and change the path in my source accoring to the file path. There are a few good tutorial on AVR Studio. They will teach you how to do this in step.

      Delete
  32. Ciao Davide, come stai?
    I need some help from you. I've tested your library on ATmega32 with DHT11 sensor and it works very well. However when I plugged in the DHT22 it did not. I've changed in the code to:
    #define DHT_TYPE DHT_DHT22
    Am I suppose to change something else? I receive only some strange numbers on my LCD.

    ReplyDelete
    Replies
    1. Hello. I'm fine thanks. It should works just changing that macro as you are doing there. I'm using this on other ATmega and DHT11 without problem (ex. http://davidegironi.blogspot.it/2015/08/amqumo-xively-ambient-quality-monitor.html). You also have to change you input variables, with DHT22 you should use float. You could also try cleaning and recompiling your project. Check it with avr-gcc as compiler. Check it with other DHT22 sensor.

      Delete
  33. can you please give me the code to interface dht11 with atmega32 and 16x2 lcd display

    ReplyDelete
    Replies
    1. Hello, according to "artineo March 6, 2015 at 5:02 PM" this works with ATmega32, anyway I've never tryied it. As 16x2 LCD library you can use the Peter Fleury one, it works great. Please do not write twice the same comment.

      Delete
    2. This comment has been removed by the author.

      Delete
    3. sorry to say this but its not complete yet
      its giving two erors
      Error 1 undefined reference to `dht11_gethumidity'
      Error 2 undefined reference to `dht11_gettemperature'
      i have already added the libraries for dht11 and uart
      please tell me what to do

      Delete
    4. It may be that you are not compiling the dht11 library. Check that your avrgcc is compiling this, and that your linker is linking that. Using the Eclipse + AVR plugin get things simpler, the most of the time you just have to add code to your project, then the AVR plugin does the compiling job.

      Delete
  34. Hello, Davide!

    My project: mega8, dht22, 7seg-indicator.

    To display the humidity, it is necessary to assign the variable "display". In the code "display = dht_humidity();" Eclipse says that "implicit declaration of function 'dht_humidity'". What data should be put in brackets?

    Thanks a lot!

    Oleg

    ReplyDelete
    Replies
    1. Hello, you have to include the dht library header. So '#include "dht/dht.h'"

      Delete
    2. Thanks for answer!

      Already did. It did not help.

      Could you give an example of the appeal to this library? The DHT22 sensor.

      Thanks!

      Delete
  35. Hi

    i just want to display integer part. I don't want decimal. What should i do ? i want to display only integer part in 7 segment.

    ReplyDelete
    Replies
    1. Hello, you could set DHT_FLOAT to 0, then set int8_t temperature and int8_t humidity variables. Run dht_gettemperaturehumidity(&temperature, &humidity), then use the itoa function to load a char buffer with the int value, something like itoa(temperature, tempprintbuff, 10) and itoa(humidity, tempeprintbuff, 10).

      Delete
  36. This comment has been removed by the author.

    ReplyDelete
  37. Replies
    1. Hello, I'm sorry but I've only got this avrgcc version.

      Delete
  38. Hello Davide,
    I'm Working on ATmega16 and DHT22. WHILE RUNNING YOUR MAIN CODE on AVR studio 4, I'm getting this error.(../JSG_DHT.c:61: fatal error: opening dependency file dep/JSG_DHT.o.d: No such file or directory)
    Please help me to solve this !!

    ReplyDelete
    Replies
    1. Hello, make sure you have linked all the library you have to compile. Also give it a try to the Eclipse + AVR plugin and avrgcc compiler, which is simpler to use than the AVR Studio to me.

      Delete
    2. Thanx for your Reply !!
      Problem solved.

      Delete
  39. Hi Sir,
    I'm a beginner, Need your help !!
    My Code:
    #include
    #define F_CPU 8000000UL
    #include
    #include

    #include"lcd.c"
    #include"dht.c"

    int main(void)
    {
    char printbuff[100];

    lcd_init(); // initialize LCD
    DDRD = 0xff;
    sei();

    int8_t temperature = 0;
    int8_t humidity = 0;

    while(1)
    {
    humidity = dht_getdata(temperature, &humidity);;
    temperature = dht_getdata(&temperature, humidity);;
    lcd_string("temperature: ");
    itoa(temperature, printbuff, 10);
    lcd_string(printbuff);
    lcd_string("C");
    lcd_string("\r\n");
    lcd_string("humidity: ");
    itoa(humidity, printbuff, 10);
    lcd_string(printbuff);
    lcd_string("%");
    lcd_string("\r\n");
    _delay_ms(1500);
    }

    return 0;

    no output

    ReplyDelete
    Replies
    1. Hello, please do not post code here, use pastepin instead. Then, about your problem. At fisrt start to check your lcd library and lcd output. Then mix this with the DHT. To me, the first error could be the header #include #define F_CPU 8000000UL #include #include #include"lcd.c" #include"dht.c". You should your .h (lcd.h and dht.h) files, not the .c. Then, if you are a begineer a good place to start is the avrfreaks forum, here you will find a lot of help, much more than just me replying as my time allow me to do. In addition, you could try the Arduino IDE, which is fairly simple than writing plain avrgcc code.

      Delete
  40. i was very confused for some days but now i have solved it and its working...if anyone wants the full coding of dht11 and atmega32 leave your email adress i will send you the complete working code and the corresponding simulations


    ReplyDelete