-
Notifications
You must be signed in to change notification settings - Fork 5
/
aht20.ex
119 lines (102 loc) · 2.98 KB
/
aht20.ex
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
defmodule NervesjpBasis.Sensor.Aht20 do
@moduledoc """
Documentation for `Aht20`.
温湿度センサAHT20の制御モジュール
"""
# 関連するライブラリを読み込み
require Logger
use Bitwise
alias Circuits.I2C
# 定数
## i2c-1 for Raspberry Pi, i2c-2 for BBB/BBG Board
@i2c_bus "i2c-1"
## AHT32 I2C Addr
@i2c_addr 0x38
# 定数
## I2C通信待機時間(ms)
## (50msくらいまでOK。40ms以下になると測定に失敗する)
@i2c_delay 100
## 換算定数の事前計算
@two_pow_20 :math.pow(2, 20)
@doc """
温度を表示
## Examples
iex> Aht20.print_temp
> temp (degree Celsius)
22.1
:ok
"""
def print_temp() do
IO.puts(" > temp: #{temp()} (degree Celsius)")
end
# 温度の値を取得
defp temp do
# AHT20から読み出し
{:ok, {temp, _}} = read_from_aht20()
temp
end
@doc """
湿度を表示
## Examples
iex> Aht20.print_humi
> humi (%)
41.2
:ok
"""
def print_humi() do
IO.puts(" > humi: #{humi()} (%)")
end
# 湿度の値を取得
defp humi do
# AHT20から読み出し
{:ok, {_, humi}} = read_from_aht20()
humi
end
@doc """
AHT20から温度・湿度を取得
## Examples
iex> Aht20.read_from_ath20
{:ok, {22.4, 40.3}}
{:error, "Sensor is not connected"}
"""
def read_from_aht20() do
# I2Cを開く
{:ok, ref} = I2C.open(@i2c_bus)
# AHT20を初期化する
I2C.write(ref, @i2c_addr, <<0xBE, 0x08, 0x00>>)
# 処理完了まで一定時間待機
Process.sleep(@i2c_delay)
# 温度・湿度を読み出しコマンドを送る
I2C.write(ref, @i2c_addr, <<0xAC, 0x33, 0x00>>)
# 処理完了まで一定時間待機
Process.sleep(@i2c_delay)
# 温度・湿度を読み出す
ret =
case I2C.read(ref, @i2c_addr, 7) do
# 正常に値が取得できたときは温度・湿度の値をタプルで返す
{:ok, val} -> {:ok, val |> convert()}
# センサからの応答がないときはメッセージを返す
{:error, :i2c_nak} -> {:error, "Sensor is not connected"}
# その他のエラーのときもメッセージを返す
_ -> {:error, "An error occurred"}
end
# I2Cを閉じる
I2C.close(ref)
# 結果を返す
ret
end
#生データを温度と湿度の値に変換
## Parameters
## - val: POSTする内容
defp convert(src) do
# バイナリデータ部をビット長でパターンマッチ
# <<0:state, 1:humi1, 2:humi2, 3:humi3/temp1, 4:temp2, 5:temp3, 6:crc>>
<<_state::8, raw_humi::20, raw_temp::20, _crc::8>> = src
# 湿度に換算する計算(データシートの換算方法に準じた)
humi = Float.round(raw_humi / @two_pow_20 * 100.0, 1)
# 温度に換算する計算(データシートの換算方法に準じた)
temp = Float.round(raw_temp / @two_pow_20 * 200.0 - 50.0, 1)
# 温度と湿度をタプルにして返す
{temp, humi}
end
end