now listens to tasmota power state and disables sleep mode when POWER ON
This commit is contained in:
		
							parent
							
								
									e756e5405f
								
							
						
					
					
						commit
						91da7dff4c
					
				
					 1 changed files with 112 additions and 163 deletions
				
			
		
							
								
								
									
										275
									
								
								main/main.c
									
										
									
									
									
								
							
							
						
						
									
										275
									
								
								main/main.c
									
										
									
									
									
								
							|  | @ -28,21 +28,20 @@ | ||||||
| #include "argtable3/argtable3.h" | #include "argtable3/argtable3.h" | ||||||
| #include "driver/gpio.h" | #include "driver/gpio.h" | ||||||
| #include "driver/spi_master.h" | #include "driver/spi_master.h" | ||||||
|  | #include "lwip/sockets.h" | ||||||
|  | #include "lwip/dns.h" | ||||||
|  | #include "lwip/netdb.h" | ||||||
|  | 
 | ||||||
|  | #include "mqtt_client.h" | ||||||
| 
 | 
 | ||||||
| #include "esp32-wifi-manager.h" | #include "esp32-wifi-manager.h" | ||||||
| 
 | 
 | ||||||
| #define TAG "CACO" | #define TAG "BTN" | ||||||
| 
 | 
 | ||||||
| #define GPIO_INPUT_IO_0    33 | #define GPIO_INPUT_IO_0    33 | ||||||
| #define GPIO_INPUT_PIN_SEL  ((1ULL<<GPIO_INPUT_IO_0)) | #define GPIO_INPUT_PIN_SEL  ((1ULL<<GPIO_INPUT_IO_0)) | ||||||
| #define ESP_INTR_FLAG_DEFAULT 0 | #define ESP_INTR_FLAG_DEFAULT 0 | ||||||
| 
 | 
 | ||||||
| #define BASE_URL "http://192.168.0.1/"
 |  | ||||||
| #define CMD_BEEP "cmd=audio resplay 0 1 3\n" |  | ||||||
| 
 |  | ||||||
| #define CONFIG_SERVO_ENABLE (0) |  | ||||||
| #define CONFIG_SHOOT_DELAY_MS (30000) |  | ||||||
| #define CONFIG_TIMEOUT_SHOOT (100 / portTICK_PERIOD_MS) |  | ||||||
| #define CONFIG_SLEEP_TIMEOUT (60000 / portTICK_PERIOD_MS) | #define CONFIG_SLEEP_TIMEOUT (60000 / portTICK_PERIOD_MS) | ||||||
| 
 | 
 | ||||||
| #define RTC_WAKE_IO RTC_GPIO8 | #define RTC_WAKE_IO RTC_GPIO8 | ||||||
|  | @ -54,6 +53,8 @@ | ||||||
| #define LED_COUNT (1) | #define LED_COUNT (1) | ||||||
| #define SPI_BUF   (LED_COUNT + 2) | #define SPI_BUF   (LED_COUNT + 2) | ||||||
| 
 | 
 | ||||||
|  | #define TOPIC_POWER_STATUS "stat/tasmota_E74A79/POWER" | ||||||
|  | 
 | ||||||
| static uint8_t id; | static uint8_t id; | ||||||
| 
 | 
 | ||||||
| static EventGroupHandle_t wm_event_group; | static EventGroupHandle_t wm_event_group; | ||||||
|  | @ -62,12 +63,6 @@ static xTimerHandle sleep_timer; | ||||||
| static spi_device_handle_t spi; | static spi_device_handle_t spi; | ||||||
| xQueueHandle gpio_evt_queue = NULL; | xQueueHandle gpio_evt_queue = NULL; | ||||||
| 
 | 
 | ||||||
| static struct { |  | ||||||
|   struct arg_int *value; // how fast it will move in uS
 |  | ||||||
|   struct arg_int *duration; // for how long it will move
 |  | ||||||
|   struct arg_end *end; |  | ||||||
| } servo_args; |  | ||||||
| 
 |  | ||||||
