前提・実現したいこと
文系学生が、趣味でラズパイを弄り始めておそらく初歩的なミスを犯しました。
RaspberryPi pico と Pythonで、DHT11から得た値をある指数に変換し、指数の大きさによってフルカラーLEDの色を変化させるというデバイスを制作しております。開発環境は、VScodeです。
その前段階として、以下に示した参考サイトのコードをほとんどそのまま用いて(華氏と摂氏の両方を表すプログラムであったため、華氏に言及する2行を削除しました。 14行目、16行目。)DHT11のモジュールが使用できるかを試しています。
しかしながら、コードを添付したところ、下記(該当のソースコード 5行目)のDHT11の部分に赤波線が現れ、そのまま実行しましたが正常にプログラムが作動しませんでした。
モジュールであるDHT11のファイル、dht.pyもインストール済みで、同じように進めていたのですがどこに問題があるのかわからず苦戦しております。
今回のテストを行う前に、ラズパイpicoに搭載してあるLEDを点滅させるプログラムは正常に作動いたしましたので、今回はおそらくモジュールが反映されていないのではないかと考えております。
お忙しいところ恐縮ですが、ご教授いただけると幸いです。
* 尚、エラーメッセージ5行目の _convert_pulses_to_buffer ですが、
dht.py の 99行目に表記されております。
https://randomnerdtutorials.com/esp32-esp8266-dht11-dht22-micropython-temperature-humidity-sensor/
発生している問題・エラーメッセージ
Traceback (most recent call last): File "<stdin>", line 10, in <module> File "/lib/dht.py", line 58, in temperature File "/lib/dht.py", line 44, in measure AttributeError: 'DHT11' object has no attribute '_convert_pulses_to_buffer'
該当のソースコード
Python (Complete project details at https://RandomNerdTutorials.com)
from machine import Pin from time import sleep import dht sensor = dht.DHT11(Pin(28)) #sensor = dht.DHT11(Pin(14)) while True: try: sleep(2) sensor.measure() temp = sensor.temperature() hum = sensor.humidity() #temp_f = temp * (9/5) + 32.0 print('Temperature: %3.1f C' %temp) #print('Temperature: %3.1f F' %temp_f) print('Humidity: %3.1f %%' %hum) except OSError as e: print('Failed to read sensor.')
Python (DHT11モジュールファイル)
dht.py
import array import micropython import utime from machine import Pin from micropython import const class InvalidChecksum(Exception): pass class InvalidPulseCount(Exception): pass MAX_UNCHANGED = const(100) MIN_INTERVAL_US = const(200000) HIGH_LEVEL = const(50) EXPECTED_PULSES = const(84) class DHT11: _temperature: float _humidity: float def __init__(self, pin): self._pin = pin self._last_measure = utime.ticks_us() self._temperature = -1 self._humidity = -1 def measure(self): current_ticks = utime.ticks_us() if utime.ticks_diff(current_ticks, self._last_measure) < MIN_INTERVAL_US and ( self._temperature > -1 or self._humidity > -1 ): # Less than a second since last read, which is too soon according # to the datasheet return self._send_init_signal() pulses = self._capture_pulses() buffer = self._convert_pulses_to_buffer(pulses) self._verify_checksum(buffer) self._humidity = buffer[0] + buffer[1] / 10 self._temperature = buffer[2] + buffer[3] / 10 self._last_measure = utime.ticks_us() @property def humidity(self): self.measure() return self._humidity @property def temperature(self): self.measure() return self._temperature def _send_init_signal(self): self._pin.init(Pin.OUT, Pin.PULL_DOWN) self._pin.value(1) utime.sleep_ms(50) self._pin.value(0) utime.sleep_ms(18) def _capture_pulses(self): pin = self._pin pin.init(Pin.IN, Pin.PULL_UP) val = 1 idx = 0 transitions = bytearray(EXPECTED_PULSES) unchanged = 0 timestamp = utime.ticks_us() while unchanged < MAX_UNCHANGED: if val != pin.value(): if idx >= EXPECTED_PULSES: raise InvalidPulseCount( "Got more than {} pulses".format(EXPECTED_PULSES) ) now = utime.ticks_us() transitions[idx] = now - timestamp timestamp = now idx += 1 val = 1 - val unchanged = 0 else: unchanged += 1 pin.init(Pin.OUT, Pin.PULL_DOWN) if idx != EXPECTED_PULSES: raise InvalidPulseCount( "Expected {} but got {} pulses".format(EXPECTED_PULSES, idx) ) return transitions[4:] def _convert_pulses_to_buffer(self, pulses): """Convert a list of 80 pulses into a 5 byte buffer The resulting 5 bytes in the buffer will be: 0: Integral relative humidity data 1: Decimal relative humidity data 2: Integral temperature data 3: Decimal temperature data 4: Checksum """ # Convert the pulses to 40 bits binary = 0 for idx in range(0, len(pulses), 2): binary = binary << 1 | int(pulses[idx] > HIGH_LEVEL) # Split into 5 bytes buffer = array.array("B") for shift in range(4, -1, -1): buffer.append(binary >> shift * 8 & 0xFF) return buffer def _verify_checksum(self, buffer): # Calculate checksum checksum = 0 for buf in buffer[0:4]: checksum += buf if checksum & 0xFF != buffer[4]: raise InvalidChecksum()
補足情報(FW/ツールのバージョンなど)
・ macOS
・ VScode
・ Python
・ RaspberryPi pico