125 lines
3.6 KiB
C
125 lines
3.6 KiB
C
#include <sys/time.h>
|
|
|
|
/* ESP drivers */
|
|
#include "driver/i2c.h"
|
|
#include "esp_log.h"
|
|
#include "esp_system.h"
|
|
|
|
/* FreeRTOS */
|
|
#include "freertos/FreeRTOS.h"
|
|
#include "freertos/task.h"
|
|
|
|
/* MQTT */
|
|
#include "app_mqtt.h"
|
|
|
|
/* AHT10 */
|
|
#include "aht10/aht10.h"
|
|
|
|
/* Log tag */
|
|
#define APP_LOG_TAG "APP_DHT"
|
|
|
|
/* Configurations */
|
|
#define APP_DHT_I2C_SCL_IO CONFIG_APP_I2C_SCL_PIN
|
|
#define APP_DHT_I2C_SDA_IO CONFIG_APP_I2C_SDA_PIN
|
|
#define APP_DHT_I2C_INSTANCE 0
|
|
#define APP_DHT_I2C_TIMEOUT 100
|
|
#define APP_DHT_AHT10_ADDR 0x38
|
|
|
|
#define INFLUX_TOPIC "iot/metric"
|
|
#define INFLUX_HOSTNAME "DHT_Temp"
|
|
#define INFLUX_FORMATTED_STRING \
|
|
"dht,hostname=" INFLUX_HOSTNAME \
|
|
" " \
|
|
"temperature=%.02lf," \
|
|
"humidity=%.02lf" \
|
|
" " \
|
|
"%llu"
|
|
|
|
static void app_dht_task(void *pvParameters);
|
|
static uint64_t app_get_nsec_timestamp(void);
|
|
static aht10_ret_t app_dht_impl_xfer(void *pdev, aht10_xfer_desc_t *xfer);
|
|
static aht10_ret_t app_dht_impl_delay(void *pdev, uint32_t delay_msec);
|
|
|
|
esp_err_t app_dht_init(void) {
|
|
i2c_config_t cfg = {
|
|
.mode = I2C_MODE_MASTER,
|
|
.sda_io_num = APP_DHT_I2C_SDA_IO,
|
|
.scl_io_num = APP_DHT_I2C_SCL_IO,
|
|
.sda_pullup_en = GPIO_PULLUP_DISABLE,
|
|
.scl_pullup_en = GPIO_PULLUP_DISABLE,
|
|
.master.clk_speed = 400000,
|
|
};
|
|
|
|
i2c_param_config(APP_DHT_I2C_INSTANCE, &cfg);
|
|
|
|
if (i2c_driver_install(APP_DHT_I2C_INSTANCE, cfg.mode, 0U, 0U, 0U) != ESP_OK) {
|
|
return ESP_FAIL;
|
|
}
|
|
|
|
if (xTaskCreate(app_dht_task, "DHT_TASK", 2048, NULL, 1U, NULL) != pdPASS) {
|
|
return ESP_FAIL;
|
|
}
|
|
|
|
return ESP_OK;
|
|
}
|
|
|
|
static void app_dht_task(void *pvParameters) {
|
|
aht10_t aht = {
|
|
.cb =
|
|
{
|
|
.xfer = app_dht_impl_xfer,
|
|
.delay = app_dht_impl_delay,
|
|
},
|
|
};
|
|
|
|
aht10_init(&aht);
|
|
|
|
aht10_result_t result;
|
|
char report_buf[256];
|
|
uint64_t ns_ts;
|
|
|
|
for (;;) {
|
|
aht10_measure(&aht, &result);
|
|
ns_ts = app_get_nsec_timestamp();
|
|
|
|
/* Simple check to see if NTP is synchronized... */
|
|
if (ns_ts > (uint64_t)(1600000000L) * 1000000000) {
|
|
snprintf(report_buf, 256, INFLUX_FORMATTED_STRING, result.temperature, result.humidity, ns_ts);
|
|
app_mqtt_publish(INFLUX_TOPIC, report_buf);
|
|
}
|
|
vTaskDelay(pdMS_TO_TICKS(500));
|
|
}
|
|
}
|
|
|
|
static uint64_t app_get_nsec_timestamp(void) {
|
|
struct timeval tv_now;
|
|
gettimeofday(&tv_now, NULL);
|
|
int64_t time_ns = (int64_t)tv_now.tv_sec * 1000000000L + (int64_t)tv_now.tv_usec * 1000;
|
|
return time_ns;
|
|
}
|
|
|
|
static aht10_ret_t app_dht_impl_xfer(void *pdev, aht10_xfer_desc_t *xfer) {
|
|
esp_err_t ret;
|
|
if (xfer->rx_size == 0) {
|
|
ret = i2c_master_write_to_device(APP_DHT_I2C_INSTANCE, APP_DHT_AHT10_ADDR, xfer->tx_data, xfer->tx_size,
|
|
pdMS_TO_TICKS(APP_DHT_I2C_TIMEOUT));
|
|
} else if (xfer->tx_size == 0) {
|
|
ret = i2c_master_read_from_device(APP_DHT_I2C_INSTANCE, APP_DHT_AHT10_ADDR, xfer->rx_data, xfer->rx_size,
|
|
pdMS_TO_TICKS(APP_DHT_I2C_TIMEOUT));
|
|
} else {
|
|
ret = i2c_master_write_read_device(APP_DHT_I2C_INSTANCE, APP_DHT_AHT10_ADDR, xfer->tx_data, xfer->tx_size,
|
|
xfer->rx_data, xfer->rx_size, pdMS_TO_TICKS(APP_DHT_I2C_TIMEOUT));
|
|
}
|
|
|
|
if (ret != ESP_OK) {
|
|
return AHT10_FAIL;
|
|
}
|
|
|
|
return AHT10_OK;
|
|
}
|
|
|
|
static aht10_ret_t app_dht_impl_delay(void *pdev, uint32_t delay_msec) {
|
|
vTaskDelay(pdMS_TO_TICKS(delay_msec));
|
|
|
|
return AHT10_OK;
|
|
} |