Arduino MKR WiFi 1010をデータ入力に使う⑩I2C温湿度センサAHT20
DHT11などの湿度センサを作っているAosong(ASAIR)社のAHT20は、Sensirion SHTC3よりわずかに安価です。IC自体が3.3/5Vのどちらの電源でも使えるため、レベル変換回路は入っていません。Adafruit AHT20 Temperature & Humidity Sensorを利用しました。
●湿度センサAHT20のおもなスペック
- 電源電圧 2.0~5.5V
- 湿度 確度±2%RH、分解能0.024%RH
- 温度 確度±0.3℃、分解能0.01℃
- インターフェース I2C(0~400kHz)
- スレーブ・アドレス 0x38(固定)
●接続
I2C専用の4ピンのコネクタでArduino MKR WiFi 1010と接続します。第4回の気圧センサLPS25HBの接続と同じです。
●プログラム-step1
最初にInitilizationをし、次に測定のトリガをかけます。80ms待って7バイト読み出します。最初の1バイトはstateで、MSBがbusyフラグです。次の20ビットが湿度、残りの20ビットが温度、最後の1バイトがCRCです。
湿度と温度は全部で5バイトです。3バイト目の上位4ビットが湿度で、3バイト目の下位ビットが温度です。
clear all
a = arduino('COM15', 'MKR1010', 'Libraries', 'I2C');
aht20 = device(a, 'I2CAddress', 0x38)
Initilization = 0xbe;
dataI = [0x08,0x00];
writeRegister(aht20, Initilization, dataI, 'uint8')
pause(0.1);
trigger_measurement = 0xac;
dataM = [0x33,0x00];
writeRegister(aht20, trigger_measurement, dataM, 'uint8')
pause(0.1);
rdata = read(aht20, 7 ,'uint8')
humi_raw= bitshift(uint32(bitshift(rdata(2), 16)) + uint32(bitshift(rdata(3), 8)) + uint32(bitand(rdata(4),0xf0)),-4)
humi = double(humi_raw) / 1048576.0 *100
temp_raw = bitshift(uint32(bitand(rdata(4), 0x0f)), 16) + bitshift(uint32(rdata(5)), 8) + uint32(rdata(6))
temp = double(temp_raw) * 200 / 1048576 -50
実行結果です。
●プログラム-step2
CRCを求めます。SHTC3のときは、手計算でCRCを求める手順を実装しました。ここでは、いろいろなところでC言語でCRC-8の計算ルーチンで紹介されているプログラムを移植します。
データの数は任意です。テストは2個の場合、6個の場合の確認をしました。
%main
testdata = [28,165,222,70,53,100]
dec2hex(CalcCrc(testdata))
function [crcResult] = CalcCrc(data)
crc8A = 0xff;
for i = 1:length(data)
crc8A = bitxor(crc8A, data(i))
for bit = 8:-1:1
if bitand(crc8A, 0x80)
crc8A = bitxor(bitshift(crc8A , 1) , 0x31);
else
crc8A = bitshift(crc8A , 1);
end
end
end
crcResult = crc8A;
end
動作確認は、このサイトでもできます。
●プログラム-step3
読みだしたCRCと計算したCRCの値を比較します。計算するのは、最初のstateの1バイトと湿度と温度の5バイトの合計6バイトが対象です。
clear all
a = arduino('COM15', 'MKR1010', 'Libraries', 'I2C');
aht20 = device(a, 'I2CAddress', 0x38);
Initilization = 0xbe;
dataI = [0x08,0x00];
writeRegister(aht20, Initilization, dataI, 'uint8')
pause(0.1);
trigger_measurement = 0xac;
dataM = [0x33,0x00];
writeRegister(aht20, trigger_measurement, dataM, 'uint8');
pause(0.1);
rdata = read(aht20, 7 ,'uint8');
humi_raw= bitshift(uint32(bitshift(rdata(2), 16)) + uint32(bitshift(rdata(3), 8)) + uint32(bitand(rdata(4),0xf0)),-4)
humi = double(humi_raw) / 1048576.0 *100
temp_raw = bitshift(uint32(bitand(rdata(4), 0x0f)), 16) + bitshift(uint32(rdata(5)), 8) + uint32(rdata(6))
temp = double(temp_raw) * 200 / 1048576 -50
data = [rdata(1),rdata(2),rdata(3),rdata(4),rdata(5),rdata(6)]
fprintf('readCRC is 0x%s 0x%s <-calculated ',dec2hex(rdata(7)),dec2hex(CalcCrc(data)) );
function crcResult = CalcCrc(data)
crc8A = 0xff;
for i = 1:length(data)
crc8A = bitxor(crc8A, data(i));
for bit = 8:-1:1
if bitand(crc8A, 0x80)
crc8A = bitxor(bitshift(crc8A , 1) , 0x31);
else
crc8A = bitshift(crc8A , 1);
end
end
end
crcResult = crc8A;
end
実行例です。