| enum led_states { | enum led_states { | ||||||
|   POR, |   POR, | ||||||
|   CONNECTING, |   CONNECTING, | ||||||
|  | @ -77,39 +72,7 @@ enum led_states { | ||||||
| 
 | 
 | ||||||
| enum led_states led_state; | enum led_states led_state; | ||||||
| 
 | 
 | ||||||
| esp_err_t _http_event_handle(esp_http_client_event_t *evt) { | esp_mqtt_client_handle_t client; | ||||||
|   //ESP_LOGI(TAG, "Returning request for %s", (char*)evt->user_data);
 |  | ||||||
| 
 |  | ||||||
|   switch(evt->event_id) { |  | ||||||
|     case HTTP_EVENT_ERROR: |  | ||||||
|       ESP_LOGI(TAG, "HTTP_EVENT_ERROR"); |  | ||||||
|       break; |  | ||||||
|     case HTTP_EVENT_ON_CONNECTED: |  | ||||||
|       ESP_LOGI(TAG, "HTTP_EVENT_ON_CONNECTED"); |  | ||||||
|       break; |  | ||||||
|     case HTTP_EVENT_HEADER_SENT: |  | ||||||
|       ESP_LOGI(TAG, "HTTP_EVENT_HEADER_SENT"); |  | ||||||
|       break; |  | ||||||
|     case HTTP_EVENT_ON_HEADER: |  | ||||||
|       ESP_LOGI(TAG, "HTTP_EVENT_ON_HEADER"); |  | ||||||
|       printf("%.*s", evt->data_len, (char*)evt->data); |  | ||||||
|       break; |  | ||||||
|     case HTTP_EVENT_ON_DATA: |  | ||||||
|       ESP_LOGI(TAG, "HTTP_EVENT_ON_DATA, len=%d", evt->data_len); |  | ||||||
|       if (!esp_http_client_is_chunked_response(evt->client)) { |  | ||||||
|         printf("%.*s", evt->data_len, (char*)evt->data); |  | ||||||
|       } |  | ||||||
| 
 |  | ||||||
|       break; |  | ||||||
|     case HTTP_EVENT_ON_FINISH: |  | ||||||
|       ESP_LOGI(TAG, "HTTP_EVENT_ON_FINISH"); |  | ||||||
|       break; |  | ||||||
|     case HTTP_EVENT_DISCONNECTED: |  | ||||||
|       ESP_LOGI(TAG, "HTTP_EVENT_DISCONNECTED"); |  | ||||||
|       break; |  | ||||||
|   } |  | ||||||
|   return ESP_OK; |  | ||||||
| } |  | ||||||
| 
 | 
 | ||||||
| void enter_sleep() { | void enter_sleep() { | ||||||
|   ESP_LOGI(TAG, "Enter sleep"); |   ESP_LOGI(TAG, "Enter sleep"); | ||||||
|  | @ -147,65 +110,43 @@ void reset_sleep_timer() { | ||||||
|   xTimerStart(sleep_timer, portMAX_DELAY); |   xTimerStart(sleep_timer, portMAX_DELAY); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void ping() { | uint8_t led_state_new[4]; | ||||||
|   esp_http_client_config_t config = { | uint8_t led_state_cur[4]; | ||||||
|     .url = "http://192.168.0.1/_gr", |  | ||||||
|     .method = HTTP_METHOD_POST, |  | ||||||
|   }; |  | ||||||
| 
 | 
 | ||||||
|   esp_http_client_handle_t client = esp_http_client_init(&config); | void led_display_loop() { | ||||||
|   esp_http_client_set_post_field(client, CMD_BEEP, strlen(CMD_BEEP)); |   static spi_transaction_t trans[SPI_BUF]; | ||||||
|   esp_err_t err = esp_http_client_perform(client); |  | ||||||
| 
 | 
 | ||||||
|   if (err == ESP_OK) { |   int i; | ||||||
|     ESP_LOGI(TAG, "Status = %d, content_length = %d", |   for (i = 0; i < SPI_BUF; i++) { | ||||||
|         esp_http_client_get_status_code(client), |     memset(&trans[i], 0, sizeof(spi_transaction_t)); | ||||||
|         esp_http_client_get_content_length(client)); | 
 | ||||||
|  |     trans[i].length=8*4; | ||||||
|  |     trans[i].flags = SPI_TRANS_USE_TXDATA; | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   trans[1].tx_data[0] = (0b11100000 | 1); | ||||||
|  |   memset(&trans[SPI_BUF - 1].tx_data, 0xFF, 4); | ||||||
|  | 
 | ||||||
|  |   bool update = false; | ||||||
|  | 
 | ||||||
|  |   while(true) { | ||||||
|  |     /// TODO check _new vs _cur, ramping the channel value per step until they match
 | ||||||
|  |     /// only transmit spi data if a change was made
 | ||||||
|  |     if(led_state_new[1] != led_state_cur[1]) { | ||||||
|  |       trans[1].tx_data[1] = 0; | ||||||
|  |     } | ||||||
|  |     trans[1].tx_data[2] = 127; | ||||||
|  |     trans[1].tx_data[3] = 0; | ||||||
|  | 
 | ||||||
|  |     for(i = 0; i < SPI_BUF; i++) { | ||||||
|  |       spi_device_queue_trans(spi, &trans[i], portMAX_DELAY); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     vTaskDelay(1000 / portTICK_PERIOD_MS); | ||||||
|   } |   } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void shoot() { | void led_control_loop() { | ||||||
|   ESP_LOGI(TAG, "shooting"); |  | ||||||
| 
 |  | ||||||
|   esp_http_client_config_t config = { |  | ||||||
|     .url = "http://192.168.0.1/v1/camera/shoot", |  | ||||||
|     .method = HTTP_METHOD_POST, |  | ||||||
|   }; |  | ||||||
| 
 |  | ||||||
|   esp_http_client_handle_t client = esp_http_client_init(&config); |  | ||||||
|   esp_http_client_set_post_field(client, CMD_BEEP, strlen(CMD_BEEP)); |  | ||||||
|   esp_err_t err = esp_http_client_perform(client); |  | ||||||
| 
 |  | ||||||
|   if (err == ESP_OK) { |  | ||||||
|     ESP_LOGI(TAG, "Status = %d, content_length = %d", |  | ||||||
|         esp_http_client_get_status_code(client), |  | ||||||
|         esp_http_client_get_content_length(client)); |  | ||||||
|   } |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| void request(char *path) { |  | ||||||
|   char *url = malloc(strlen(BASE_URL) + strlen(path) + 1); |  | ||||||
|   strcpy(url, BASE_URL); |  | ||||||
|   strcat(url, path); |  | ||||||
| 
 |  | ||||||
|   ESP_LOGI(TAG, "Making request to %s", url); |  | ||||||
| 
 |  | ||||||
|   esp_http_client_config_t config = { |  | ||||||
|     .url = url, |  | ||||||
|     .event_handler = _http_event_handle |  | ||||||
|   }; |  | ||||||
| 
 |  | ||||||
|   esp_http_client_handle_t client = esp_http_client_init(&config); |  | ||||||
|   esp_err_t err = esp_http_client_perform(client); |  | ||||||
| 
 |  | ||||||
|   if (err == ESP_OK) { |  | ||||||
|     ESP_LOGI(TAG, "Status = %d, content_length = %d", |  | ||||||
|         esp_http_client_get_status_code(client), |  | ||||||
|         esp_http_client_get_content_length(client)); |  | ||||||
|   } |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| void led_loop() { |  | ||||||
|   uint8_t v = 0; |   uint8_t v = 0; | ||||||
| 
 | 
 | ||||||
|   while(true) { |   while(true) { | ||||||
|  | @ -213,6 +154,9 @@ void led_loop() { | ||||||
|       EventBits_t ev_bits = xEventGroupGetBits(wm_event_group); |       EventBits_t ev_bits = xEventGroupGetBits(wm_event_group); | ||||||
|       ESP_LOGI(TAG, "got event: %d", ev_bits); |       ESP_LOGI(TAG, "got event: %d", ev_bits); | ||||||
| 
 | 
 | ||||||
|  |       // TODO XXX rewrite to only update led_state_new and let led_display_loop 
 | ||||||
|  |       // handle rendering
 | ||||||
|  | 
 | ||||||
|       static spi_transaction_t trans[SPI_BUF]; |       static spi_transaction_t trans[SPI_BUF]; | ||||||
| 
 | 
 | ||||||
|       int i; |       int i; | ||||||
|  | @ -226,6 +170,8 @@ void led_loop() { | ||||||
|       trans[1].tx_data[0] = (0b11100000 | 1); |       trans[1].tx_data[0] = (0b11100000 | 1); | ||||||
| 
 | 
 | ||||||
|       if(ev_bits & WIFI_CONNECTED) { |       if(ev_bits & WIFI_CONNECTED) { | ||||||
|  |         esp_mqtt_client_start(client); | ||||||
|  | 
 | ||||||
|         trans[1].tx_data[1] = 0; |         trans[1].tx_data[1] = 0; | ||||||
|         trans[1].tx_data[2] = 127; |         trans[1].tx_data[2] = 127; | ||||||
|         trans[1].tx_data[3] = 0; |         trans[1].tx_data[3] = 0; | ||||||
|  | @ -252,76 +198,74 @@ void led_loop() { | ||||||
|   } |   } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void pwm_init() { |  | ||||||
|   mcpwm_gpio_init(MCPWM_UNIT_0, MCPWM0A, 21); |  | ||||||
| 
 |  | ||||||
|   mcpwm_config_t pwm_config; |  | ||||||
|   pwm_config.frequency = 50;    //frequency = 50Hz, i.e. for every servo motor time period should be 20ms
 |  | ||||||
|   pwm_config.cmpr_a = 0;    //duty cycle of PWMxA = 0
 |  | ||||||
|   pwm_config.cmpr_b = 0;    //duty cycle of PWMxb = 0
 |  | ||||||
|   pwm_config.counter_mode = MCPWM_UP_COUNTER; |  | ||||||
|   pwm_config.duty_mode = MCPWM_DUTY_MODE_0; |  | ||||||
|   mcpwm_init(MCPWM_UNIT_0, MCPWM_TIMER_0, &pwm_config); //Configure PWM0A & PWM0B with above settings
 |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| void servo() { |  | ||||||
|   ESP_LOGI(TAG, "value: %d duration: %d", servo_args.value->ival[0], servo_args.duration->ival[0]); |  | ||||||
| 
 |  | ||||||
|   while(true) { |  | ||||||
|     mcpwm_set_duty_in_us(MCPWM_UNIT_0, MCPWM_TIMER_0, MCPWM_OPR_A, servo_args.value->ival[0]); |  | ||||||
|     vTaskDelay(servo_args.duration->ival[0] / portTICK_PERIOD_MS); |  | ||||||
|     mcpwm_set_duty_in_us(MCPWM_UNIT_0, MCPWM_TIMER_0, MCPWM_OPR_A, 1500); |  | ||||||
| 
 |  | ||||||
|     vTaskDelay(5000 / portTICK_PERIOD_MS); |  | ||||||
|   } |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| bool running = false; |  | ||||||
| 
 |  | ||||||
| static int servo_start(int argc, char **argv) { |  | ||||||
|   int nerrors = arg_parse(argc, argv, (void**) &servo_args); |  | ||||||
|   if (nerrors != 0) { |  | ||||||
|     arg_print_errors(stderr, servo_args.end, argv[0]); |  | ||||||
|     return 1; |  | ||||||
|   } |  | ||||||
| 
 |  | ||||||
|   if(!running) { |  | ||||||
|     running = true; |  | ||||||
|     xTaskCreate(&servo, "servo",  4096, NULL, 6, NULL); |  | ||||||
|   } |  | ||||||
| 
 |  | ||||||
|   return ESP_OK; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| void register_servo_cmd() { |  | ||||||
|   servo_args.value = arg_int0("v", "value", "<int>", "move value in us"); |  | ||||||
|   servo_args.value->ival[0] = 1200; |  | ||||||
| 
 |  | ||||||
|   servo_args.duration = arg_int0("d", "duration", "<int>", "duration in ms"); |  | ||||||
| 
 |  | ||||||
|   servo_args.end = arg_end(2); |  | ||||||
| 
 |  | ||||||
|   const esp_console_cmd_t start_cmd = { |  | ||||||
|     .command = "start", |  | ||||||
|     .help = "Starts the servo", |  | ||||||
|     .hint = NULL, |  | ||||||
|     .func = &servo_start, |  | ||||||
|     .argtable = &servo_args |  | ||||||
|   }; |  | ||||||
| 
 |  | ||||||
|   ESP_ERROR_CHECK( esp_console_cmd_register(&start_cmd) ); |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| static void IRAM_ATTR gpio_isr_handler(void* arg) | static void IRAM_ATTR gpio_isr_handler(void* arg) | ||||||
| { | { | ||||||
|     uint32_t gpio_num = (uint32_t) arg; |     uint32_t gpio_num = (uint32_t) arg; | ||||||
|     xQueueSendFromISR(gpio_evt_queue, &gpio_num, NULL); |     xQueueSendFromISR(gpio_evt_queue, &gpio_num, NULL); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | static void mqtt_event_handler(void *handler_args, esp_event_base_t base, int32_t event_id, void *event_data) | ||||||
|  | { | ||||||
|  |     ESP_LOGD(TAG, "Event dispatched from event loop base=%s, event_id=%d", base, event_id); | ||||||
|  |     esp_mqtt_event_handle_t event = event_data; | ||||||
|  |     esp_mqtt_client_handle_t client = event->client; | ||||||
|  |     int msg_id; | ||||||
|  |     switch ((esp_mqtt_event_id_t)event_id) { | ||||||
|  |     case MQTT_EVENT_CONNECTED: | ||||||
|  |         ESP_LOGI(TAG, "MQTT_EVENT_CONNECTED"); | ||||||
|  |         esp_mqtt_client_subscribe(client, "espbutton/update", 0); | ||||||
|  |         esp_mqtt_client_subscribe(client, TOPIC_POWER_STATUS, 0); | ||||||
|  |         break; | ||||||
|  |     case MQTT_EVENT_DISCONNECTED: | ||||||
|  |         ESP_LOGI(TAG, "MQTT_EVENT_DISCONNECTED"); | ||||||
|  |         break; | ||||||
|  | 
 | ||||||
|  |     case MQTT_EVENT_SUBSCRIBED: | ||||||
|  |         ESP_LOGI(TAG, "MQTT_EVENT_SUBSCRIBED, msg_id=%d", event->msg_id); | ||||||
|  |         break; | ||||||
|  |     case MQTT_EVENT_UNSUBSCRIBED: | ||||||
|  |         ESP_LOGI(TAG, "MQTT_EVENT_UNSUBSCRIBED, msg_id=%d", event->msg_id); | ||||||
|  |         break; | ||||||
|  |     case MQTT_EVENT_PUBLISHED: | ||||||
|  |         ESP_LOGI(TAG, "MQTT_EVENT_PUBLISHED, msg_id=%d", event->msg_id); | ||||||
|  |         break; | ||||||
|  |     case MQTT_EVENT_DATA: | ||||||
|  |         ESP_LOGI(TAG, "MQTT_EVENT_DATA [topic: %.*s]", event->topic_len, event->topic); | ||||||
|  | 
 | ||||||
|  |         if(strncmp(event->topic, (const char*)TOPIC_POWER_STATUS, event->data_len) == 0) { | ||||||
|  |           ESP_LOGI(TAG, "data_len: %d", event->data_len); | ||||||
|  |           if(strncmp(event->data, "ON", 2) == 0) { | ||||||
|  |             xTimerStop(sleep_timer, portMAX_DELAY); | ||||||
|  |           } else if(strncmp(event->data, "OFF", 3) == 0) { | ||||||
|  |             reset_sleep_timer(); | ||||||
|  |           } | ||||||
|  |         } | ||||||
|  |         break; | ||||||
|  |     case MQTT_EVENT_ERROR: | ||||||
|  |         ESP_LOGI(TAG, "MQTT_EVENT_ERROR"); | ||||||
|  |         if (event->error_handle->error_type == MQTT_ERROR_TYPE_TCP_TRANSPORT) { | ||||||
|  |             ESP_LOGI(TAG, "Last errno string (%s)", strerror(event->error_handle->esp_transport_sock_errno)); | ||||||
|  | 
 | ||||||
|  |         } | ||||||
|  |         break; | ||||||
|  |     default: | ||||||
|  |         ESP_LOGI(TAG, "Other event id:%d", event->event_id); | ||||||
|  |         break; | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
| void gpio_loop() { | void gpio_loop() { | ||||||
|   int8_t state = -1; |   int8_t state = -1; | ||||||
|   uint32_t io_num; |   uint32_t io_num; | ||||||
| 
 | 
 | ||||||
|  |   esp_mqtt_client_config_t mqtt_cfg = { | ||||||
|  |     .uri = "mqtt://192.168.1.1", | ||||||
|  |   }; | ||||||
|  | 
 | ||||||
|  |   client = esp_mqtt_client_init(&mqtt_cfg); | ||||||
|  |   /* The last argument may be used to pass data to the event handler, in this example mqtt_event_handler */ | ||||||
|  |   esp_mqtt_client_register_event(client, ESP_EVENT_ANY_ID, mqtt_event_handler, NULL); | ||||||
|  | 
 | ||||||
|   for(;;) { |   for(;;) { | ||||||
|     if(xQueueReceive(gpio_evt_queue, &io_num, portMAX_DELAY)) { |     if(xQueueReceive(gpio_evt_queue, &io_num, portMAX_DELAY)) { | ||||||
|       uint8_t level = gpio_get_level(io_num); |       uint8_t level = gpio_get_level(io_num); | ||||||
|  | @ -347,7 +291,7 @@ void gpio_loop() { | ||||||
|       reset_sleep_timer(); |       reset_sleep_timer(); | ||||||
| 
 | 
 | ||||||
|       if(level == 0) { |       if(level == 0) { | ||||||
|         xTimerChangePeriod(button_timer, CONFIG_TIMEOUT_SHOOT, portMAX_DELAY); |         xTimerChangePeriod(button_timer, 100 / portTICK_PERIOD_MS, portMAX_DELAY); | ||||||
|         xTimerStart(button_timer, portMAX_DELAY); |         xTimerStart(button_timer, portMAX_DELAY); | ||||||
|       } else { |       } else { | ||||||
|         xTimerStop(button_timer, portMAX_DELAY); |         xTimerStop(button_timer, portMAX_DELAY); | ||||||
|  | @ -357,7 +301,7 @@ void gpio_loop() { | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void handle_button_timer() { | void handle_button_timer() { | ||||||
|   shoot(); |   esp_mqtt_client_publish(client, "cmnd/tasmota_E74A79/POWER", "TOGGLE", 0, 1, 0); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void gpio_init() { | void gpio_init() { | ||||||
|  | @ -462,7 +406,12 @@ void app_main() { | ||||||
|   gpio_init(); |   gpio_init(); | ||||||
|   spi_init(); |   spi_init(); | ||||||
| 
 | 
 | ||||||
|   xTaskCreate(&led_loop, "led_loop",  4096, NULL, 6, NULL); |   xTaskCreate(&led_display_loop, "led_display_loop",  4096, NULL, 6, NULL); | ||||||
|  |   xTaskCreate(&led_control_loop, "led_control_loop",  4096, NULL, 6, NULL); | ||||||
| 
 | 
 | ||||||
|   wifi_manager_scan(); |   wifi_manager_scan(); | ||||||
|  | 
 | ||||||
|  |   while(true) { | ||||||
|  |     vTaskDelay(1000 / portTICK_PERIOD_MS); | ||||||
|  |   } | ||||||
| }; | }; | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		
		Reference in a new issue