OrangePi-PCを使ってみる

Python GPIOライブラリ その3

こ ちらにorangepi_PC_gpio_pyH3ライブラリを使って、DHT11の温度・湿度計から、湿度と温度をとりだす方法が 紹介さ れています。
公開されている「dht11_example.py」を使うと、一発で温度と湿度を取り出すことができます。


DHT11は少し変わったI/Fを持つモジュールです。
そこで、これだけでは面白くないので、プログラム中にコードを追加して、どのようにデータを取り出すのか調べてみました。

len(data)= 647
len(pull_up_lengths)= 40
[4, 3, 10, 3, 10, 11, 3, 4, 4, 4, 4, 3, 4, 4, 3, 3, 4, 3, 4, 11, 10, 11, 10, 4, 4, 3, 3, 4, 4, 3, 3, 4, 4, 11, 4, 4, 11, 4, 10, 4]
[False, False, True, False, True, True, False, False, False, False, False, False, False, False, False, False, False, False, False, True, True, True, True, False, False, False, False, False, False, False, False, False, False, True, False, False, True, False, True, False]
0x2c 0x0 0x1e 0x0 0x4a
Last valid input: 2017-07-31 13:00:44.233506
Temperature: 30 C
Humidity: 44 %

上にあるのがプログラム中にコードを追加した時の出力です。
これでは何のことか分からないので、少し解説を加えます。
len(data)= 647
ディジタル入力で647個のデータを入力しています。
データの中身はディジタル値(1 or 0)で、647個の0/1がずらずらと並んでいます。
同じ値(正確には1が)100回連続するとデータの終了と判断しています。

len(pull_up_lengths)= 40
[4, 3, 10, 3, 10, 11, 3, 4, 4, 4, 4, 3, 4, 4, 3, 3, 4, 3, 4, 11, 10, 11, 10, 4, 4, 3, 3, 4, 4, 3, 3, 4, 4, 11, 4, 4, 11, 4, 10, 4]
LOW(=0)が1回でも出現するまで、何回HIGHが連続するかを数えます。
上の例では以下のようなデータになっています。
HHHH      HHH     HHHHHHHHHH      HHH     HHHHHHHHHH     HHHHHHHHHHH
    L....L   L...L          L....L   L...L          L...L           L...L
ここでのLOWはデータの区切りを示しているだけで、連続する個数は意味が有りません。

次に、Hが続く個数の最大個数と最小個数を求め、その平均値を求めます。
最大個数→11
最小個数→3
平均を求める
3 + (11 - 3) / 2 =
3 + 8 / 2 =
3 + 4 = 7

[False, False, True, False, True, True, False, False, False, False, False, False, False, False, False, False, False, False, False, True, True, True, True, False, False, False, False, False, False, False, False, False, False, True, False, False, True, False, True, False]
上記の7を閾値としてHIGHの連続個数をTrue/Falseに変換します。
連続個数が7を超えるとき→True
それ以外→False
[4, 3, 10, 3, 10, 11, 3, 4.... → F, F, T, F, T, T, F, F.....

True/Falseを8個ごとに分解します。
@False, False, True, False, True, True, False, False,
AFalse, False, False, False, False, False, False, False,
BFalse, False, False, True, True, True, True, False,
CFalse, False, False, False, False, False, False, False,
DFalse, True, False, False, True, False, True, False

これをTrue→1 False→0として16進に変換します。
@00101100 = 0x2c
A00000000 = 0x00
B00011110 = 0x1e
C00000000 = 0x00
D01001010 = 0x4a

@からCのCheckSumを計算します。
(0x2c + 0x00 + 0x1e + 0x00) & 0xFF = 0x4a
Dと一致するのでデータは正常です。

0x2c 0x0 0x1e 0x0 0x4a

DHT11は8ビットの分解能なのでACは常に0です。
0x2c = 44 → 湿度
0x1e = 30 → 温度

Last valid input: 2017-07-31 13:00:44.233506
Temperature: 30 C
Humidity: 44 %

データシートによると、HIGHが26から28μ秒続く時は0、HIGHが70μ秒続く時は1となっています。
上の例ではHIGHの最小個数は3個なので、8μ秒間隔程度でデータをサンプリングしています。
別の処理でCPUが忙しくて、28μ秒以内にデータをサンプリングできないときは正しくデータをとれません。
リアルタイムOSではないLinuxではあまりお勧めできないI/Fです。
BMP085/180/280やLM75のディジタル温度計を使った方が安定してデータを取れます。

分解能が16ビットのDHT22も基本同じですが、ACの部分が有効となり、10倍の整数値が戻ります。
DHT22の場合はこち らのコードを使います。

次回はOPi.GPIOライブラリを紹介します。