【Python】Raspberry Piで室温、湿度を取得

2021年11月3日

pigpioを使い温度と湿度をPythonで取得してみたので、自分用に内容を記事にしときたいと思います。

前回の記事でDHT22を動かす為の配線を行いましたので、これを動かしていきます。

Pythonでpigpioを動かす場合、まずこっちの環境構築をしておきましょう。

プログラムはこちらのソースをほぼほぼ流用しており、3秒ごとに温度と湿度を示す数値を表示するものです。

# -*- coding: utf-8 -*-

import time
import pigpio

class DHT22:
	'DHT22 sensor reader class for Raspberry'

	pi = None
	temp = 0
	rhum = 0
	bad_CS = 0  # Bad checksum count.
	bad_SM = 0  # Short message count.
	bad_MM = 0  # Missing message count.
	bad_SR = 0  # Sensor reset count.
	high_tick = 0
	bit = 40
	cb = None
	no_response = 0
	
	MAX_NO_RESPONSE = 2

	def __init__(self, pin):
		self.__pin = pin
		self.pi = pigpio.pi()
		self.pi.set_pull_up_down(pin,pigpio.PUD_UP)
		self.pi.set_watchdog(pin, 0)
		self.cb = self.pi.callback(pin, pigpio.EITHER_EDGE, self._cb)

	def _cb(self, gpio, level, tick):
		"""
		Accumulate the 40 data bits. Format into 5 bytes, humidity high,
		humidity low, temperature high, temperature low, checksum.
		"""
		diff = pigpio.tickDiff(self.high_tick, tick)
		
		if level == 0:

			# Edge length determines if bit is 1 or 0.

			if diff >= 50:
				val = 1
				if diff >= 200:	# Bad bit?
					self.CS = 256	# Force bad checksum.
			else:
				val = 0

			if self.bit >= 40:	# Message complete.
				self.bit = 40

			elif self.bit >= 32:	# In checksum byte.
				self.CS	= (self.CS << 1) + val

				if self.bit == 39:

					# 40th bit received.

					self.pi.set_watchdog(gpio, 0)

					self.no_response = 0

					total = self.hH + self.hL + self.tH + self.tL

					if (total & 255) == self.CS:	# Is checksum ok?

						self.rhum = round(((self.hH << 8) + self.hL) * 0.1,2)

						if self.tH & 128:	# Negative temperature.
							mult = -0.1
							self.tH = self.tH & 127
						else:
							mult = 0.1

						self.temp = round(((self.tH << 8) + self.tL) * mult,2)

						self.tov = time.time()

					else:

						self.bad_CS += 1

			elif self.bit >= 24:	# in temp low byte
				self.tL = (self.tL << 1) + val

			elif self.bit >= 16:	# in temp high byte
				self.tH = (self.tH << 1) + val

			elif self.bit >= 8:	# in humidity low byte
				self.hL = (self.hL << 1) + val

			elif self.bit >= 0:	# in humidity high byte
				self.hH = (self.hH << 1) + val

			else:				# header bits
				pass

			self.bit += 1

		elif level == 1:
			self.high_tick = tick
			if diff > 250000:
				self.bit = -2
				self.hH = 0
				self.hL = 0
				self.tH = 0
				self.tL = 0
				self.CS = 0

		else:	# level == pigpio.TIMEOUT:
			self.pi.set_watchdog(self.__pin, 0)
			
			if self.bit < 8:		# Too few data bits received.
				self.bad_MM += 1	# Bump missing message count.
				self.no_response += 1
				if self.no_response > self.MAX_NO_RESPONSE:
					self.no_response = 0
					self.bad_SR += 1	# Bump sensor reset count.
				
			elif self.bit < 39:	# Short message receieved.
				self.bad_SM += 1	# Bump short message count.
				self.no_response = 0

			else:					# Full message received.
				self.no_response = 0
		
	def trigger(self):
		self.pi.write(self.__pin, pigpio.LOW)
		time.sleep(0.019)
		self.pi.set_mode(self.__pin, pigpio.INPUT)
		self.pi.set_pull_up_down(self.__pin,pigpio.PUD_UP)
		self.pi.set_watchdog(self.__pin, 200)
		
	def temperature(self):
		"""Return current temperature."""
		return self.temp

	def humidity(self):
		"""Return current relative humidity."""
		return self.rhum


GPIO_PIN = 17
s = DHT22(pin=GPIO_PIN)

while True:
	s.trigger()
	time.sleep(3)
	print("温度:"+str(s.temperature())+" 湿度:"+str(s.humidity()))

s.pi.stop()
実行結果

温度:19.2 湿度:55.0
温度:19.2 湿度:55.1
温度:19.2 湿度:53.8
温度:19.2 湿度:54.9
温度:19.2 湿度:53.8
温度:19.2 湿度:55.0

関連記事