сайт для палких паяльників

Подключим датчик температуры и влажности DHT11 к Raspberry Pi. Я раньше писал о популярном датчик влажности и температуры DHT11 в статье DHT11 – цифровой датчик температуры и влажности Документация по DHT11: DHT11.pdf, DHT11_a.pdf.

Размеры и распиновка DHT11:

DHT11

Подключим датчик к Raspberry Pi, как указано на схеме.

RaspberryPi - DHT11

DHT11 & Raspberry Pi

Начнем с примера на С. Создадим файл dht11.c:

#include <wiringPi.h>

#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#define MAXTIMINGS	85
#define DHTPIN		7
int dht11_dat[5] = { 0, 0, 0, 0, 0 };

void read_dht11_dat()
{
	uint8_t laststate	= HIGH;
	uint8_t counter		= 0;
	uint8_t j		= 0, i;
	float	f; /* fahrenheit */

	dht11_dat[0] = dht11_dat[1] = dht11_dat[2] = dht11_dat[3] = dht11_dat[4] = 0;

	/* pull pin down for 18 milliseconds */
	pinMode( DHTPIN, OUTPUT );
	digitalWrite( DHTPIN, LOW );
	delay( 18 );
	/* then pull it up for 40 microseconds */
	digitalWrite( DHTPIN, HIGH );
	delayMicroseconds( 40 );
	/* prepare to read the pin */
	pinMode( DHTPIN, INPUT );

	/* detect change and read data */
	for ( i = 0; i < MAXTIMINGS; i++ )
	{
		counter = 0;
		while ( digitalRead( DHTPIN ) == laststate )
		{
			counter++;
			delayMicroseconds( 1 );
			if ( counter == 255 )
			{
				break;
			}
		}
		laststate = digitalRead( DHTPIN );

		if ( counter == 255 )
			break;

		/* ignore first 3 transitions */
		if ( (i >= 4) && (i % 2 == 0) )
		{
			/* shove each bit into the storage bytes */
			dht11_dat[j / 8] <<= 1;
			if ( counter > 16 )
				dht11_dat[j / 8] |= 1;
			j++;
		}
	}

	/*
	 * check we read 40 bits (8bit x 5 ) + verify checksum in the last byte
	 * print it out if data is good
	 */
	if ( (j >= 40) &&
	     (dht11_dat[4] == ( (dht11_dat[0] + dht11_dat[1] + dht11_dat[2] + dht11_dat[3]) & 0xFF) ) )
	{
		f = dht11_dat[2] * 9. / 5. + 32;
		printf( "Humidity = %d.%d %% Temperature = %d.%d *C (%.1f *F)\n",
			dht11_dat[0], dht11_dat[1], dht11_dat[2], dht11_dat[3], f );
	}else  {
		printf( "Data not good, skip\n" );
	}
}

int main( void )
{
	printf( "Raspberry Pi wiringPi DHT11 Temperature test program\n" );

	if ( wiringPiSetup() == -1 )
		exit( 1 );

	while ( 1 )
	{
		read_dht11_dat();
		delay( 1000 ); /* wait 1sec to refresh */
	}

	return(0);
}

В этой программе используется библиотека wiringPi. Мы её устанавливали в предыдущей статье Raspberry Pi – PWM и Сервопривод. Если wiringPi еще не установлен, это делается следующим образом:

sudo apt-get install git-core
git clone git://git.drogon.net/wiringPi
cd wiringPi
./build
cd ..

Компилируем dht11.c:

gcc dht11.c -o dht11 -lwiringPi

Запустим программу:

./dht11

На экране должны увидеть следующее:

