The secret to brewing great beer at home is making sure that you keep it at the right temperature. This can be tricky when your house doesn’t have a thermostat and you’re not in the house for most of the day. However, by using a cheap and cheerful sensor with a raspberry pi, you can record a log of the temperature and check it over the internet to make sure your beer is brewing nicely.
Hardware
The sensor I used is the DHT11 which, at the time of writing, you can order on eBay for £1.12 delivered. It has a digital interface, so you don’t need to do any calibration or digital conversion as you would with a thermistor. To connect the sensor to the RPi, all you need is a 10k resistor to pull-up the data signal and to make the following connections (see pic).
RPi VCC (pin 1) -> DHT11 pin 1 RPi GPIO4 (pin 7) -> DHT11 pin 2 RPi GND (pin 6) -> DHT11 pin 4
Interfacing
The DHT11 uses its own serial interface, which can be interrogated using the wiringPi C library. To install and compile the library, use the following commands:
sudo apt-get install git-core build-essential git clone git://git.drogon.net/wiringPi cd wiringPi ./build
This blog post details the code necessary to read the sensor data. The code below has been modified to return only the current temperature and to repeat the request if there is an error. Place the following into a file named dht11.c
.
#include <wiringPi.h> #include <stdio.h> #include <stdlib.h> #include <stdint.h> #define MAX_TIME 85 #define DHT11PIN 7 #define ATTEMPTS 5 int dht11_val[5]={0,0,0,0,0}; int dht11_read_val() { uint8_t lststate=HIGH; uint8_t counter=0; uint8_t j=0,i; for(i=0;i<5;i++) dht11_val[i]=0; pinMode(DHT11PIN,OUTPUT); digitalWrite(DHT11PIN,LOW); delay(18); digitalWrite(DHT11PIN,HIGH); delayMicroseconds(40); pinMode(DHT11PIN,INPUT); for(i=0;i<MAX_TIME;i++) { counter=0; while(digitalRead(DHT11PIN)==lststate){ counter++; delayMicroseconds(1); if(counter==255) break; } lststate=digitalRead(DHT11PIN); if(counter==255) break; // top 3 transistions are ignored if((i>=4)&&(i%2==0)){ dht11_val[j/8]<<=1; if(counter>16) dht11_val[j/8]|=1; j++; } } // verify checksum and print the verified data if((j>=40)&&(dht11_val[4]==((dht11_val[0]+dht11_val[1]+dht11_val[2]+dht11_val[3])& 0xFF))) { printf("%d.%d,%d.%d\n",dht11_val[0],dht11_val[1],dht11_val[2],dht11_val[3]); return 1; } else return 0; } int main(void) { int attempts=ATTEMPTS; if(wiringPiSetup()==-1) exit(1); while(attempts) { int success = dht11_read_val(); if (success) { break; } attempts--; delay(500); } return 0; }
Compile and execute the source code with the following commands:
gcc -o dht11 dht11.c -L/usr/local/lib -lwiringPi -lpthread sudo ./dht11
The program should return two numbers – one for relative humidity and the other for temperature.
Logging
The simplest method of creating a log of the temp/humidity is to use a cronjob. The program must be run as root, so use the following command to edit the cron config file:
sudo crontab -e
Add the following line to the end. It will save a timestamp and the temp/humidity every minute to temp.log.
* * * * * echo `date +\%Y\%m\%d\%H\%M\%S`,`/home/pi/wiringPi/dht11` >> /home/pi/temp.log
If that doesn’t seem to be working, the system cron may not be running. The following command will start it, and the line after will make sure it starts every time the RPi turns on:
sudo service cron start sudo update-rc.d cron defaults
Display
Reading a log file isn’t the easiest way to check how the temp/humidity is changing, but we can use a graphing library to read the log file and plot it. For this, I used DyGraph which is a Javascript library for plotting time-based information. Here is the final .html file I used:
<html> <head> <script type="text/javascript" src="dygraph-combined.js"></script> </head> <body> <div id="graphdiv" style="width:750px; height:400px;"></div> <script type="text/javascript"> function addZero(num) { var s=num+""; if (s.length < 2) s="0"+s; return s; } function dateFormat(indate) { var hh = addZero(indate.getHours()); var MM = addZero(indate.getMinutes()); //var ss = addZero(indate.getSeconds()); var dd = addZero(indate.getDate()); var mm = addZero(indate.getMonth()+1); var yyyy = addZero(indate.getFullYear()); return dd+'/'+mm+' '+hh+':'+MM; } g = new Dygraph( document.getElementById("graphdiv"), "temp.log", { xValueParser: function(x) { var date = new Date(x.replace( /^(\d{4})(\d\d)(\d\d)(\d\d)(\d\d)(\d\d)$/, '$4:$5:$6 $2/$3/$1' )); return date.getTime(); }, axes: { x: { ticker: Dygraph.dateTicker, axisLabelFormatter: function(x) { return dateFormat(new Date(x)); }, valueFormatter: function(x) { return dateFormat(new Date(x)); } } }, labelsDivWidth: 310, rollPeriod: 30, strokeWidth: 2.0, labels: ['Date','Humidity (%)','Temp (°C)'] } ); </script> </body> </html>
You can set this up on the RPi by installing a web server like Apache, creating a symlink to the log file, downloading dygraph and saving the above html file as /var/www/temp.html
.
sudo apt-get install apache2 ln -s /home/pi/temp.log /var/www/temp.log wget -P /var/www http://dygraphs.com/dygraph-combined.js
Then use your browser to navigate to 192.168.1.2/temp.html
, replacing the IP address with that of your RPi. To be able to access the page from the internet, you’ll have to set up NAT on your router.
Here’s what my final system looks like (click for an interactive demo):
Way Cool! I’ve been looking for an inexpensive and simple way to monitor a computer room temp and humidity for a non-profit. This is a great and complete example. I did need to add a few ‘sudo’s to get things working, but overall a marvelous (and working) RPi project.
Very awesome and complete example. Built and implemented this in no time! Easy as Pi.
Hi from Spain!
works perfect!
Quick and easy thanks.
Interesting, I built one of these up and then modified it for monitoring a wine storage room. However, as best I can tell, the DHT11 only reports the temperature to whole degrees centigrade, and humidity to whole % as well. Not a major problem, but I wonder if the DHT22 would provide the decimal place information. val[1] and val[3] are always zero…
Hi Bill, I found this looking at the fractional part missing on DHT11:
The DHT11 only fills the decimal part and keeps the fractional part zero.
The DHT22 and 21 do provide a fractonal part.
So it seems that for the DHT11 only decimal part is provided!!
I found the same thing. I only bought it for monitoring the humidity in my basement so no loss here but that’s certainly not accurate enough for any kind of realtemperature measurement. I think I would go with a thermistor if analogue input was available (which it is not on the Pi I think) or possibly something like the DS18B20 which I have used for external temperature monitoring (Not sure how easy that is to rig up to the Pi but I think I may find out soon).
Hi, Up and running Thanks!!!
The trouble that I have is that it is only displaying Humidity, The graph is auto scaling around the humidity signal.
Any thoughts?
Hi,
Thanks for your post, it’s so interesting and now I have the dth11 working… in my aquarium! Now I have a doubt, it’s possible connect two sensors? for example to measure indoor and outdoor temperature.
I tried to connect other sensor to my raspberry using the gpio pins numbers 4 (5.5v), 11 (data) and 14 (ground). Then I modified the file dht11.c, I replaced line “#define DHTPIN 7” to “#define DHTPIN 11”, but it’s possible that isn’t enough, I have not sufficient knowledge of programming :_(
I continued with the other steps, but it didn’t work…
Any idea about??
Thanks for all!!
Hi all, i have some problems… When i try to open from my browser 192.168.0.9/temp.html i can see only a blank page  . Apache is up and running because it opens correctlt 192.168.0.2/index.html. The temp.log file is correctly populated but the web display doesn’t work. Is needed some packages to use javascripts on raspberry? Do you have any idea? thanks in advance Bye Maurizio
This is a little confusing – is your Raspberry Pi Apache server on .9 or .2?
Whichever it is, make sure that the file “dygraph-combined.js” is in the same folder as your html file or you won’t see any graphing.
Hi Chris, thank you very much for this lovely setup, it works flawlessly, and ‘out of the box’.
I have a request, could you show me where to add 20% to the RH in the dht11.c code?
The cheap DHT11 sensors are usually kinda RH-off-set ;), and mine is 20% RH too low… I would like to adjust the RH value as ‘deep’ as possible, but I lack C programming skills.
Temperature is fine and shows realistic values. Cheers
Thanks – glad it worked. To include an offset I would add
#define HUMIDITY_OFFSET 20
to the top, then replace the printf line with
printf(“%d.%d,%d.%d\n”,dht11_val[0]+HUMIDITY_OFFSET,dht11_val[1],dht11_val[2],dht11_val[3]);
Wow, again your directions worked instantly:
20131118153501,37.0,20.0
20131118153601,38.0,20.0
20131118153702,37.0,20.0
20131118153801,57.0,20.0
20131118153901,58.0,20.0
… resulting in a steep climb in the chart, as to be expected.
Thanks again Chris, you rock!
can be added to to the graph sensor DS18B20 as the outside temperature? if yes, how pls.
thx
This is pretty cool. Thanks for posting. I’m trying to help out my son for his school project- he wants to see if plants grow better in two different greenhouses designs. We’ve got 2 dht 11 sensors hooked up to gpio 4 and 17 (pins 3 and 9, I believe). Both read independently, but I can’t seem to figure out the code to read both at the same time ( more or less). I’ve hacked away at this for a couple hours, and needless to say, my c skills leave something to be desired. Can anyone help out here?
Hello, I have done everything like you said, but if I run sudo Adafruit_DHT 2302 4 I get good response:
pi@raspberrypi /var/www $ sudo Adafruit_DHT 2302 4
Using pin #4
Data (40): 0x2 0x4f 0x0 0xc5 0x16
Temp = 19.7 *C, Hum = 59.1 %
But when I run sudo ./dht11 I get crazy response, I’m using AM2302 instead of DHT11:
pi@raspberrypi ~/wiringPi $ sudo ./dht11
2.86,0.197
Can you help me? Because in the log and graph display the wrong values…
Thanks.
If you look into the code for Adafruit, it looks like DHT22 processes the data differently.
However, if you change this code to similar to what Adafruit does, you still get a different value. Notably the biggest difference is Adafruit does High/Low where this code does Low/High. Changing this code doesnt change the values returned.
I am wondering if wiringPi does something different. This code does not match the Oregon Temp/Humid sensor sitting right next to my RPi + DHT22.
Another note.
I have not tried the HTML data graphing. B/c of this tutorial I plan on saving my data into a database (i feel like a log file with 1440 datapoints a day could get really large really quick), serve it up via nginx (less memory consumer), and run it in php (so that i can read the db).
This is a very cool idea and though the code to read the sensor didnt work, the overall idea is fantastic.
Database is a good solution but a logfile would not be overly huge (and would take up about the same space). If you mean a database on a different system, you could also do that with a logfile.
Very useful article, works great on my pi.
Everything is complete, except i’m just not getting anything on the html, I’ve modified the code and used a water moisture sensor, so far, the output on the log file (moisture.log) is good (i’ve only have one data output instead of two like on the humidity + temperature sensor), I’ve installed apache, my html is accessible (ip-address/moisture.html) but it’s not displaying the graph…. I’ve modified the HTML code, to point to moisture.log instead of temp.log and changed the levels. Any suggestions?
thanks (:
I mean labels*
Hey there!
I am not able to compile the c code. I always get the following error:
/usr/lib/gcc/arm-linux-gnueabihf/4.6/../../../arm-linux-gnueabihf/crt1.o: In function `_start’:
(.text+0x34): undefined reference to `main’
collect2: ld returned 1 exit status
I dont understand it, what is going wrong with the compilation?
can anybody help or send me the compiled program?
Try adding -lpthread to the compile command. Otherwise, try this.
I too have compile errors: sudo gcc -o dht11.c -L/usr/local/lib -lwiringPi -lpthread
/usr/lib/gcc/arm-linux-gnueabihf/4.6/../../../arm-linux-gnueabihf/crt1.o: In function `_start’:
(.text+0x34): undefined reference to `main’
collect2: ld returned 1 exit status
“Otherwise, try this above” does not work either
Amazing job, thanks for sharing!
Just one question: I followed all the steps, but in my case the graph shows only the humidity data. If I read the log I find the temperature is there too. What can be the issue?
I’m also missing one more thing: the log saves the data like “20140611224501,34.0,31.0”, but where do the graph find the other decimals?
Thanks in advance, hope you can help me
purge the first data of your log or erase your log.
Hi, Great tutorial.All worked well until I restarted then had same problem as others,only humidity is shown.Temp data is shown in temp.log.
I have searched for answers but not found anything.
Thanks in advance.
[…] found a great and detailed post about using the DHT11 humidiy sensor with Raspberry Pi and publish the data […]
[…] Sensor. An avid beer brewer used Raspberry Pi to make a humidity sensor that he could monitor on his […]
[…] time I tried to use a DHT11 and follow, more or less, the advise from this link. Then I move into more sensors and use graphite as data base as well of a way to represent […]
Hi.Thanks for the article. I came across this page looking for a similar solution. I tried the steps. However, for the command “ln -s /home/pi/temp.log /var/www/temp.log”, I get a message “Failed to create symbolic link ‘var/www/temp.log’: No such file or directory.
If it helps RPi isn’t connected to internet when I tried this. Can you help me with this?
I created a temp.log file using leaf pad at /var/www/temp.log and the message now for the command “ln -s /home/pi/temp.log /var/www/temp.log” is “Failed to create symbolic link ‘var/www/temp.log’: File found.
I also see the temp file is empty whenever I check it. By the way, Im trying to use this technique with the files from https://github.com/richardghirst/PiBits/tree/master/MPU6050-Pi-Demo.
However, the index.html gives a nice it is working display.
Advise please on where Im missing
[…] following this project that basically is a tutorial to create a local webpage and display the room temperature and […]
Hello,
great tutorial, however in temp.html file there were no temperature data showing up, only humidity. So i changed some things:
In crontab i changed temp.log to temp.csv:
* * * * * echo `date +\%Y\%m\%d\%H\%M\%S`,`/home/pi/wiringPi/dht11` >> /home/pi/temp.csv
Then:
sudo ln -s /home/pi/temp.csv /var/www/temp.csv
And in html code:
g = new Dygraph(
document.getElementById(“graphdiv”),
“temp.csv”,
I changed temp.log to temp.csv everywhere. And now it shows temperature data.
I am no expert, foud out by trial and error.
If anybody knows better way please write it down here.
Thanks.
Great – as folks above say, it worked “straight out the box”. I’m very new to programming on the RPi but would like to call the C programme above from Python and get it to return the temperature and humidity values for further manipulation (from my reading the reason for using C to read the DTH11 is to get a more reliable solution than by reading from Python directly) . Does anyone have any suggestions on how I would / could do this and would it work?
Hi ,
congratulations ,
I was looking for this solution ,
is very well explained . I learned a lot , and created a graph to monitor the temperature of the raspberry .
Thank you
Will the log file grow forever or will the oldest data be deleted?
[…] publish the weather data on the web you must follow my old DHT11 post and this one, but you must change the original DHT11 C program to the new DHT11/22 python […]
[…] a last but not least, minnor changes on the web client to show […]
Reblogged this on True Lover!!!.
Very nice tutorial. It’s working like a charm. 🙂
For All that are trying to move the DHT11 sensor to another pin.
Yes changing the #define DHT11PIN in the c file is enough (and the recompile it).
But the thing is that for example GPIO-17 is on pin 11 of the pi BUT on pin 0 of the wiringPI interface. 🙂
So that would be
// #define DHT11PIN 7 //GPIO-4
#define DHT11PIN 0 //GPIO-17
see

http://www.instructables.com/id/Raspberry-Pi-Temperature-Humidity-Network-Monitor/?ALLSTEPS &
perhaps something interesting for Chris to add to his beautiful and very useful blog
The Graph would not shown in Safari, in Firefox it works. Any hints what i can do?
[…] also found a guy using the DHT-11 for monitoring his beer https://chrisbaume.wordpress.com/2013/02/10/beer-monitoring/ That sounds like a good use for a […]
Hi,
this is a nice instruction. I still have a problem with the data i get when i type sudo ./dht11. Iget severeal error (invalid data) and in between som values.
Can anybody help me with this issue?
Another Problem is an empty temp.log file. I have a cron job allready started.
best regards
Cay
Good morning, I followed his wonderful example, but I have a problem I can not solve in the chart that comes from the web page is missing the line with the current temperature as in his graphic 07/02 10:52: Humidity (%): 39.63 … .what did I go wrong? thanks
maybe I did not understand, the data in the upper right corner are those corresponding to the mouse position in the curve of the graph. You can instead add a line that print the last reading , maybe in the bottom left? thank you very much.
Hello! Great project, I have had a lot of fun with this. Unfortunately, my web page simply displays a blank page. I had a feeling it had to do with default file permissions on the temp.html file. So I changed it so everyone had read write privileges. That did not make a difference. My dygraph-combined.js file is in the same directory as my .html file. I am out of ideas. Can someone give me a better idea to make this work? Thx
[…] publish the weather data on the web you must follow my old DHT11 post and this one, but you must change the original DHT11 C program to the new DHT11/22 python […]
It worked at the first try 🙂 thanx!
Thanks for the code!
I found if you only get humidity readings, it’s probably down to corrupt data in the log file. Try deleting the log file or editing out the corrupt data. In my case I had some null characters in the log. I removed them and refreshed the graph and the temperature readings appeared.
[…] https://chrisbaume.wordpress.com/2013/02/10/beer-monitoring/ […]
Could you help me out for just 1 thing?
i followed everything except the part of the webpage, and all seem well.
you said ” i have to set up NAT on my router”, could you explain how to do this?
i googled but i can’t get it well. Thanks
Having a little trouble adding the dht11.c file to the wiringPi directory. How do you do this exactly?
Thanks for sharing this nice article.
[…] 湿度と温度センサー […]
Very Nice, i like the way you explain, Thank you
Hello,
great tutorial! The only thing I had to change was this path “/var/www/” to “/var/www/html”
(everywhere)
https://askubuntu.com/questions/683953/where-is-apache-web-root-directory-on-ubuntu
[…] by: Chris Baume Project Website: https://chrisbaume.wordpress.com/2013/02/10/beer-monitoring/ If you’re lucky enough to have a beer brewing station in your own home, you know that one of the […]
[…] Beer monitoring with my Raspberry Pi – Chris Baume […]