RaspberryPi Humidity and Temperature Sensor (obsolete)

From Wurst-Wasser.net
Jump to navigation Jump to search
The printable version is no longer supported and may have rendering errors. Please update your browser bookmarks and please use the default browser print function instead.

THIS PAGE IS OBSOLETE - PLEASE CONTINUE READING HERE: Home Automation with Raspberry Pi


Schematics

RaspberryPiDHT11.png
Remember that the Pi revisions have different pinouts! This will work for Revison 2, that is board revision 0004[1]. If you don't need humidity readings, I strongly recommend using a DS18B20 instead of the DHT11, as showed in RaspberryPi Temperature Sensor, because you can use the 1-wire kernel modules for reading the DS18B20, which makes it much easier to read and extend.

Configure the Pi

Update the OS

This is not necessary, but generally a good idea.

apt-get update
apt-get upgrade

Install missing packages

If you have already installed them, you can skip this step.

apt-get install gnuplot
apt-get install git

Install DHT11 driver

Since there seems to be no kernel module for DHT11, do this:

git clone git://git.drogon.net/wiringPi
cd wiringPi
git pull origin
./build

Create a file hum_temp.c with this content (Code taken from here from Rahul Kar):

#include <wiringPi.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#define MAX_TIME 85
#define DHT11PIN 7
int dht11_val[5]={0,0,0,0,0};

void dht11_read_val()
{
uint8_t lststate=HIGH;
uint8_t counter=0;
uint8_t j=0,i;
float farenheit;
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)))
{
	farenheit=dht11_val[2]*9./5.+32;
	printf("Humidity: %d.%d%% Temperature: %d.%dC (%.1f *F)\n",dht11_val[0],dht11_val[1],dht11_val[2],dht11_val[3],farenheit);
}
else
{
	printf("Invalid Data!!\n");
}
}

int main(void)
{
//printf("Interfacing Temperature and Humidity Sensor (DHT11) With Raspberry Pi\n");
if(wiringPiSetup()==-1)
{ 
	exit(1);
} 

dht11_read_val();

return 0;
}
gcc -o sensor hum_temp.c -L/usr/local/lib -lwiringPi
./sensor
Humidity: 46.0% Temperature: 22.0C (71.6 *F)

Code

This is how I read the device and generate a nice plot using GNUplot:

#/bin/bash
#set -x
#
# Script: readHumidityAndTemperature.sh
# Author: Heiko Kretschmer
# Purpose: Reading the humidity/temperature and generating a nice plot
#
#

#
# Globals
#
GBASENAME="readHumidityAndTemperature"
GTIMESTAMPFORMAT="%Y-%m-%d_%H:%M"
GTIMESTAMP="`date +${GTIMESTAMPFORMAT}`"
GTIMESTAMPTIME="`date '+%H:%M'`"
GTIMESTAMPDATE="`date '+%Y-%m-%d'`" # ISO 8601 date format
GTIMESTAMPDATEHUMANREADABLE="`date '+%A, %Y-%m-%d'`"
#GFOLDERBASE="/home/pi/Development/humidity_and_temperature"
GFOLDERBASE="/home/pi/Development/humidity_and_temperature/wiringPi"
GCMDSENSOR="${GFOLDERBASE}/sensor"
GFOLDERLOGS="${GFOLDERBASE}/logs"
GFOLDERGRAPHS="${GFOLDERBASE}/graphs"
GFOLDERTMP="${GFOLDERBASE}/tmp"
GFILELOGHUM="${GFOLDERLOGS}/${GBASENAME}_${GTIMESTAMPDATE}_Humidity.log"
GFILELOGTEMP="${GFOLDERLOGS}/${GBASENAME}_${GTIMESTAMPDATE}_Temperature.log"
GFILEGRAPHHUM="${GFOLDERGRAPHS}/${GBASENAME}_${GTIMESTAMPDATE}_Humidity.svg"
GFILEGRAPHTEMP="${GFOLDERGRAPHS}/${GBASENAME}_${GTIMESTAMPDATE}_Temperature.svg"
GFILEGRAPHHUMTEMP="${GFOLDERGRAPHS}/${GBASENAME}_${GTIMESTAMPDATE}_Humidity_Temperature.svg"
GFILEPLOTCOMMANDS="${GFOLDERTMP}/${GBASENAME}-plot.cmd"

