RHT data reads and reporting humidity
authorjweigele <jweigele@local>
Sat, 13 Apr 2024 01:44:35 +0000 (18:44 -0700)
committerjweigele <jweigele@local>
Sat, 13 Apr 2024 01:44:35 +0000 (18:44 -0700)
 * Also reads temp, but not reporting that just because it's so
   different from the current sensors we have?? why??
 * Lots of debug info for now, probably best to clean up
 * Unknown if regular temp still works since I refactored a bunch of
   functions

aqi/main/Kconfig
aqi/main/aqi.c
aqi/main/aqi.h

index 308e35817821590bc90e546b0561fb6ee2c25638..9b75c4285c30a039e3de62f83146e81103220a06 100644 (file)
@@ -41,6 +41,25 @@ config AQI_RX_PIN
     help
       Gets passed and used later for includes
 
+config RHT_ENABLED
+    bool "Fetch and report humidity + temp from RHT sensor?"
+    default n
+
+config RHT_SCL_PIN
+    int "RHT I2C clock pin"
+    depends on RHT_ENABLED
+    default 0
+
+config RHT_SDA_PIN
+    int "RHT I2C SDA PIN"
+    depends on RHT_ENABLED
+    default 0
+
+config RHT_ADDRESS
+    int "RHT I2C address in hex"
+    depends on RHT_ENABLED
+    default "68"
+
 config CO2_PWM_ENABLED
     bool "Fetch and report CO2 from PWM?"
     default n
