a few moderate changes
authorjweigele <jweigele@local>
Mon, 19 Feb 2024 21:39:56 +0000 (13:39 -0800)
committerjweigele <jweigele@local>
Mon, 19 Feb 2024 21:39:56 +0000 (13:39 -0800)
Features:
 * Support version string emission, once per hour to
   esp32/sensor_version
 * Set every PWM LED GPIO invididually if it's != -1 (now supports all 6
   channels)

Bugfix:
 * Never sleep negative time if you waited too long already (which since
   it's a uint I think just becomes very positive and sleeps almost
   forever)

Ehh:
 * Some attempted changes around repolling and rechecking motion
   settings
 * Pull-down back to enabled because we're using the big PIR sensors
 * Hysteresis enabled to prevent spamming of the channel

aqi/dependencies.lock
aqi/main/aqi.c
aqi/main/aqi.h
aqi/sdkconfig

index 03a995e342b28b1d307ac5125f4678ca6b71065b..fd71409715f791b2accabad79d6dacdf67193102 100644 (file)
@@ -10,6 +10,6 @@ dependencies:
     source:
       type: idf
     version: 5.2.0
-manifest_hash: 9370ef27f76f2bf2bf1ebd1e72c5af82f7b264148974987baedcb874f8fab004
+manifest_hash: fe84d3cba19d4dc50bbd18a9bed2d19eaa863b4be82668f06a4725d7b974e0c1
 target: esp32h2
 version: 1.0.0
index 1be28f03cffb22478b7aa78c83a16eb33edc53cb..148f0689f14f9c8b08347bc66284c79b381ab858 100644 (file)
@@ -48,6 +48,7 @@ typedef struct pwm_data_s {
 } pwm_data_t;
 #endif
 