#
# Functions 
#
FPLOTGRAPHDOUBLE() # Plotting a single graph into one diagramm
{
  DATAFILE1=$1
  LINE1COLOUR=$2
  LINE1LABEL=$3
  LINE1UNITS=$4
  DATAFILE2=$5
  LINE2COLOUR=$6
  LINE2LABEL=$7
  LINE2UNITS=$8
  OUTFILE=$9

  test -f "${GFILEPLOTCOMMANDS}" && rm "${GFILEPLOTCOMMANDS}"

  # Reset
  echo "reset" >> "${GFILEPLOTCOMMANDS}"

  # Set output file type to svg
  echo "set term svg size 640,480" >> "${GFILEPLOTCOMMANDS}"
  echo "set output \"${OUTFILE}\"" >> "${GFILEPLOTCOMMANDS}"
  
  # Key
  echo "set key inside right top vertical Right noreverse enhanced autotitles columnhead nobox" >> "${GFILEPLOTCOMMANDS}"

  # Set time format for X axis
  echo "set timefmt \"%H:%M\"" >> "${GFILEPLOTCOMMANDS}"
  echo "set xdata time" >> "${GFILEPLOTCOMMANDS}"
  echo "set format x \"%H:%M\"" >> "${GFILEPLOTCOMMANDS}"

  # Setup line style (#1) for the first line
  echo "set style line 1 lc rgb \"${LINE1COLOUR}\" pt 1 ps 1 lt 1 lw 2" >> "${GFILEPLOTCOMMANDS}" # http://www.gnuplotting.org/tag/grid/

  # Setup line style (#2) for the second line
  echo "set style line 2 lc rgb \"${LINE2COLOUR}\" pt 1 ps 1 lt 1 lw 2" >> "${GFILEPLOTCOMMANDS}" # http://www.gnuplotting.org/tag/grid/
  echo "set style data lines" >> "${GFILEPLOTCOMMANDS}"

  # Set X tics (one tic per hour, rotate that tick-labels by 90 deg and move em a bit)
  echo "set xtics \"01:00\" rotate by 90 offset 0,-2 out nomirror" >> "${GFILEPLOTCOMMANDS}"

  # Setup Grid (with line style #12)
  echo "set style line 12 lc rgb '#E0E0E0' lt 0 lw 1" >> "${GFILEPLOTCOMMANDS}" # http://www.gnuplotting.org/tag/grid/
  echo "set grid back ls 12" >> "${GFILEPLOTCOMMANDS}" # http://www.gnuplotting.org/tag/grid/

  # Setup Title
  echo "set title \"${LINE1LABEL} and ${LINE2LABEL} on ${GTIMESTAMPDATEHUMANREADABLE}\"" >> "${GFILEPLOTCOMMANDS}"

  # Label X and Y Axis
  echo "set ylabel \"${LINE1UNITS}\"" >> "${GFILEPLOTCOMMANDS}"
  echo "set y2label \"${LINE2UNITS}\"" >> "${GFILEPLOTCOMMANDS}"
  echo "set xlabel \"Time\" offset 0,-0.5" >> "${GFILEPLOTCOMMANDS}"

  # Setup Y range(s)
  echo "set yrange [ 0.000 : 100.000 ] noreverse nowriteback" >> "${GFILEPLOTCOMMANDS}"
  echo "set y2range [ 0.000 : 50.000  ] noreverse nowriteback" >> "${GFILEPLOTCOMMANDS}"

  # Tics on the outside, also do the tics for y2, too
  echo "set tics out" >> "${GFILEPLOTCOMMANDS}"
  echo "set y2tics" >> "${GFILEPLOTCOMMANDS}"

  # Plot line 1
  echo "plot \"${DATAFILE1}\" using 1:2 title '${LINE1LABEL}' with l ls 1 axes x1y1, \"${DATAFILE2}\" using 1:2 title '${LINE2LABEL}' with l ls 2 axes x1y2" >> "${GFILEPLOTCOMMANDS}"

  cat "${GFILEPLOTCOMMANDS}" 
  cat "${GFILEPLOTCOMMANDS}" | gnuplot 

} # end of FPLOTGRAPHDOUBLE