index dc7ddf3dda742a05678c32b833f5207505f439aa..b27f5b46c0258bcbfbd494a7555c1bcb44e818b1 100644 (file)
@@ -49,7 +49,10 @@ typedef struct report_data_s {
 #if defined(CONFIG_CO2_UART_ENABLED) || defined(CONFIG_CO2_PWM_ENABLED)
   int16_t co2_ppm;
 #endif
-#ifdef CONFIG_TEMP_ENABLED
+#ifdef CONFIG_RHT_ENABLED
+  float humidity;
+#endif
+#if defined(CONFIG_TEMP_ENABLED) || defined(CONFIG_RHT_ENABLED)
   uint16_t temperature;
 #endif
 #if defined(CONFIG_MOTION_FIRST_ENABLED) || defined(CONFIG_MOTION_SECOND_ENABLED)
@@ -93,12 +96,18 @@ static QueueHandle_t pwm_queue;
 // for tracking and reporting device uptime
 static uint32_t device_uptime_seconds = 0;
 
-#ifdef CONFIG_TEMP_ENABLED
+#if defined(CONFIG_TEMP_ENABLED) || defined(CONFIG_RHT_ENABLED)
 
 static int tempbuffer[TEMPBUFFERSIZE];
 static int tempbufferindex = 0;
-static OW ow;
+#endif
 
+#ifdef CONFIG_RHT_ENABLED
+static i2c_master_dev_handle_t rht_handle;
+#endif
+
+#ifdef CONFIG_TEMP_ENABLED
+static OW ow;
 #endif
 
 #ifdef CONFIG_LED_ENABLED
@@ -461,9 +470,10 @@ void init_led(){
 
 #endif
 
+
 #ifdef CONFIG_TEMP_ENABLED
 
-bool init_temp(){
+bool init_temp_ow(){
     bool err = ow_init(&ow, CONFIG_TEMP_PIN);
     if (err){
         ESP_LOGI(TAG, "there was an error initing ow");
@@ -471,51 +481,11 @@ bool init_temp(){
     return err;
 }
 
-int new_temp_average(short new_val){
-    tempbuffer[tempbufferindex++] = new_val;
-    // rollover
-    if (tempbufferindex == TEMPBUFFERSIZE){
-        tempbufferindex = 0;
-    }
-
-    int total = 0;
-    int count = 0;
-    for (int i = 0; i < TEMPBUFFERSIZE; i++ ){
-        // ignore invalid
-        if ( tempbuffer[i] != 0x8000 ){
-            if (tempbuffer[i] > MIN_TEMP_VALUE && tempbuffer[i] < MAX_TEMP_VALUE){
-                total += tempbuffer[i];
-                count++;
-            } else {
-                ESP_LOGW(TAG, "temp value outside configured range, ignoring (value: %d min: %d max: %d)",
-                        tempbuffer[i], MIN_TEMP_VALUE, MAX_TEMP_VALUE);
-            }
-        }
-    }
-    int retval;
-    // we should only get here if all values are added are 0x8000 (aka no read)
-    // but it's still important to fill out just so we don't crash
-    // mainly, when ds18b20 is not connected or sensing properly
-    if (count == 0){
-        retval = 0x8000;
-    } else {
-        retval = (int)(total/count);
-    }
-    ESP_LOGI(TAG, "returning average temp to send: %d", retval);
-    return retval;
-
-}
-
-void init_tempbuffer(){
-    for (int i = 0; i < TEMPBUFFERSIZE; i++){
-        tempbuffer[i] = 0x8000;
-    }
-}
 
 // fetches temperature from any attached ds18b20 devices
 // returns as value * 100 (so that we can get 2 decimal places by later /100
 // without dealing with float nonsense now)
-static short get_temp(){
+static short get_temp_ow(){
     if (ow_reset (&ow)) {
         // scan bus for devices
         uint64_t romcode[MAXDEVS];
@@ -554,7 +524,155 @@ static short get_temp(){
     }
 }
 
+#endif
+
+#ifdef CONFIG_RHT_ENABLED
+
+bool init_rht(){
+    report_data.humidity = 0;
+    i2c_master_bus_config_t i2c_mst_config = {
+        .clk_source = I2C_CLK_SRC_DEFAULT,
+        .i2c_port = 0,
+        .scl_io_num = CONFIG_RHT_SCL_PIN,
+        .sda_io_num = CONFIG_RHT_SDA_PIN,
+        .glitch_ignore_cnt = 0,
+        .flags.enable_internal_pullup = false, //true,
+    };
+
+    i2c_master_bus_handle_t bus_handle;
+    ESP_ERROR_CHECK(i2c_new_master_bus(&i2c_mst_config, &bus_handle));
+
+    esp_err_t check = i2c_master_probe(bus_handle, CONFIG_RHT_ADDRESS, -1);
+    if (check != ESP_OK){
+        ESP_LOGE(TAG, "unable to find RHT device at address 0x%02x, error!", CONFIG_RHT_ADDRESS);
+        return false;
+    }
+
+    ESP_LOGI(TAG, "i2c RHT sensor found at address 0x%02x", CONFIG_RHT_ADDRESS);
+
+    i2c_device_config_t dev_cfg = {
+        .dev_addr_length = I2C_ADDR_BIT_LEN_7,
+        .device_address = CONFIG_RHT_ADDRESS,
+        .scl_speed_hz = 400000,
+    };
+
+    ESP_ERROR_CHECK(i2c_master_bus_add_device(bus_handle, &dev_cfg, &rht_handle));    
+    return true;
+    
+}
+
+
+static short get_data_rht(){
+    uint8_t send_cmd[1] = CMD_HIGH_PRECISION_READ;
+    uint8_t buf[8];
+    memset(buf, 0, 8);
+
+    ESP_LOGI(TAG, "fetching rht data");
+    //ESP_ERROR_CHECK(i2c_master_transmit_receive(rht_handle, send_cmd, 2, buf, 6, -1));
+    esp_err_t tx_check = i2c_master_transmit(rht_handle, send_cmd, sizeof(send_cmd), -1);
+    ESP_LOGE(TAG, "i2c transmit status is %s", esp_err_to_name(tx_check));
+    if (tx_check != ESP_OK){
+        return -1;
+    }    
+    // delay to allow measurement time to finish
+    vTaskDelay( pdMS_TO_TICKS(10) );    
+    esp_err_t rx_check = i2c_master_receive(rht_handle, buf, 6, -1);
+    ESP_LOGE(TAG, "i2c receive status is %s", esp_err_to_name(rx_check));
+    if (rx_check != ESP_OK){
+        return -1;
+    }
+
 
+    ESP_LOG_BUFFER_HEXDUMP(TAG, buf, sizeof(buf), ESP_LOG_INFO);
+
+    uint16_t sensor_data_temp = (buf[0] << 8) | buf[1];
+    float sensor_temp = (-49+(175 * (sensor_data_temp/65535.0)));
+    ESP_LOGI(TAG, "i2c sensor temp %f", sensor_temp);
+    uint16_t sensor_data_rh = (buf[3] << 8) | buf[4];
+    float sensor_rh = (-6 + (125 * (sensor_data_rh/65535.0)));
+    ESP_LOGI(TAG, "i2c sensor rh %f", sensor_rh);
+
+    // doesn't really matter when we start the counting loop, so just block until we have the semaphore
+    // (should only be unavailable if another task is updating, or more likely we're generating the report)
+    xSemaphoreTake(report_data.mutex, portMAX_DELAY);
+    report_data.humidity = sensor_rh;
+    xSemaphoreGive(report_data.mutex);
+    
+    
+    return -1;
+
+}
+#endif
+
+#if defined(CONFIG_TEMP_ENABLED) || defined(CONFIG_RHT_ENABLED)
+
+short get_temp(){
+#ifdef CONFIG_TEMP_ENABLED
+    return get_temp_ow();
+#endif
+#ifdef CONFIG_RHT_ENABLED
+    return get_data_rht();
+#endif
+}
+
+bool init_temp(){
+    // initialize one wire temperature if enabled
+#ifdef CONFIG_TEMP_ENABLED
+    if (!init_temp_ow()){
+        return false;
+    }
+#endif    
+    // initialize RHT if enabled
+#ifdef CONFIG_RHT_ENABLED
+    if (!init_rht()){
+        return false;
+    }
+#endif
+    // all configured sensors init
+    ESP_LOGI(TAG, "temperature init successfully!");
+    return true;
+}
+
+int new_temp_average(short new_val){
+    tempbuffer[tempbufferindex++] = new_val;
+    // rollover
+    if (tempbufferindex == TEMPBUFFERSIZE){
+        tempbufferindex = 0;
+    }
+
+    int total = 0;
+    int count = 0;
+    for (int i = 0; i < TEMPBUFFERSIZE; i++ ){
+        // ignore invalid
+        if ( tempbuffer[i] != 0x8000 ){
+            if (tempbuffer[i] > MIN_TEMP_VALUE && tempbuffer[i] < MAX_TEMP_VALUE){
+                total += tempbuffer[i];
+                count++;
+            } else {
+                ESP_LOGW(TAG, "temp value outside configured range, ignoring (value: %d min: %d max: %d)",
+                        tempbuffer[i], MIN_TEMP_VALUE, MAX_TEMP_VALUE);
+            }
+        }
+    }
+    int retval;
+    // we should only get here if all values are added are 0x8000 (aka no read)
+    // but it's still important to fill out just so we don't crash
+    // mainly, when ds18b20 is not connected or sensing properly
+    if (count == 0){
+        retval = 0x8000;
+    } else {
+        retval = (int)(total/count);
+    }
+    ESP_LOGI(TAG, "returning average temp to send: %d", retval);
+    return retval;
+
+}
+
+void init_tempbuffer(){
+    for (int i = 0; i < TEMPBUFFERSIZE; i++){
+        tempbuffer[i] = 0x8000;
+    }
+}
 #endif
 // most conditional stuff done by now
 
@@ -931,6 +1049,13 @@ static void send_report_summary(report_data_t report_data){
     cJSON_AddNumberToObject(root, "pm25", ((float)report_data.pm25/100));
     cJSON_AddNumberToObject(root, "aqi", report_data.aqi);
 #endif    
+#ifdef CONFIG_RHT_ENABLED
+    char* rh = malloc(10);
+    memset(rh, 0, 10);
+    snprintf(rh, 10, "%.02f", report_data.humidity);
+    cJSON_AddStringToObject(root, "rh",  rh);
+    free(rh);
+#endif
 #if defined(CONFIG_CO2_UART_ENABLED) || defined(CONFIG_CO2_PWM_ENABLED)
 
     // -1 is what we use for errors, 0 seems to be the device just isn't yet init
@@ -1436,7 +1561,7 @@ static void motion_task(void* discard){
 static void monitoring_task(void* discard)
 {
 
-#ifdef CONFIG_TEMP_ENABLED
+#if defined(CONFIG_TEMP_ENABLED) || defined(CONFIG_RHT_ENABLED)
     short temp_avg = 0;
     init_temp();
 #endif
@@ -1537,7 +1662,7 @@ static void monitoring_task(void* discard)
         }
 #endif // end CO2 UART section
 
-#ifdef CONFIG_TEMP_ENABLED
+#if defined(CONFIG_TEMP_ENABLED) || defined(CONFIG_RHT_ENABLED)
         // Temperature fetch/calculation/report
         temp_avg = new_temp_average(get_temp());
         xSemaphoreTake(report_data.mutex, portMAX_DELAY);
index 138931079b3283b51032f23bb363f92e375fa43a..57e1a45edf3e336ab1a5b7669e29ff741adf98a1 100644 (file)
@@ -102,10 +102,18 @@ static const char *TAG = "aqi";
 
 #ifdef CONFIG_TEMP_ENABLED
 #include "onewire.h"
+#endif
+#if defined(CONFIG_TEMP_ENABLED) || defined(CONFIG_RHT_ENABLED)
 #define MIN_TEMP_VALUE -5500
 #define MAX_TEMP_VALUE 12500
 #endif
 
+
+#ifdef CONFIG_RHT_ENABLED
+#include "driver/i2c_master.h"
+#define CMD_HIGH_PRECISION_READ {0xFD}
+#endif
+
 #ifdef CONFIG_CO2_UART_ENABLED
 // 8 bytes + 1 checksum, defined by manufacturer
 // we should expect 9 bytes in return