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 "driver/gpio.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" | ||||
| 
 | ||||
| #define TAG "CACO" | ||||
| #define TAG "BTN" | ||||
| 
 | ||||
| #define GPIO_INPUT_IO_0    33 | ||||
| #define GPIO_INPUT_PIN_SEL  ((1ULL<<GPIO_INPUT_IO_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 RTC_WAKE_IO RTC_GPIO8 | ||||
|  | @ -54,6 +53,8 @@ | |||
| #define LED_COUNT (1) | ||||
| #define SPI_BUF   (LED_COUNT + 2) | ||||
| 
 | ||||
| #define TOPIC_POWER_STATUS "stat/tasmota_E74A79/POWER" | ||||
| 
 | ||||
| static uint8_t id; | ||||
| 
 | ||||
| static EventGroupHandle_t wm_event_group; | ||||
|  | @ -62,12 +63,6 @@ static xTimerHandle sleep_timer; | |||
| static spi_device_handle_t spi; | ||||
| 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 { | ||||
|   POR, | ||||
|   CONNECTING, | ||||
|  | @ -77,39 +72,7 @@ enum led_states { | |||
| 
 | ||||
| enum led_states led_state; | ||||
| 
 | ||||
| esp_err_t _http_event_handle(esp_http_client_event_t *evt) { | ||||
|   //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; | ||||
| } | ||||
| esp_mqtt_client_handle_t client; | ||||
| 
 | ||||
| void enter_sleep() { | ||||
|   ESP_LOGI(TAG, "Enter sleep"); | ||||
|  | @ -147,65 +110,43 @@ void reset_sleep_timer() { | |||
|   xTimerStart(sleep_timer, portMAX_DELAY); | ||||
| } | ||||
| 
 | ||||
| void ping() { | ||||
|   esp_http_client_config_t config = { | ||||
|     .url = "http://192.168.0.1/_gr", | ||||
|     .method = HTTP_METHOD_POST, | ||||
|   }; | ||||
| uint8_t led_state_new[4]; | ||||
| uint8_t led_state_cur[4]; | ||||
| 
 | ||||
|   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); | ||||
| void led_display_loop() { | ||||
|   static spi_transaction_t trans[SPI_BUF]; | ||||
| 
 | ||||
|   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)); | ||||
|   int i; | ||||
|   for (i = 0; i < SPI_BUF; i++) { | ||||
|     memset(&trans[i], 0, sizeof(spi_transaction_t)); | ||||
| 
 | ||||
|     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() { | ||||
|   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() { | ||||
| void led_control_loop() { | ||||
|   uint8_t v = 0; | ||||
| 
 | ||||
|   while(true) { | ||||
|  | @ -213,6 +154,9 @@ void led_loop() { | |||
|       EventBits_t ev_bits = xEventGroupGetBits(wm_event_group); | ||||
|       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]; | ||||
| 
 | ||||
|       int i; | ||||
|  | @ -226,6 +170,8 @@ void led_loop() { | |||
|       trans[1].tx_data[0] = (0b11100000 | 1); | ||||
| 
 | ||||
|       if(ev_bits & WIFI_CONNECTED) { | ||||
|         esp_mqtt_client_start(client); | ||||
| 
 | ||||
|         trans[1].tx_data[1] = 0; | ||||
|         trans[1].tx_data[2] = 127; | ||||
|         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) | ||||
| { | ||||
|     uint32_t gpio_num = (uint32_t) arg; | ||||
|     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() { | ||||
|   int8_t state = -1; | ||||
|   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(;;) { | ||||
|     if(xQueueReceive(gpio_evt_queue, &io_num, portMAX_DELAY)) { | ||||
|       uint8_t level = gpio_get_level(io_num); | ||||
|  | @ -347,7 +291,7 @@ void gpio_loop() { | |||
|       reset_sleep_timer(); | ||||
| 
 | ||||
|       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); | ||||
|       } else { | ||||
|         xTimerStop(button_timer, portMAX_DELAY); | ||||
|  | @ -357,7 +301,7 @@ void gpio_loop() { | |||
| } | ||||
| 
 | ||||
| void handle_button_timer() { | ||||
|   shoot(); | ||||
|   esp_mqtt_client_publish(client, "cmnd/tasmota_E74A79/POWER", "TOGGLE", 0, 1, 0); | ||||
| } | ||||
| 
 | ||||
| void gpio_init() { | ||||
|  | @ -462,7 +406,12 @@ void app_main() { | |||
|   gpio_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(); | ||||
| 
 | ||||
|   while(true) { | ||||
|     vTaskDelay(1000 / portTICK_PERIOD_MS); | ||||
|   } | ||||
| }; | ||||
|  |  | |||
		Loading…
	
	Add table
		
		Reference in a new issue