FPLOTGRAPHSINGLE() # Plotting a single graph
{
  DATAFILE=$1
  LINE1COLOUR=$2
  LINE1LABEL=$3
  LINE1UNITS=$4
  OUTFILE=$5
  test -f "${GFILEPLOTCOMMANDS}" && rm "${GFILEPLOTCOMMANDS}"
  echo "reset" >> "${GFILEPLOTCOMMANDS}"
  echo "set key inside right top vertical Right noreverse enhanced autotitles columnhead nobox" >> "${GFILEPLOTCOMMANDS}"

  # Set time format for X axis
  echo "set timefmt \"%H:%M\"" >> "${GFILEPLOTCOMMANDS}"
  echo "set xdata time" >> "${GFILEPLOTCOMMANDS}"
  echo "set format x \"%H:%M\"" >> "${GFILEPLOTCOMMANDS}"

  # Setup line style (#1) for the temperature line
  echo "set style line 1 lc rgb \"${LINE1COLOUR}\" pt 1 ps 1 lt 1 lw 2" >> "${GFILEPLOTCOMMANDS}" # http://www.gnuplotting.org/tag/grid/
  echo "set style data lines" >> "${GFILEPLOTCOMMANDS}"

  # Set X tics (one tic per hour, rotate that tick-labels by 90 deg and move em a bit)
  echo "set xtics \"01:00\" rotate by 90 offset 0,-2 out nomirror" >> "${GFILEPLOTCOMMANDS}"

  # Setup Grid (with line style #12)
  echo "set style line 12 lc rgb '#E0E0E0' lt 0 lw 1" >> "${GFILEPLOTCOMMANDS}" # http://www.gnuplotting.org/tag/grid/
  echo "set grid back ls 12" >> "${GFILEPLOTCOMMANDS}" # http://www.gnuplotting.org/tag/grid/

  # Setup Title
  echo "set title \"${LINE1LABEL} on ${GTIMESTAMPDATEHUMANREADABLE}\"" >> "${GFILEPLOTCOMMANDS}"

  # Label X and Y Axis
  echo "set ylabel \"${LINE1UNITS}\"" >> "${GFILEPLOTCOMMANDS}"
  echo "set xlabel \"Time\" offset 0,-0.5" >> "${GFILEPLOTCOMMANDS}"

  # Setup Y range
  echo "set yrange [ 0.000 : ] noreverse nowriteback" >> "${GFILEPLOTCOMMANDS}"

  # Set output file type to svg and plot it into file
  echo "set term svg size 640,480" >> "${GFILEPLOTCOMMANDS}"
  echo "set output \"${OUTFILE}\"" >> "${GFILEPLOTCOMMANDS}"
  echo "plot \"${DATAFILE}\" using 1:2 title '${LINE1LABEL}' with l ls 1" >> "${GFILEPLOTCOMMANDS}"
  cat "${GFILEPLOTCOMMANDS}" | gnuplot 
}

#
# Main
#

# Init
test ! -d "${GFOLDERLOGS}" && mkdir "${GFOLDERLOGS}"
test ! -d "${GFOLDERGRAPHS}" && mkdir "${GFOLDERGRAPHS}"
test ! -d "${GFOLDERTMP}" && mkdir "${GFOLDERTMP}"

# Get values
LINE="`sudo ${GCMDSENSOR}`"
echo "LINE: ${LINE}"
HUMIDITY="`echo \"${LINE}\" | cut -d: -f2 | cut -d\\% -f1 | awk '{printf $1}'`"
echo "HUMIDITY: ${HUMIDITY}"
TEMPERATURE="`echo \"${LINE}\" | cut -d: -f3 | cut -dC -f1 | awk '{printf $1}'`"
echo "TEMPERATURE: ${TEMPERATURE}"

if [ "${HUMIDITY}" != "Invalid" -a "${TEMPERATURE}" != "Invalid" ]; then

  # Write it into the log (one logfile per day to get nice graphs)
  echo -e "${GTIMESTAMPTIME}\t${HUMIDITY}" >> "${GFILELOGHUM}"
  echo -e "${GTIMESTAMPTIME}\t${TEMPERATURE}" >> "${GFILELOGTEMP}"
#  echo -e "${GTIMESTAMPTIME}\t${HUMIDITY}\t${TEMPERATURE}" >> "${GFILELOGHUMTEMP}"

else
  echo "Read from sensor failed, plotting (old data) anyway."
fi

  # Generate the graphs (single)
  FPLOTGRAPHSINGLE "${GFILELOGHUM}" '#0e1a8b' "Humidity" "%" "${GFILEGRAPHHUM}"
  FPLOTGRAPHSINGLE "${GFILELOGTEMP}" '#8b1a0e' "Temperature" "°C" "${GFILEGRAPHTEMP}"

  # Generate combined graph (double)
  FPLOTGRAPHDOUBLE "${GFILELOGHUM}" '#0e1a8b' "Humidity" "%" "${GFILELOGTEMP}" '#8b1a0e' "Temperature" "°C" "${GFILEGRAPHHUMTEMP}"


You might want to use a cronjob like this:

*/15 * * * *    /home/pi/Development/temperature/readHumidityAndTemperature.sh > /dev/null 2>&1

Resulting graph

And this is how it looks:
RaspberryPiDHT11TemperaturePlotExample.svg
RaspberryPiDHT11HumidityPlotExample.svg
RaspberryPiDHT11HumidityTemperaturePlotExample.svg