+
 typedef struct report_data_s {
 #ifdef CONFIG_UART_ENABLED    
   uint16_t pm10;
@@ -69,9 +70,16 @@ typedef struct report_data_s {
 static temperature_sensor_handle_t temp_handle;
 static QueueHandle_t event_queue;
 static QueueHandle_t send_queue;
+static QueueHandle_t version_queue;
+
+static esp_app_desc_t app_desc;
+static char mac_string[12 + 1];
+static char ext_string[16 + 1];
 
 #if defined(CONFIG_MOTION_FIRST_ENABLED) || defined(CONFIG_MOTION_SECOND_ENABLED)
+static uint32_t squelch_time = 0;
 static QueueHandle_t motion_queue;
+static QueueHandle_t off_queue;
 static QueueHandle_t check_queue;
 
 static int prev_motion[2] = {0, 0};
@@ -301,6 +309,9 @@ static void create_config_network(otInstance *instance)
 
     memcpy(otExt, otLinkGetExtendedAddress(instance), 8);
 
+    sprintf(ext_string, "%02x%02x%02x%02x%02x%02x%02x%02x",
+            otExt[0], otExt[1], otExt[2], otExt[3], otExt[4], otExt[5], otExt[6], otExt[7]);
+
     /* Start the Thread network interface (CLI cmd > ifconfig up) */
     otIp6SetEnabled(instance, true);
 
@@ -363,19 +374,15 @@ static void ot_task_worker(void *aContext)
 
     //esp_err_t err_netif = esp_netif_get_mac(openthread_netif, ot_mac);
     esp_err_t err_netif = esp_base_mac_addr_get(ot_mac);
+    sprintf(mac_string, "%02x%02x%02x%02x%02x%02x", 
+            ot_mac[0], ot_mac[1], ot_mac[2], ot_mac[3], ot_mac[4], ot_mac[5]);
     ESP_LOGE(TAG, "error status is %s", esp_err_to_name(err_netif));
-    ESP_LOG_BUFFER_HEXDUMP(TAG, ot_mac, 6, ESP_LOG_INFO);
+    ESP_LOGI(TAG, "mac address is %s", mac_string);
 
     esp_openthread_lock_release();
 
-    //while (true) {
-        // Run the main loop
     esp_err_t err = esp_openthread_launch_mainloop();
     ESP_LOGE(TAG, "Error somewhere in openthread loop %s.", esp_err_to_name(err));
-      //  vTaskDelay( pdMS_TO_TICKS(10000) );
-
-    //}
-
 
     // Clean up
     esp_netif_destroy(openthread_netif);
@@ -621,11 +628,44 @@ void init_uart(void) {
     uart_set_pin(UART_NUM_1, UART_TX_GPIO, UART_RX_GPIO, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE);
 }
 
+static void version_task(void* discard){
+    // give 5 seconds before starting, just to allow all network vars to be populated
+    vTaskDelay( pdMS_TO_TICKS(5000) );
+
+    for (;;){
+        cJSON *root;
+        root = cJSON_CreateObject();
+        cJSON_AddStringToObject(root, "app_version", app_desc.version);
+        cJSON_AddStringToObject(root, "idf_version", app_desc.idf_ver);
+        cJSON_AddStringToObject(root, "mac", mac_string);
+#ifdef CONFIG_OT_ENABLED
+        cJSON_AddStringToObject(root, "ext", ext_string); 
+#endif
+        cJSON_AddStringToObject(root, "location", CONFIG_LOCATION);
+        char *mqtt_string = cJSON_Print(root);
+        xQueueSend(version_queue, &mqtt_string, portMAX_DELAY);
+        cJSON_Delete(root);
+
+        // wait an hour, then send again
+        vTaskDelay( pdMS_TO_TICKS(3600000) );
+    }
+}
+
+
 static void send_task(void* discard){
 
     char* mqtt_string = ""; //NULL;
     bool last_sent = false;
     for(;;){
+        // version string queue -> send on mqtt
+        if (netif_connected == true && mqtt_connected == true){
+            if (xQueueReceive(version_queue, &mqtt_string, 0 )){
+                ESP_LOGI(TAG, "sending version string:\n%s",mqtt_string);
+                int msg_id = esp_mqtt_client_publish(mqtt_client, "esp32/version_info", mqtt_string, 0, 1, 0);
+                ESP_LOGI(TAG, "sent publish successful, msg_id=%d", msg_id);
+                free(mqtt_string);
+            }                
+        }
         // receive an event we need to deal with from elsewhere, right now just reconnect related
         if (xQueueReceive(send_queue, &mqtt_string, portMAX_DELAY )){
             last_sent = true;
@@ -652,8 +692,11 @@ static void send_task(void* discard){
 
 
 #if defined(CONFIG_WIFI_ENABLED) || defined(CONFIG_OT_ENABLED)
+#if defined(CONFIG_MOTION_FIRST_ENABLED) || defined(CONFIG_MOTION_SECOND_ENABLED)
 static void send_report_motion(bool motion){
     xSemaphoreTake(report_data.mutex, portMAX_DELAY);
+    report_data.motion = motion;
+    xSemaphoreGive(report_data.mutex);
 
     ESP_LOGI(TAG, "send_report_motion was called!");
     cJSON *root;
@@ -663,10 +706,9 @@ static void send_report_motion(bool motion){
     char *mqtt_string = cJSON_Print(root);
     xQueueSend(send_queue, &mqtt_string, portMAX_DELAY);
     cJSON_Delete(root);
-
-    xSemaphoreGive(report_data.mutex);
     
 }
+#endif // CONFIG_MOTION_ENABLED
 
 static void send_report_wifi(report_data_t report_data){
     xSemaphoreTake(report_data.mutex, portMAX_DELAY);
@@ -702,7 +744,7 @@ static void send_report_wifi(report_data_t report_data){
 
 }
 
-#endif
+#endif // wifi or ot enabled
 
 bool verify_checksum(uint8_t* data){
     int total = 0;
@@ -826,31 +868,57 @@ static void pwm_task(void* discard){
     // Prepare and then apply the LEDC PWM channel configuration
     ledc_channel_config_t ledc_channel = {
         .speed_mode     = LEDC_MODE,
-        .channel        = R1_CHANNEL,
+        .channel        = LEDC_CHANNEL_0,
         .timer_sel      = LEDC_TIMER,
         .intr_type      = LEDC_INTR_DISABLE,
-        .gpio_num       = CONFIG_PWM_R1_GPIO,
+        .gpio_num       = 0,
         .duty           = 0, // Set duty to 0%
         .hpoint         = 0
     };
-    ESP_LOGI(TAG, "configuring R1 PWM");
-    ESP_ERROR_CHECK(ledc_channel_config(&ledc_channel));
 
 
-    ledc_channel.channel = G1_CHANNEL;
-    ledc_channel.gpio_num = CONFIG_PWM_G1_GPIO;
+    if (CONFIG_PWM_R1_GPIO != -1){
+        ledc_channel.channel = R1_CHANNEL;
+        ledc_channel.gpio_num = CONFIG_PWM_R1_GPIO;
+        ESP_LOGI(TAG, "configuring R1 PWM");
+        ESP_ERROR_CHECK(ledc_channel_config(&ledc_channel));
+    }
 
-    ESP_LOGI(TAG, "configuring G1 PWM");
-    ESP_ERROR_CHECK(ledc_channel_config(&ledc_channel));
+    if (CONFIG_PWM_G1_GPIO != -1){
+        ledc_channel.channel = G1_CHANNEL;
+        ledc_channel.gpio_num = CONFIG_PWM_G1_GPIO;
+        ESP_LOGI(TAG, "configuring G1 PWM");
+        ESP_ERROR_CHECK(ledc_channel_config(&ledc_channel));
+    }
 
-    ledc_channel.channel = B1_CHANNEL; 
-    ledc_channel.gpio_num = CONFIG_PWM_B1_GPIO;
-    
-    ESP_LOGI(TAG, "configuring B1 PWM");
-    ESP_ERROR_CHECK(ledc_channel_config(&ledc_channel));
+    if (CONFIG_PWM_B1_GPIO != -1){    
+        ledc_channel.channel = B1_CHANNEL; 
+        ledc_channel.gpio_num = CONFIG_PWM_B1_GPIO;
+        ESP_LOGI(TAG, "configuring B1 PWM");
+        ESP_ERROR_CHECK(ledc_channel_config(&ledc_channel));
+    }
+
+    if (CONFIG_PWM_R2_GPIO != -1){
+        ledc_channel.channel = R2_CHANNEL;
+        ledc_channel.gpio_num = CONFIG_PWM_R2_GPIO;
+        ESP_LOGI(TAG, "configuring R2 PWM");
+        ESP_ERROR_CHECK(ledc_channel_config(&ledc_channel));
+    }
 
+    if (CONFIG_PWM_G2_GPIO != -1){
+        ledc_channel.channel = G2_CHANNEL;
+        ledc_channel.gpio_num = CONFIG_PWM_G2_GPIO;
+        ESP_LOGI(TAG, "configuring G2 PWM");
+        ESP_ERROR_CHECK(ledc_channel_config(&ledc_channel));
+    }
 
-    
+    if (CONFIG_PWM_B2_GPIO != -1){    
+        ledc_channel.channel = B2_CHANNEL; 
+        ledc_channel.gpio_num = CONFIG_PWM_B2_GPIO;
+        ESP_LOGI(TAG, "configuring B2 PWM");
+        ESP_ERROR_CHECK(ledc_channel_config(&ledc_channel));
+    }
 
 
 
@@ -933,19 +1001,49 @@ static void pwm_task(void* discard){
 
 
                 ESP_LOGI(TAG, "red duty float calculated as %02f, int %d", red_duty_float, red_duty_int);
-                ESP_ERROR_CHECK(ledc_set_duty(LEDC_MODE, R1_CHANNEL, red_duty_int));
-                // Update duty to apply the new value
-                ESP_ERROR_CHECK(ledc_update_duty(LEDC_MODE, R1_CHANNEL));
-            
-                ESP_LOGI(TAG, "green duty floatcalculated as %02f, int %d", green_duty_float, green_duty_int);
-                ESP_ERROR_CHECK(ledc_set_duty(LEDC_MODE, G1_CHANNEL, green_duty_int));
-                // Update duty to apply the new value
-                ESP_ERROR_CHECK(ledc_update_duty(LEDC_MODE, G1_CHANNEL));
+
+                if (CONFIG_PWM_R1_GPIO != -1){
+                    ESP_ERROR_CHECK(ledc_set_duty(LEDC_MODE, R1_CHANNEL, red_duty_int));
+                    // Update duty to apply the new value
+                    ESP_ERROR_CHECK(ledc_update_duty(LEDC_MODE, R1_CHANNEL));
+                }
+
+                if (CONFIG_PWM_R2_GPIO != -1){
+                    ESP_ERROR_CHECK(ledc_set_duty(LEDC_MODE, R2_CHANNEL, red_duty_int));
+                    // Update duty to apply the new value
+                    ESP_ERROR_CHECK(ledc_update_duty(LEDC_MODE, R2_CHANNEL));
+                }
+                
+
+                ESP_LOGI(TAG, "green duty float calculated as %02f, int %d", green_duty_float, green_duty_int);
+                
+                if (CONFIG_PWM_G1_GPIO != -1){            
+                    ESP_ERROR_CHECK(ledc_set_duty(LEDC_MODE, G1_CHANNEL, green_duty_int));
+                    // Update duty to apply the new value
+                    ESP_ERROR_CHECK(ledc_update_duty(LEDC_MODE, G1_CHANNEL));
+                }
+
+                if (CONFIG_PWM_G2_GPIO != -1){
+                    ESP_ERROR_CHECK(ledc_set_duty(LEDC_MODE, G2_CHANNEL, green_duty_int));
+                    // Update duty to apply the new value
+                    ESP_ERROR_CHECK(ledc_update_duty(LEDC_MODE, G2_CHANNEL));
+                }
+
 
                 ESP_LOGI(TAG, "blue duty float calculated as %02f, int %d", blue_duty_float, blue_duty_int);
-                ESP_ERROR_CHECK(ledc_set_duty(LEDC_MODE, B1_CHANNEL, blue_duty_int));
-                // Update duty to apply the new value
-                ESP_ERROR_CHECK(ledc_update_duty(LEDC_MODE, B1_CHANNEL));
+                
+                if (CONFIG_PWM_B1_GPIO != -1){                            
+                    ESP_ERROR_CHECK(ledc_set_duty(LEDC_MODE, B1_CHANNEL, blue_duty_int));
+                    // Update duty to apply the new value
+                    ESP_ERROR_CHECK(ledc_update_duty(LEDC_MODE, B1_CHANNEL));
+                }
+
+                if (CONFIG_PWM_B2_GPIO != -1){
+                    ESP_ERROR_CHECK(ledc_set_duty(LEDC_MODE, B2_CHANNEL, blue_duty_int));
+                    // Update duty to apply the new value
+                    ESP_ERROR_CHECK(ledc_update_duty(LEDC_MODE, B2_CHANNEL));
+                }
+
  
             } else {
                 ESP_LOGE(TAG, "failed to parse json successfully!");
@@ -972,24 +1070,21 @@ static void check_motion(void* discard){
         if(xQueueReceive(check_queue, &io_num, portMAX_DELAY)) {
 #ifdef CONFIG_MOTION_RECHECK
             // check after this much time
-            vTaskDelay( pdMS_TO_TICKS(MOTION_SLEEP_MS) );
+            for (int i = 0; i < 300; i++){
+                vTaskDelay( pdMS_TO_TICKS(10) );
+                gpio_get_level(io_num);
+            }
             // recheck the GPIO to see if it's still active (i.e. not a blip)
             int current_value = gpio_get_level(io_num);
             if ( current_value == 1 ){
-                xSemaphoreTake(report_data.mutex, portMAX_DELAY);
-                report_data.motion = true;
                 ESP_LOGI(TAG, "recheck verified motion, on pin %"PRIu32" sending!", io_num);
-                xSemaphoreGive(report_data.mutex);
-                send_report_motion(report_data.motion);
+                send_report_motion(true);
 
             } else {
                 ESP_LOGW(TAG, "recheck came back false on pin %"PRIu32", ignoring as BLIP!!", io_num);
             }
 #else
-            xSemaphoreTake(report_data.mutex, portMAX_DELAY);
-            report_data.motion = true;
-            xSemaphoreGive(report_data.mutex);
-            send_report_motion(report_data.motion);
+            send_report_motion(true);
 #endif
                 
         }
@@ -1018,8 +1113,9 @@ static void motion_task(void* discard){
     //set as input mode
     io_conf.mode = GPIO_MODE_INPUT;
     //enable pull-down mode
-    io_conf.pull_down_en = 0;
+    io_conf.pull_down_en = 1;
     io_conf.pull_up_en = 0;
+    io_conf.hys_ctrl_mode = GPIO_HYS_SOFT_ENABLE;
     gpio_config(&io_conf);
 
     //change gpio interrupt type for one pin
@@ -1032,8 +1128,10 @@ static void motion_task(void* discard){
 
 
     //create a queue to handle gpio event from isr
-    motion_queue = xQueueCreate(10, sizeof(uint32_t));
-    check_queue = xQueueCreate(10, sizeof(uint32_t));
+    motion_queue = xQueueCreate(100, sizeof(uint32_t));
+    off_queue = xQueueCreate(100, sizeof(uint32_t));
+    check_queue = xQueueCreate(100, sizeof(uint32_t));
+    
     
 
     //install gpio isr service
@@ -1054,35 +1152,31 @@ static void motion_task(void* discard){
     ESP_LOGI(TAG, "waiting for motion events");
     for(;;) {
         if(xQueueReceive(motion_queue, &io_num, portMAX_DELAY)) {
-            // Take the mutex
-            xSemaphoreTake(report_data.mutex, portMAX_DELAY);            
             int pin_value = gpio_get_level(io_num);
-            printf("GPIO[%"PRIu32"] intr, val: %d\n", io_num, pin_value);
+            ESP_LOGI(TAG, "GPIO[%"PRIu32"] intr, val: %d\n", io_num, pin_value);
+            uint32_t squelch_uptime;
             switch (io_num) {
                 case CONFIG_MOTION_FIRST_PIN:
                     prev_motion[0] = motion_pins[0];
                     motion_pins[0] = pin_value;
-                    if ( motion_pins[0] == true && prev_motion[0] == false ){
-                        xQueueSend(check_queue, &io_num, portMAX_DELAY);                    
+                    if ( motion_pins[0] == 1 && prev_motion[0] == 0 ){
+                        xQueueSend(check_queue, &io_num, portMAX_DELAY);      
                     }
                     break;
                 case CONFIG_MOTION_SECOND_PIN:
                     prev_motion[1] = motion_pins[1];
                     motion_pins[1] = pin_value;
-                    if ( motion_pins[1] == true && prev_motion[1] == false ){
-                        xQueueSend(check_queue, &io_num, portMAX_DELAY);                  
+                    if ( motion_pins[1] == 1 && prev_motion[1] == 0 ){
+                        xQueueSend(check_queue, &io_num, portMAX_DELAY); 
                     }
                     break;
                 default:
                     printf("Unable to set motion pins!\n");
             }
-            bool motion;
-            if ((motion_pins[0] == 0) && (motion_pins[1] == 0)) {
-                motion = false;
-                report_data.motion = motion;
+            if ((motion_pins[0] == 0 && motion_pins[1] == 0) &&
+                    (prev_motion[0] == 1 || prev_motion[1] == 1 )){
+                send_report_motion(false);
             }
-            xSemaphoreGive(report_data.mutex);
-            send_report_motion(motion);
         }
     }
 }
@@ -1240,7 +1334,11 @@ short temp_avg = 0;
 #else
         // sleep for 10 seconds before measuring again
         ESP_LOGI(TAG, "sleeping for %lld ms", remaining_time/1000);
-        vTaskDelay( pdMS_TO_TICKS(remaining_time/1000) );
+        if ( remaining_time > 0 ){
+            vTaskDelay( pdMS_TO_TICKS(remaining_time/1000) );
+        } else {
+            ESP_LOGW(TAG, "sleep time was negative so we're already behind, just looping around");
+        }
 #endif
 
     }
@@ -1429,6 +1527,9 @@ void adjust_color_lookup_brightness(float multiplier){
 void app_main(void)
 {
 
+    app_desc = *esp_app_get_description();
+
+    ESP_LOGI(TAG, "Built from commit %s", app_desc.version);
 
 /*#ifdef CONFIG_LIGHT_SLEEP_ENABLED
     ESP_ERROR_CHECK(esp_sleep_pd_config(ESP_PD_DOMAIN_RTC_PERIPH, ESP_PD_OPTION_ON));
@@ -1501,11 +1602,15 @@ void app_main(void)
     wifi_manager_set_callback(WM_EVENT_STA_DISCONNECTED, &wifi_connection_bad);
 #endif
     send_queue = xQueueCreate(5, sizeof(char*));
+    version_queue = xQueueCreate(5, sizeof(char*));
     xTaskCreate(send_task, "send_task", 4096, NULL, 2, NULL);
+    xTaskCreate(version_task, "version_task", 4096, NULL, 2, NULL);
+    
 #if defined(CONFIG_MOTION_FIRST_ENABLED) || defined(CONFIG_MOTION_SECOND_ENABLED)
     ESP_LOGI(TAG, "installing motion task");
     xTaskCreate(motion_task, "motion_task", 4096, NULL, 2, NULL);
 #endif
     xTaskCreate(monitoring_task, "monitoring_task", 4096, NULL, 1, NULL);    
+    
 }
 
index 276883113c04dd83f7e45ff3b28db50d01eacfcc..9998152a3e57dcb119d71cae8866a9ced56191b4 100644 (file)
@@ -23,6 +23,7 @@
 #include "esp_openthread.h"
 #include "esp_openthread_netif_glue.h"
 #include "esp_openthread_lock.h"
+#include "esp_app_desc.h"
 #include "esp_vfs_eventfd.h"
 #include "openthread/logging.h"
 #include "openthread/thread.h"
@@ -125,6 +126,7 @@ static const char *TAG = "aqi";
 
 // ten second loop
 #define SLEEP_MS 10000
+#define SQUELCH_MS 5000
 
 
 
index b3c3b6663e3a1bddf06a8800c70a3cdc3ce29fbf..2638ac3174dd945d27d317cbc07ae9e08c4de79f 100644 (file)
@@ -1817,7 +1817,7 @@ CONFIG_WIFI_PROV_STA_ALL_CHANNEL_SCAN=y
 #
 # AQI Program Configuration
 #
-# CONFIG_TEMP_ENABLED is not set
+CONFIG_TEMP_ENABLED=y
 CONFIG_TEMP_PIN=2
 # CONFIG_EEPY_DEVICE is not set
 # CONFIG_LIGHT_SLEEP_ENABLED is not set
@@ -1826,23 +1826,23 @@ CONFIG_TEMP_PIN=2
 # CONFIG_WIFI_ENABLED is not set
 CONFIG_OT_ENABLED=y
 # CONFIG_LED_ENABLED is not set
-# CONFIG_MOTION_FIRST_ENABLED is not set
-CONFIG_MOTION_FIRST_PIN=25
+CONFIG_MOTION_FIRST_ENABLED=y
+CONFIG_MOTION_FIRST_PIN=14
 # CONFIG_MOTION_SECOND_ENABLED is not set
-CONFIG_MOTION_SECOND_PIN=10
+CONFIG_MOTION_SECOND_PIN=4
 # CONFIG_MOTION_RECHECK is not set
 # CONFIG_PWM_ENABLED is not set
 CONFIG_PWM_TOPIC="esp32/pwm/stairway"
 CONFIG_PWM_TARGET_PERCENT=50
-CONFIG_PWM_R1_GPIO=0
-CONFIG_PWM_G1_GPIO=14
+CONFIG_PWM_R1_GPIO=1
+CONFIG_PWM_G1_GPIO=0
 CONFIG_PWM_B1_GPIO=13
-CONFIG_PWM_R2_GPIO=-1
-CONFIG_PWM_G2_GPIO=-1
-CONFIG_PWM_B2_GPIO=-1
+CONFIG_PWM_R2_GPIO=12
+CONFIG_PWM_G2_GPIO=14
+CONFIG_PWM_B2_GPIO=4
 # CONFIG_INDICATOR_ENABLED is not set
 CONFIG_BROKER_URL="mqtts://esp32:sensorauth@rabbitmq"
-CONFIG_LOCATION="Test Solder 2"
+CONFIG_LOCATION="Upstairs Bedroom"
 CONFIG_GPIO_ERASE_PIN=5
 # end of AQI Program Configuration