} pwm_data_t;
#endif
+
typedef struct report_data_s {
#ifdef CONFIG_UART_ENABLED
uint16_t pm10;
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};
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);
//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);
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;
#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;
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);
}
-#endif
+#endif // wifi or ot enabled
bool verify_checksum(uint8_t* data){
int total = 0;
// 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));
+ }
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!");
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
}
//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
//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
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);
}
}
}
#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
}
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));
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);
+
}