質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

Raspberry Pi

Raspberry Piは、ラズベリーパイ財団が開発した、名刺サイズのLinuxコンピュータです。 学校で基本的なコンピュータ科学の教育を促進することを意図しています。

IoT

IoT(Internet of Things)とは、インターネットがコンピュータなどの情報・通信機器のネットワークだけでなく、世の中のある様々なモノに接続されて自動認識・自動制御・遠隔計測などの能力を備えることです。「モノのインターネット」と一般的にいわれます。

Q&A

1回答

3789閲覧

RaspberryPi picoのデバイス制作にて、模倣したPythonコードで不具合が発生した。

Yuji_222

総合スコア0

Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

Raspberry Pi

Raspberry Piは、ラズベリーパイ財団が開発した、名刺サイズのLinuxコンピュータです。 学校で基本的なコンピュータ科学の教育を促進することを意図しています。

IoT

IoT(Internet of Things)とは、インターネットがコンピュータなどの情報・通信機器のネットワークだけでなく、世の中のある様々なモノに接続されて自動認識・自動制御・遠隔計測などの能力を備えることです。「モノのインターネット」と一般的にいわれます。

0グッド

0クリップ

投稿2021/09/08 10:03

編集2021/09/10 02:13

前提・実現したいこと

文系学生が、趣味でラズパイを弄り始めておそらく初歩的なミスを犯しました。

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

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

coco_bauer

2021/09/08 12:03

「DHT11の部分に赤波線が現れ、正常にプログラムが作動しません」というのは、どんなプログラムで何をした時に起きたのですか? 作ったプログラムを質問に追加して下さい。 「AttributeError: 'DHT11' object has no attribute '_convert_pulses_to_buffer'」というエラーメッセージが出るプログラムも、質問に追加して下さい。現状の質問のプログラムには”_convert_pulses_to_buffer”という文字列が含まれていません。エラーが起きたプログラム全体を質問に追加して下さい。 プログラムを見ないで、何が問題で、どうすれば改良できるのかを判る人は居ないですよ。
thkana

2021/09/08 22:59

pythonでインデントが失われるのは致命的です。ヘルプ https://teratail.com/help/question-tips#questionTips3-5-1 などをみてコードとして表示されるようにしてください。 > 以下のサイトのコードをほとんどそのまま用いて もとのコードそのままでエラーは発生しますか? どこを変えたか、なぜ変えたかの説明をしてください。
Yuji_222

2021/09/10 02:18

@coco_bauer様 ご指摘ありがとうございます。 先ほど、コピープログラムとエラ〜メッセージが出るプログラムの2つを追加し更新させていただきました。 初めての質問のため、ご迷惑をおかけしております。申し訳ありません。
thkana

2021/09/10 02:33

もとのコードそのままでエラーは発生しますか? (むしろ、編集前に「参照している」としたページのコードではどうなりますか、と聞いたほうがいいのかしら) ソースコードとエラーメッセージとの対応が変です。エラーメッセージは状況を読み解くための**大変重要な**情報です。誤った情報を提示されると解ける問題も解けなくなることもありますので注意してください。 エラーメッセージからは、mainの10行目から呼ばれたDHT11.temperature()からDHT11.measure()が呼ばれ、その中でエラーが起こった...と読み取れますが、ソースでは10行目はsleep(2)です。修正前でもsensor.measure()でしたので、temperature()関数は呼ばれません。なぜここにtemerature()関数が絡んでくるのかしら??? また、コードが意図通りに動いているなら、DHT11.measure()が連続して呼ばれると測定を行わずにreturnすることになっていますから、 sensor.measure() temp=sensor.temperature() と連続して呼び出されたらtemperature()関数経由で呼び出されるmeasure()関数内では_convert_pulses_to_bufferの呼び出しに到達しないはずなのですが。 単純にdht.pyの取り込みに失敗しているのなら、冒頭のimport dhtやsensor = dht.DHT11(Pin(28))でエラーになるはずですから、そういうことではなさそうに思います。
Yuji_222

2021/09/10 02:40

@thkana様 ご指摘ありがとうございます。 コードを添付する位置を誤っており、インデントが崩壊していたようです。 先ほど修正し、更新させていただきました。
thkana

2021/09/10 02:51

もとのコードそのままでエラーは発生しますか? (むしろ、編集前に「参照している」としたページのコードではどうなりますか、と聞いたほうがいいのかしら) > 先ほど修正し、更新 つまり、現時点で質問にあるソースコードを実行すると、質問にあるエラーメッセージが出る、ということですか? そうなると難しいですね...不可思議。
guest

回答1

0

質問文中に参考サイトのURLがふたつ記載されていました。前者は質問文の編集によってすでに削除されているもの、後者は編集によって追加されたものです。

いずれのサイトでも dht ライブラリをインポートして使用していますが、前者の dht ライブラリと後者の dht ライブラリは、名前は同じですが別のものです。

前者:

後者:

両者のライブラリは同じ名前ですがプログラムの書き方に互換性はありません。
前者のライブラリを使用してプログラムを書くときは、前者のサイトやリポジトリの README に記載されているプログラムを参考にしてください。measure()は実行する必要がないこと、temperaturehumidityはメソッドではなくプロパティであることに注意してください。

コンパイル済みモジュールのキャッシュディレクトリ(__pycache__) が作成されている場合は、このディレクトリを削除してから実行し直してください。

投稿2021/09/11 01:06

etherbeg

総合スコア1195

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問