diff --git a/_locales/ja/Grove-strings.json b/_locales/ja/Grove-strings.json index e259c7a..8b42b5d 100644 --- a/_locales/ja/Grove-strings.json +++ b/_locales/ja/Grove-strings.json @@ -20,5 +20,8 @@ "grove.TM1637.set|block": "%strip|[Grove - 4桁ディスプレイ]|明るさを|%level|に変更する", "grove.TM1637.bit|block": "%strip|[Grove - 4桁ディスプレイ]|%dispData|を|%bitAddr|桁目に表示する", "grove.TM1637.point|block": "%strip|[Grove - 4桁ディスプレイ]|コロンの表示を|%point|に変更する", - "grove.TM1637.clear|block": "%strip|[Grove - 4桁ディスプレイ]|表示を消す" -} \ No newline at end of file + "grove.TM1637.clear|block": "%strip|[Grove - 4桁ディスプレイ]|表示を消す", + "grove.aht20ReadTemperatureC|block": "[Grove - 温湿度センサー]|温度(℃)を読み取る", + "grove.aht20ReadTemperatureF|block": "[Grove - 温湿度センサー]|温度(℉)を読み取る", + "grove.aht20ReadHumidity|block": "[Grove - 温湿度センサー]|湿度を読み取る" +} diff --git a/blocks/GroveAHT20.ts b/blocks/GroveAHT20.ts new file mode 100644 index 0000000..a4ad5eb --- /dev/null +++ b/blocks/GroveAHT20.ts @@ -0,0 +1,71 @@ +/** + * Grove - AHT20 Custom Block + */ +//% groups=['AHT20'] +namespace grove +{ + function Read(aht20: grove.sensors.AHT20): { Humidity: number, Temperature: number } + { + if (!aht20.GetState().Calibrated) + { + aht20.Initialization(); + if (!aht20.GetState().Calibrated) return null; + } + + aht20.TriggerMeasurement(); + for (let i = 0; ; ++i) + { + if (!aht20.GetState().Busy) break; + if (i >= 500) return null; + basic.pause(10); + } + + return aht20.Read(); + } + + /** + * Read the temperature(°C) from Grove-AHT20(SKU#101990644) + */ + //% group="AHT20" + //% block="[Grove - Temp&Humi Sensor]|Read the temperature(°C))" + //% weight=3 + export function aht20ReadTemperatureC(): number + { + const aht20 = new grove.sensors.AHT20(); + const val = Read(aht20); + if (val == null) return null; + + return val.Temperature; + } + + /** + * Read the temperature(°F) from Grove-AHT20(SKU#101990644) + */ + //% group="AHT20" + //% block="[Grove - Temp&Humi Sensor]|Read the temperature(°F))" + //% weight=2 + export function aht20ReadTemperatureF(): number + { + const aht20 = new grove.sensors.AHT20(); + const val = Read(aht20); + if (val == null) return null; + + return val.Temperature * 9 / 5 + 32; + } + + /** + * Read the humidity from Grove-AHT20(SKU#101990644) + */ + //% group="AHT20" + //% block="[Grove - Temp&Humi Sensor]|Read the humidity" + //% weight=1 + export function aht20ReadHumidity(): number + { + const aht20 = new grove.sensors.AHT20(); + const val = Read(aht20); + if (val == null) return null; + + return val.Humidity; + } + +} diff --git a/pxt.json b/pxt.json index 51bb30d..102c4ef 100644 --- a/pxt.json +++ b/pxt.json @@ -9,8 +9,10 @@ "files": [ "README.md", "main.ts", + "blocks/GroveAHT20.ts", "_locales/ja/Grove-strings.json", - "_locales/de/Grove-strings.json" + "_locales/de/Grove-strings.json", + "sensors/AHT20.ts" ], "testFiles": [ "test.ts" diff --git a/sensors/AHT20.ts b/sensors/AHT20.ts new file mode 100644 index 0000000..bcd311e --- /dev/null +++ b/sensors/AHT20.ts @@ -0,0 +1,87 @@ +namespace grove +{ + export namespace sensors + { + + export class AHT20 + { + public constructor(address: number = 0x38) + { + this._Address = address; + } + + public Initialization(): AHT20 + { + const buf = pins.createBuffer(3); + buf[0] = 0xbe; + buf[1] = 0x08; + buf[2] = 0x00; + pins.i2cWriteBuffer(this._Address, buf, false); + basic.pause(10); + + return this; + } + + public TriggerMeasurement(): AHT20 + { + const buf = pins.createBuffer(3); + buf[0] = 0xac; + buf[1] = 0x33; + buf[2] = 0x00; + pins.i2cWriteBuffer(this._Address, buf, false); + basic.pause(80); + + return this; + } + + public GetState(): { Busy: boolean, Calibrated: boolean } + { + const buf = pins.i2cReadBuffer(this._Address, 1, false); + const busy = buf[0] & 0x80 ? true : false; + const calibrated = buf[0] & 0x08 ? true : false; + + return { Busy: busy, Calibrated: calibrated }; + } + + public Read(): { Humidity: number, Temperature: number } + { + const buf = pins.i2cReadBuffer(this._Address, 7, false); + + const crc8 = AHT20.CalcCRC8(buf, 0, 6); + if (buf[6] != crc8) return null; + + const humidity = ((buf[1] << 12) + (buf[2] << 4) + (buf[3] >> 4)) * 100 / 1048576; + const temperature = (((buf[3] & 0x0f) << 16) + (buf[4] << 8) + buf[5]) * 200 / 1048576 - 50; + + return { Humidity: humidity, Temperature: temperature }; + } + + private _Address: number; + + private static CalcCRC8(buf: Buffer, offset: number, size: number): number + { + let crc8 = 0xff; + for (let i = 0; i < size; ++i) + { + crc8 ^= buf[offset + i]; + for (let j = 0; j < 8; ++j) + { + if (crc8 & 0x80) + { + crc8 <<= 1; + crc8 ^= 0x31; + } + else + { + crc8 <<= 1; + } + crc8 &= 0xff; + } + } + + return crc8; + } + + } + } +}