From: Not Zed Date: Sat, 9 Nov 2024 23:46:58 +0000 (+1030) Subject: Initial import. X-Git-Url: https://code.zedzone.au/cvs?a=commitdiff_plain;ds=inline;p=esp-aht30 Initial import. --- e1489d225c40d0a87e002c696e475951d00cfa2f diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..8648526 --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,3 @@ +idf_component_register(SRCS "esp-aht30.c" + INCLUDE_DIRS "include" + REQUIRES esp_driver_i2c) diff --git a/README b/README new file mode 100644 index 0000000..fec426e --- /dev/null +++ b/README @@ -0,0 +1,57 @@ + +Copyright (C) 2024 Michael Zucchi + +See the section LICENSE for details. + +Introduction +------------ + +esp-aht30 is an i2c driver for the ASAIR AHT30 temperature and +humidity sensor. + +Compile +------- + +This is an esp-idf component which needs to be copied to the +components directory of your project or otherwise referenced by the +esp-idf build system for your project. + +Then add REQUIRES esp-aht30 to idf_component_register() for the +project. + +Usage +----- + +See the header. + +Links +----- + +* browse source + source code + +* esp-idf + +* AHT30 + +LICENSE +------- + +This code is licensed under GNU General Public License version +3, see COPYING for the full details. + + Copyright (C) 2024 Michael Zucchi + + This program is free software: you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the + License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see + . diff --git a/esp-aht30.c b/esp-aht30.c new file mode 100644 index 0000000..a8c95f7 --- /dev/null +++ b/esp-aht30.c @@ -0,0 +1,60 @@ +#include + +#include "freertos/FreeRTOS.h" +#include "freertos/task.h" + +#include "esp-aht30.h" + +static const uint8_t aht30_update_seq[] = { 0xac, 0x33, 0x00 }; + +static uint8_t crc8(uint8_t *msg, size_t n) { + uint8_t crc = 0xff; + uint8_t *end = msg + n; + + while (msg < end) { + crc ^= *msg++; + for (int i=0;i<8;i++) { + if (crc & 0x80) + crc = (crc << 1) ^ 0x31; + else + crc = (crc << 1); + } + } + + return crc; +} + +esp_err_t aht30_init(i2c_master_bus_handle_t bus, const aht30_config_t *config, aht30_handle_t *aht) { + i2c_device_config_t i2c_dev_conf = { + .dev_addr_length = I2C_ADDR_BIT_LEN_7, + .device_address = AHT30_ADDR, + .scl_speed_hz = config ? config->scl_speed_hz : 400000, + .scl_wait_us = config ? config->scl_wait_us : 20000, + }; + + return i2c_master_bus_add_device(bus, &i2c_dev_conf, &aht->dev); +} + +esp_err_t aht30_delete(aht30_handle_t *aht) { + return i2c_master_bus_rm_device(aht->dev); +} + +esp_err_t aht30_read(aht30_handle_t *aht, aht30_reading_t *res) { + uint8_t data[7]; + + // request sensor update + ESP_ERROR_CHECK(i2c_master_transmit(aht->dev, aht30_update_seq, sizeof(aht30_update_seq), 500)); + + // delay required 80ms + vTaskDelay(80 / portTICK_PERIOD_MS); + + // poll result + ESP_ERROR_CHECK(i2c_master_receive(aht->dev, data, 7, 500)); + + res->status = data[0]; + res->valid = crc8(data, 6) == data[6]; + res->humidity = (data[1] << 12 | data[2] << 4 | data[3] >> 4) * 100; + res->temperature = ((data[3] << 16 | data[4] << 8 | data[5]) & 0xfffff) * 200 - (50 << 20); + + return 0; +} diff --git a/include/esp-aht30.h b/include/esp-aht30.h new file mode 100644 index 0000000..7f8331f --- /dev/null +++ b/include/esp-aht30.h @@ -0,0 +1,38 @@ +#ifndef ESP_AHT30_H +#define ESP_AHT30_H + +#include "driver/i2c_master.h" + +struct aht30_reading { + uint8_t status; + uint8_t valid; /* if crc check passed */ + int32_t temperature; /* deg C, fixed point 12.20 */ + uint32_t humidity; /* RH%, fixed point 12.20 */ +}; + +typedef struct aht30_reading aht30_reading_t; + +#define AHT30_ADDR (0x38) +#define AHT30_STATUS_BUSY 0x80 +#define AHT30_STATUS_CRC_PASSED 0x10 +#define AHT30_STATUS_CALIBRATED 0x08 + +struct aht30_config { + uint32_t scl_speed_hz; + uint32_t scl_wait_us; +}; + +typedef struct aht30_config aht30_config_t; + +struct aht30_handle { + i2c_master_dev_handle_t dev; +}; + +typedef struct aht30_handle aht30_handle_t; + +esp_err_t aht30_init(i2c_master_bus_handle_t bus, const aht30_config_t *config, aht30_handle_t *handle); +esp_err_t aht30_delete(aht30_handle_t *aht); + +esp_err_t aht30_read(aht30_handle_t *aht, aht30_reading_t *res); + +#endif