Raspberry Pi wiringPi DHT11 Temperature test program
Humidity = 33.0 % Temperature = 27.0 *C (80.6 *F)
Humidity = 33.0 % Temperature = 27.0 *C (80.6 *F)
Data not good, skip
Data not good, skip
Humidity = 33.0 % Temperature = 27.0 *C (80.6 *F)
Humidity = 33.0 % Temperature = 27.0 *C (80.6 *F)
Data not good, skip
Humidity = 33.0 % Temperature = 27.0 *C (80.6 *F)
Humidity = 33.0 % Temperature = 27.0 *C (80.6 *F)
Humidity = 33.0 % Temperature = 27.0 *C (80.6 *F)
Humidity = 33.0 % Temperature = 27.0 *C (80.6 *F)
Humidity = 33.0 % Temperature = 27.0 *C (80.6 *F)
Humidity = 33.0 % Temperature = 27.0 *C (80.6 *F)

Теперь попробуем пример на Python.
Создадим файл dht11.py:

import RPi.GPIO as GPIO
import time

def bin2dec(string_num):
    return str(int(string_num, 2))

data = []

GPIO.setmode(GPIO.BCM)

GPIO.setup(4,GPIO.OUT)
GPIO.output(4,GPIO.HIGH)
time.sleep(0.025)
GPIO.output(4,GPIO.LOW)
time.sleep(0.02)

GPIO.setup(4, GPIO.IN, pull_up_down=GPIO.PUD_UP)

for i in range(0,500):
    data.append(GPIO.input(4))

bit_count = 0
tmp = 0
count = 0
HumidityBit = ""
TemperatureBit = ""
crc = ""

try:
        while data[count] == 1:
                tmp = 1
                count = count + 1

        for i in range(0, 32):
                bit_count = 0

                while data[count] == 0:
                        tmp = 1
                        count = count + 1

                while data[count] == 1:
                        bit_count = bit_count + 1
                        count = count + 1

                if bit_count > 3:
                        if i>=0 and i<8:
                                HumidityBit = HumidityBit + "1"
                        if i>=16 and i<24:
                                TemperatureBit = TemperatureBit + "1"
                else:
                        if i>=0 and i<8:
                                HumidityBit = HumidityBit + "0"
                        if i>=16 and i<24:
                                TemperatureBit = TemperatureBit + "0"

except:
        print "ERR_RANGE"
        exit(0)

try:
        for i in range(0, 8):
                bit_count = 0

                while data[count] == 0:
                        tmp = 1
                        count = count + 1

                while data[count] == 1:
                        bit_count = bit_count + 1
                        count = count + 1

                if bit_count > 3:
                        crc = crc + "1"
                else:
                        crc = crc + "0"
except:
        print "ERR_RANGE"
        exit(0)

Humidity = bin2dec(HumidityBit)
Temperature = bin2dec(TemperatureBit)

if int(Humidity) + int(Temperature) - int(bin2dec(crc)) == 0:
        print "Humidity:"+ Humidity +"%"
        print "Temperature:"+ Temperature +"C"
else:
        print "ERR_CRC"

Запустим его:

python ./dht11.py

Должны увидеть следующее:

Humidity:33%
Temperature:27C

Но иногда скрипт выдает:

ERR_RANGE

Если вы обратили внимание программа на С тоже не всегда мог четко считывать данные. Я долго ковырялся с этой проблемой и пытался хоть как-то ее решить. Оказалось, что Raspberry Pi … не работает в режиме реального времени! То есть, программные задержки не всегда точны. Это приводит к ошибкам при считывании данных.
Я не нашел другого пути (он мне не нравится, но он работает), как написать скрипта, который пытается считывать данные из датчика до первой удачной попытки. Количество попыток ограничено 10.

Текст скрипта dht11_read.py:

# This script try to read from DHT11 10 times
# Return first correct result
# Note This script is a way to fix bug of reading from DHT11
import subprocess
counter = 0

while (counter < 10 ):
	result = subprocess.Popen("python /root/scripts/dht11.py", shell = True, stdout = subprocess.PIPE).communicate()[0]
	if (result == "32\n"):
		print result
		exit(1)
	counter +=1

Успехов.

Смотри также:
Translate
Архіви

© 2011-2018 Андрій Корягін, Кременчук - Київ, Україна