#include #include #include #include "freertos/FreeRTOS.h" #include "freertos/task.h" #include "freertos/queue.h" #include "freertos/semphr.h" #include "esp_log.h" #include "esp_system.h" #include "freertos/event_groups.h" #include "esp_timer.h" #include "esp_err.h" #include "user_config.h" //#include "lvgl/lvgl.h" #include"LED.h" #include"list.h" #include "freertos/timers.h" #include "user_sleep.h" #include "esp_sleep.h" #include "esp_sleep.h" //#include "ble_ota.h" #include "batt_charge.h" #include "user_time.h" #include "driver/uart.h" #include "driver/rtc_io.h" char user_device_id[50] ={0}; RTC_FAST_ATTR unsigned char power = 0; #define MAX_RETRY_ACK 3 //最大重传次数停止发送数据 int retry_times = 0; bool powerOn_flag = false; static const char *LOG_TAG = "user_main"; extern Node *Send_list; //发送数据链表 YC_DATA_T yc_data; //ListNode *list_head = NULL; adc_oneshot_unit_handle_t adc1_handle; QueueHandle_t left_screen_queue; QueueHandle_t right_screen_queue; QueueHandle_t lora_data_queue; QueueHandle_t yc_data_queue; QueueHandle_t button_Data_queue; EventGroupHandle_t screen_event; extern QueueHandle_t lora_receiveQueue; //lora底层数据上报 extern QueueHandle_t lora_dealhandle; //开始处理逻辑的数据 QueueHandle_t sleep_queue; QueueHandle_t wakeup_queue; QueueHandle_t Send_Data_queue; //发送链表任务 SemaphoreHandle_t button_semaphore; //刷新屏幕时都得加上按键互斥锁 SemaphoreHandle_t screen_semaphore; //刷新屏幕时都得加上互斥锁 #if !HARDWARE_SPI struct EPD_INFO_SET left_screen = {}; struct EPD_INFO_SET right_screen = {}; #endif extern LORA_DATA_T lora_data; extern TERMINAL_INFO_T terminal_info; #include "y_ringbuf.h" extern struct RINGBUF_st; extern RINGBUF_st *lora_ringbuf; // static void board_init(void); // static void info_init(void); static void left_screen_task(void* arg); static void right_screen_task(void* arg); static void unpack_task(void* arg); static void lora_task(void* arg); static void button_task(void* arg); static void business_logic_task(void* arg); static void gui_task(void* pvParameter); void read_deal_data_callback_handler(); // void Sendlist_task_callback_handler(); void uart_task_callback_handler(); void beep_open() { // Set duty to 50% ESP_ERROR_CHECK(ledc_set_duty(LEDC_MODE, LEDC_CHANNEL, LEDC_DUTY)); // Update duty to apply the new value ESP_ERROR_CHECK(ledc_update_duty(LEDC_MODE, LEDC_CHANNEL)); } void beep_close() { ESP_ERROR_CHECK(ledc_set_duty(LEDC_MODE, LEDC_CHANNEL, 0)); // Update duty to apply the new value ESP_ERROR_CHECK(ledc_update_duty(LEDC_MODE, LEDC_CHANNEL)); } void beep_blink(uint16_t ms,uint16_t count) { for(int i =0;i60) { Machine_info.last_batt_precent = Machine_info.batt_precent; value_count = 0; } #if 0 power_key = gpio_get_level(4); vTaskDelay(4000 / portTICK_PERIOD_MS); if( 0 == gpio_get_level(4)) { uart_wait_tx_idle_polling(CONFIG_ESP_CONSOLE_UART_NUM); printf("power on\r\n"); #if 1//USER_DEEP_SLEEP_ENABLE reson = is_wake_up_reson(); //返回唤醒的原因 /* ULP Risc-V read and detected a temperature above the limit */ if (reson == ESP_SLEEP_WAKEUP_EXT0) { if(Machine_info.power_status == 0) { Machine_info.power_status = 1; //开机 lora_set_power_level(1); //打开lora电源 // Set duty to 50% ESP_ERROR_CHECK(ledc_set_duty(LEDC_MODE, LEDC_CHANNEL, LEDC_DUTY)); // Update duty to apply the new value ESP_ERROR_CHECK(ledc_update_duty(LEDC_MODE, LEDC_CHANNEL)); vTaskDelay(1000/ portTICK_PERIOD_MS); ESP_ERROR_CHECK(ledc_set_duty(LEDC_MODE, LEDC_CHANNEL, 0)); // Update duty to apply the new value ESP_ERROR_CHECK(ledc_update_duty(LEDC_MODE, LEDC_CHANNEL)); Machine_info.left_current_Quick_refresh_time = 5; vTaskDelay(1000/ portTICK_PERIOD_MS); if(xQueueSend(left_screen_queue,&Machine_info,portMAX_DELAY) != true) { printf("left send fail\r\n"); } }else if(Machine_info.power_status == 1) { printf("aready power on\r\n"); } } #endif break; } #endif } }else //未充电 { printf("charge_key is %s\r\n",!charge_key?"charge in":"charge out"); extern void dis_right_instructions(); dis_right_instructions(); printf("start power off\r\n"); uart_wait_tx_idle_polling(CONFIG_ESP_CONSOLE_UART_NUM); #if 1 //电源按键 // adc_oneshot_del_unit(adc1_handle); gpio_reset_pin(4); int ext_wakeup_pin_0 = 4; printf("Enabling EXT0 wakeup on pin GPIO%d\n", ext_wakeup_pin_0); ESP_ERROR_CHECK(esp_sleep_enable_ext0_wakeup(ext_wakeup_pin_0, 0)); // Configure pullup/downs via RTCIO to tie wakeup pins to inactive level during deepsleep. // EXT0 resides in the same power domain (RTC_PERIPH) as the RTC IO pullup/downs. // No need to keep that power domain explicitly, unlike EXT1. ESP_ERROR_CHECK(rtc_gpio_pullup_en(ext_wakeup_pin_0)); ESP_ERROR_CHECK(rtc_gpio_pulldown_dis(ext_wakeup_pin_0)); gpio_reset_pin(2); const int ext_wakeup_pin_1 = 2; const uint64_t ext_wakeup_pin_1_mask = 1ULL << ext_wakeup_pin_1; printf("Enabling EXT1 wakeup on pins GPIO%d\r\n",ext_wakeup_pin_1); ESP_ERROR_CHECK(esp_sleep_enable_ext1_wakeup(ext_wakeup_pin_1_mask, ESP_EXT1_WAKEUP_ALL_LOW)); #endif esp_deep_sleep_start(); break; } vTaskDelay(1000 / portTICK_PERIOD_MS); } } xTaskCreate( left_screen_task, "left_screen_task", 25*1024, NULL, configMAX_PRIORITIES - 1, NULL); //idf.py 设置分区 spiffs_init(); extern uint32_t ulp_wakeup_result; if ( (reson !=ESP_SLEEP_WAKEUP_EXT0)&& (reson !=ESP_SLEEP_WAKEUP_ULP)&& (reson !=ESP_SLEEP_WAKEUP_TIMER) ) { #if PRINT_SPIFFS printHexData(&default_info,sizeof(Machine_info_t)); // spiffs_write(&default_info); #endif spiffs_read_powerOn(&Machine_info); //重新初始化开机后默认关机 Machine_info.power_status = 0; user_nvs_init(); } if(reson == ESP_SLEEP_WAKEUP_EXT0) { #if 0 adc1_init(); int value = 0; while(1) { value++; adc_read_left_key_pin(adc1_handle); vTaskDelay(10 / portTICK_PERIOD_MS); if(value>10) { break; } } #else int power_key =0; adc1_init(); while(1) { //value++; power_key = gpio_get_level(4); vTaskDelay(4000 / portTICK_PERIOD_MS); if( 0 == gpio_get_level(4)) { if(read_battery_voltage()<10) //判断电压小于10% 不让开机 { printf("start power off\r\n"); uart_wait_tx_idle_polling(CONFIG_ESP_CONSOLE_UART_NUM); #if 1 //电源按键 // adc_oneshot_del_unit(adc1_handle); gpio_reset_pin(4); int ext_wakeup_pin_0 = 4; printf("Enabling EXT0 wakeup on pin GPIO%d\n", ext_wakeup_pin_0); ESP_ERROR_CHECK(esp_sleep_enable_ext0_wakeup(ext_wakeup_pin_0, 0)); // Configure pullup/downs via RTCIO to tie wakeup pins to inactive level during deepsleep. // EXT0 resides in the same power domain (RTC_PERIPH) as the RTC IO pullup/downs. // No need to keep that power domain explicitly, unlike EXT1. ESP_ERROR_CHECK(rtc_gpio_pullup_en(ext_wakeup_pin_0)); ESP_ERROR_CHECK(rtc_gpio_pulldown_dis(ext_wakeup_pin_0)); gpio_reset_pin(2); const int ext_wakeup_pin_1 = 2; const uint64_t ext_wakeup_pin_1_mask = 1ULL << ext_wakeup_pin_1; printf("Enabling EXT1 wakeup on pins GPIO%d\r\n",ext_wakeup_pin_1); ESP_ERROR_CHECK(esp_sleep_enable_ext1_wakeup(ext_wakeup_pin_1_mask, ESP_EXT1_WAKEUP_ALL_LOW)); #endif esp_deep_sleep_start(); } adc_oneshot_del_unit(adc1_handle); //删除adc使用 uart_wait_tx_idle_polling(CONFIG_ESP_CONSOLE_UART_NUM); printf("power on-\r\n"); #if 1//USER_DEEP_SLEEP_ENABLE reson = is_wake_up_reson(); //返回唤醒的原因 /* ULP Risc-V read and detected a temperature above the limit */ if (reson == ESP_SLEEP_WAKEUP_EXT0) { if(Machine_info.power_status == 0) { Machine_info.power_status = 1; //开机 lora_set_power_level(1); //打开lora电源 // Set duty to 50% ESP_ERROR_CHECK(ledc_set_duty(LEDC_MODE, LEDC_CHANNEL, LEDC_DUTY)); // Update duty to apply the new value ESP_ERROR_CHECK(ledc_update_duty(LEDC_MODE, LEDC_CHANNEL)); vTaskDelay(1000/ portTICK_PERIOD_MS); ESP_ERROR_CHECK(ledc_set_duty(LEDC_MODE, LEDC_CHANNEL, 0)); // Update duty to apply the new value ESP_ERROR_CHECK(ledc_update_duty(LEDC_MODE, LEDC_CHANNEL)); Machine_info.left_current_Quick_refresh_time = 5; vTaskDelay(1000/ portTICK_PERIOD_MS); printf("开机刷屏\r\n"); if(xQueueSend(left_screen_queue,&Machine_info,portMAX_DELAY) != true) { printf("left send fail\r\n"); } }else if(Machine_info.power_status == 1){ printf("aready power on\r\n"); } } #endif break; }else { printf("start power off\r\n"); uart_wait_tx_idle_polling(CONFIG_ESP_CONSOLE_UART_NUM); #if 1 //电源按键 // adc_oneshot_del_unit(adc1_handle); gpio_reset_pin(4); int ext_wakeup_pin_0 = 4; printf("Enabling EXT0 wakeup on pin GPIO%d\n", ext_wakeup_pin_0); ESP_ERROR_CHECK(esp_sleep_enable_ext0_wakeup(ext_wakeup_pin_0, 0)); // Configure pullup/downs via RTCIO to tie wakeup pins to inactive level during deepsleep. // EXT0 resides in the same power domain (RTC_PERIPH) as the RTC IO pullup/downs. // No need to keep that power domain explicitly, unlike EXT1. ESP_ERROR_CHECK(rtc_gpio_pullup_en(ext_wakeup_pin_0)); ESP_ERROR_CHECK(rtc_gpio_pulldown_dis(ext_wakeup_pin_0)); gpio_reset_pin(2); const int ext_wakeup_pin_1 = 2; const uint64_t ext_wakeup_pin_1_mask = 1ULL << ext_wakeup_pin_1; printf("Enabling EXT1 wakeup on pins GPIO%d\r\n",ext_wakeup_pin_1); ESP_ERROR_CHECK(esp_sleep_enable_ext1_wakeup(ext_wakeup_pin_1_mask, ESP_EXT1_WAKEUP_ALL_LOW)); #endif esp_deep_sleep_start(); } } #endif printf("deep Wake up from ext0\n"); }else if(reson == ESP_SLEEP_WAKEUP_ULP) { printf("wakeup_result = %ld\r\n",ulp_wakeup_result); // int key = find_key_value(ulp_wakeup_result); // printf("key = %d\r\n",key); #if 1 //reson = is_wake_up_reson(); //返回唤醒的原因 /* ULP Risc-V read and detected a temperature above the limit */ if (reson == ESP_SLEEP_WAKEUP_ULP) { if(Machine_info.power_status == 0) { printf("left key press power off\r\n"); uart_wait_tx_idle_polling(CONFIG_ESP_CONSOLE_UART_NUM); #if 1 font_into_sleep(); #include "EPD.h" epd_sleep(SCREEN_LEFT); epd_sleep(SCREEN_RIGHT); //gpio_hold_en(PIN_L_CS); //gpio_hold_en(PIN_R_CS); // gpio_set_level(PIN_L_CS,1); // gpio_set_level(PIN_R_CS,1); //gpio_reset_pin(46); //uart_wait_tx_idle_polling(CONFIG_ESP_CONSOLE_UART_NUM); //ESP_ERROR_CHECK(uart_wait_tx_done(UART_NUM_1,portMAX_DELAY)); esp_sleep_disable_wakeup_source(ESP_SLEEP_WAKEUP_TIMER); // gpio_set_level(LORA_TXD_PIN, 0); // gpio_set_level(LORA_RXD_PIN, 0); //uart_sleep_in_config(); uart_driver_delete(UART_NUM_1); gpio_reset_pin(LORA_TXD_PIN); gpio_reset_pin(LORA_RXD_PIN); gpio_config_t io_conf = {}; io_conf.pin_bit_mask = (1<= Machine_info.left_max_Quick_refresh_time) { Machine_info.left_current_Quick_refresh_time = 0; Paint_leftScreen_main_slow(&info); } else { // printf("left_current_Quick_refresh_time = %d,Machine_info.left_max_Quick_refresh_time= %d\r\n",Machine_info.left_current_Quick_refresh_time,Machine_info.left_max_Quick_refresh_time); Machine_info.left_current_Quick_refresh_time++; Paint_leftScreen_main_quick(&info); } printf("left 还锁\n"); //xSemaphoreGive(screen_semaphore); } else { ESP_LOGE(LOG_TAG,"left 拿锁失败 \n"); } while(1) { if( (left_refresh_timer_isActive() == false) ) { printf("7left refresh complete %s\r\n",left_refresh_timer_isActive()?"true":"false"); break; } vTaskDelay(100/ portTICK_PERIOD_MS); } if( (Machine_info.power_status == 1)&& (Machine_info.paired == 1) //已配对 ) { sleep_timer_start(100); //进入睡眠 } if(Machine_info.power_status == 0) { printf("=>deep sleep\r\n"); uart_wait_tx_idle_polling(CONFIG_ESP_CONSOLE_UART_NUM); //vTaskDelay(100/ portTICK_PERIOD_MS); #if 1 //电源按键 // adc_oneshot_del_unit(adc1_handle); gpio_reset_pin(4); int ext_wakeup_pin_0 = 4; printf("Enabling EXT0 wakeup on pin GPIO%d\n", ext_wakeup_pin_0); ESP_ERROR_CHECK(esp_sleep_enable_ext0_wakeup(ext_wakeup_pin_0, 0)); // Configure pullup/downs via RTCIO to tie wakeup pins to inactive level during deepsleep. // EXT0 resides in the same power domain (RTC_PERIPH) as the RTC IO pullup/downs. // No need to keep that power domain explicitly, unlike EXT1. ESP_ERROR_CHECK(rtc_gpio_pullup_en(ext_wakeup_pin_0)); ESP_ERROR_CHECK(rtc_gpio_pulldown_dis(ext_wakeup_pin_0)); esp_sleep_pd_config(ESP_PD_DOMAIN_RTC_PERIPH, ESP_PD_OPTION_ON); ESP_ERROR_CHECK( esp_sleep_enable_ulp_wakeup()); #endif //adc_oneshot_del_unit(adc1_handle); esp_deep_sleep_start(); } // if(Machine_info.paired == 1) //已配对 // { // if(is_sleep == false) //已经进入sleep定时器 // { // printf("已配对 进入睡眠\n"); // sleep_timer_start(100); //进入睡眠 // } // } #if 0 int reson = is_wake_up_reson(); //返回唤醒的原因 /* ULP Risc-V read and detected a temperature above the limit */ if (reson == ESP_SLEEP_WAKEUP_ULP || reson == ESP_SLEEP_WAKEUP_TIMER) { //lora_set_power_level(0); #if 0 font_into_sleep(); //关闭外设电源 epd_sleep(SCREEN_LEFT); epd_sleep(SCREEN_RIGHT); #endif #if USER_LIGHT_SLEEP_ENABLE if(is_sleep == true) //已经进入sleep定时器 { printf("display refresh commplete ready sleep\r\n"); if(Machine_info.paired == 1) //已配对 { //if(is_sleep == false) //已经进入sleep定时器 { sleep_timer_start(100); //进入睡眠 } } }else { printf("display refresh commplete not into sleep\r\n"); } //esp_sleep_enable_timer_wakeup(TIMER_WAKEUP_TIME_US); //配置当前休眠的唤醒时间 //esp_light_sleep_start(); #endif #if USER_DEEP_SLEEP_ENABLE //esp_sleep_disable_wakeup_source(ESP_SLEEP_WAKEUP_TIMER); //重新配置休眠唤醒时间 //esp_sleep_enable_timer_wakeup(TIMER_WAKEUP_TIME_US); //配置当前休眠的唤醒时间 //esp_deep_sleep_start(); #endif }else { if(Machine_info.paired == 1) //已配对 { if(is_sleep == false) //已经进入sleep定时器 { printf("已配对 进入睡眠\n"); sleep_timer_start(100); //进入睡眠 } } } #endif } } } static void right_screen_task(void* arg) { extern bool is_sleep; #if USER_DEEP_SLEEP_ENABLE int reson = is_wake_up_reson(); //返回唤醒的原因 if ((reson != ESP_SLEEP_WAKEUP_ULP) && (reson != ESP_SLEEP_WAKEUP_TIMER)) { vTaskDelay(1000 / portTICK_PERIOD_MS); Paint_rightScreen_main_powerON(); } #endif // #if USER_NOT_SLEEP_ENABLE || USER_LIGHT_SLEEP_ENABLE // //vTaskDelay(1000 / portTICK_PERIOD_MS); // Paint_rightScreen_main_powerON(); // #endif int reson = is_wake_up_reson(); //返回唤醒的原因 //if ((reson != ESP_SLEEP_WAKEUP_ULP) && (reson != ESP_SLEEP_WAKEUP_TIMER)&&(reson != ESP_SLEEP_WAKEUP_EXT0)) { Paint_rightScreen_main_powerON(); } vTaskDelay(3000 / portTICK_PERIOD_MS); Machine_info.rssi = 100;//没有获取到真数据,默认100 Machine_info_t info; while(1) { if(xQueueReceive(right_screen_queue, &info, (TickType_t)portMAX_DELAY)) { font_exit_sleep(); ESP_LOGD(LOG_TAG,"right_screen_task"); printf("refresh %d,max %d\r\n",Machine_info.right_current_Quick_refresh_time,Machine_info.right_max_Quick_refresh_time); printf("right 拿锁\n"); //if(xSemaphoreTake(screen_semaphore, portMAX_DELAY) == true) if(1) { if(Machine_info.right_current_Quick_refresh_time >= Machine_info.right_max_Quick_refresh_time) { Machine_info.right_current_Quick_refresh_time = 0; Paint_rightScreen_main_slow(&info); }else { Machine_info.right_current_Quick_refresh_time++; // Paint_rightScreen_main_quick(&info); Paint_rightScreen_main_slow(&info); } printf("right 还锁\n"); //xSemaphoreGive(screen_semaphore); } else { ESP_LOGE(LOG_TAG,"right 拿锁失败 \n"); } while(1) { if( (right_refresh_timer_isActive() == false) ) { printf("8left refresh complete %s\r\n",right_refresh_timer_isActive()?"true":"false"); break; } vTaskDelay(100/ portTICK_PERIOD_MS); } #if 1 int reson = is_wake_up_reson(); //返回唤醒的原因 /* ULP Risc-V read and detected a temperature above the limit */ if (reson == ESP_SLEEP_WAKEUP_ULP || reson == ESP_SLEEP_WAKEUP_TIMER) { //lora_set_power_level(0); #if USER_LIGHT_SLEEP_ENABLE if(is_sleep == true) //已经进入sleep定时器 { printf("display right refresh commplete ready sleep\r\n"); if(Machine_info.paired == 1) //已配对 { //if(is_sleep == false) //已经进入sleep定时器 { sleep_timer_start(100); //进入睡眠 } } }else { printf("display right refresh commplete not into sleep\r\n"); } //esp_sleep_enable_timer_wakeup(TIMER_WAKEUP_TIME_US); //配置当前休眠的唤醒时间 //esp_light_sleep_start(); #endif #if 0 font_into_sleep(); //关闭外设电源 epd_sleep(SCREEN_LEFT); epd_sleep(SCREEN_RIGHT); #endif #if USER_LIGHT_SLEEP_ENABLE //esp_sleep_enable_timer_wakeup(TIMER_WAKEUP_TIME_US); //配置当前休眠的唤醒时间 //esp_light_sleep_start(); #endif #if USER_DEEP_SLEEP_ENABLE //重新配置休眠唤醒时间 //esp_sleep_enable_timer_wakeup(TIMER_WAKEUP_TIME_US); //配置当前休眠的唤醒时间 //esp_deep_sleep_start(); #endif }else { if(Machine_info.paired == 1) //已配对 { if(is_sleep == false) //已经进入sleep定时器 { sleep_timer_start(100); //进入睡眠 } } printf("sleep = %d\r\n",is_sleep); } #endif } } } static void button_task(void* arg) { //update_last_button_info(Machine_info.current_button.button_info);//初始化上个按键为运行,用作paint0703计时 uint8_t button_info; while(1) { if(xQueueReceive(button_Data_queue, &button_info, (TickType_t)portMAX_DELAY)) { ESP_LOGI(LOG_TAG,"btn_flag[%d][%d][%d][%d][%d][%d],button_info = [%d]%s ",Machine_info.btn_dis_flag[0],\ Machine_info.btn_dis_flag[1],Machine_info.btn_dis_flag[2],Machine_info.btn_dis_flag[3],Machine_info.btn_dis_flag[4],\ Machine_info.btn_dis_flag[5],button_info,Machine_info.power_status?"开机":"关机"); ESP_LOGI(LOG_TAG,"batt_precent[%d]\ncid[%s]\nlast_button[%d]\nlora_new_channel[%d]\neflagID[%d]\nDuration_time[%ld]rssi[%d]paired[%s]",\ Machine_info.batt_precent,\ Machine_info.cid,\ Machine_info.last_button.button_info,\ Machine_info.lora_new_channel,\ Machine_info.eflagID,\ Machine_info.Duration_time,\ Machine_info.rssi,\ Machine_info.paired?"已配网":"未配网"); if(button_info < 0x12) //左屏慕按键 { if(Machine_info.btn_dis_flag[button_info-1] == false) { printf("按键关闭,默认运行\n"); button_info = STATE_OPERATION;//按键关闭,默认运行 if((Machine_info.power_status == 1) && (Machine_info.paired == 1)) { sleep_timer_start(100); //进入睡眠 } } Machine_info .current_button.button_info = button_info; //判断当前的按键状态 设置为当前状态后 再次按键不处理 printf("last btn = %d ,curr btn = %d\n",Machine_info.last_button.button_info , Machine_info.current_button.button_info); if(Machine_info.last_button.button_info != Machine_info.current_button.button_info) { if(Machine_info.paired == 1) { printf("paired add data to list chanl = 0x%02x\r\n",Machine_info.lora_new_channel); getRtcTime(&Machine_info); //获取当前时间 //更新当前时间 Machine_info.current_button.button_info = button_info; Machine_info.current_button.Year = Machine_info.year; Machine_info.current_button.Month = Machine_info.month; Machine_info.current_button.Day = Machine_info.day; Machine_info.current_button.Hour = Machine_info.hour; Machine_info.current_button.Minute = Machine_info.min; Machine_info.current_button.Second = Machine_info.sec; long long current_Duration_time = calculate_minutes_difference ( Machine_info.last_button.Year, Machine_info.last_button.Month , Machine_info.last_button.Day , Machine_info.last_button.Hour , Machine_info.last_button.Minute , Machine_info.last_button.Second , Machine_info.current_button.Year, Machine_info.current_button.Month , Machine_info.current_button.Day , Machine_info.current_button.Hour , Machine_info.current_button.Minute , Machine_info.current_button.Second ); Machine_info.Duration_time = current_Duration_time;//持续时长 printf("Machine_info.Duration_time = %ld\r\n",Machine_info.Duration_time); terminal_send_data(); //添加数据队列 #if 0 printf("list before\r\n"); printList(Send_list); if(Machine_info.Duration_time == 0) { deleteNode_head(Send_list); } printf("list after\r\n"); printList(Send_list); #endif set_status_heights(); Machine_info.Duration_time = 0; //更新上次的状态 update_last_button_info(Machine_info.last_button.button_info); }else { // f_send_get_chart_data(); printf("not add data to list\r\n"); } Machine_info.last_button.button_info = Machine_info.current_button.button_info; // Machine_info.left_state = button_info; Machine_info.left_state = Machine_info.current_button.button_info; ESP_LOGE(LOG_TAG,"----Machine_info.left_state = %d",Machine_info.left_state); #if 1 if(xQueueSend(left_screen_queue,&Machine_info,portMAX_DELAY) != true) { ESP_LOGE(LOG_TAG,"queue:left_screen_queue"); } #endif // Set duty to 50% ESP_ERROR_CHECK(ledc_set_duty(LEDC_MODE, LEDC_CHANNEL, LEDC_DUTY)); // Update duty to apply the new value ESP_ERROR_CHECK(ledc_update_duty(LEDC_MODE, LEDC_CHANNEL)); vTaskDelay(30 / portTICK_PERIOD_MS); ESP_ERROR_CHECK(ledc_set_duty(LEDC_MODE, LEDC_CHANNEL, 0)); // Update duty to apply the new value ESP_ERROR_CHECK(ledc_update_duty(LEDC_MODE, LEDC_CHANNEL)); //printList(Send_list); //printList(list_head); } else//和上个按键重复,唤醒原因为ulp唤醒,不进入休眠 { printf("和上个按键重复,唤醒原因为ulp唤醒,不进入休眠\r\n"); sleep_timer_start(100); //开始进入倒计时休眠 } }else //右屏幕按键触发 { if(button_info == POWER_ON_PRESS_VALUE) //power 开机时短按 { // Set duty to 50% ESP_ERROR_CHECK(ledc_set_duty(LEDC_MODE, LEDC_CHANNEL, LEDC_DUTY)); // Update duty to apply the new value ESP_ERROR_CHECK(ledc_update_duty(LEDC_MODE, LEDC_CHANNEL)); vTaskDelay(30 / portTICK_PERIOD_MS); ESP_ERROR_CHECK(ledc_set_duty(LEDC_MODE, LEDC_CHANNEL, 0)); // Update duty to apply the new value ESP_ERROR_CHECK(ledc_update_duty(LEDC_MODE, LEDC_CHANNEL)); if( (Machine_info.power_status == 1) && (Machine_info.paired == 1)) { //判断当前开机 是否配对 继续执行时间片操作 sleep_timer_start(100); //开始进入倒计时休眠 } } if(button_info == POWER_OFF_PRESS_VALUE) //power 关机时短按 { sleep_timer_start(100); //开始进入倒计时休眠 } if(button_info == POWER_ON_INTO_STATUS_CHANGE_VALUE) //power 长按触发 { // Set duty to 50% ESP_ERROR_CHECK(ledc_set_duty(LEDC_MODE, LEDC_CHANNEL, LEDC_DUTY)); // Update duty to apply the new value ESP_ERROR_CHECK(ledc_update_duty(LEDC_MODE, LEDC_CHANNEL)); vTaskDelay(1000 / portTICK_PERIOD_MS); ESP_ERROR_CHECK(ledc_set_duty(LEDC_MODE, LEDC_CHANNEL, 0)); // Update duty to apply the new value ESP_ERROR_CHECK(ledc_update_duty(LEDC_MODE, LEDC_CHANNEL)); if(Machine_info.power_status == 1) //开机状态 { Machine_info.power_status = 0; dis_instructions(); vTaskDelay(1000 / portTICK_PERIOD_MS); sleep_timer_start(100); //开始进入倒计时休眠 printf("last power on current power off ready sleep\r\n"); // sleep_timer_start(100); //开始进入倒计时休眠 //更改为刷完两个屏幕,倒计时 } else if(Machine_info.power_status == 0) { printf("power on\r\n"); Machine_info.power_status = 1; lora_set_power_level(1); font_exit_sleep(); gpio_hold_dis(LORA_TXD_PIN); gpio_hold_dis(LORA_RXD_PIN); gpio_hold_dis(PIN_L_CS); gpio_hold_dis(PIN_R_CS); //恢复串口i功能 uart_sleep_out_config(); Paint_leftScreen_main_slow(&Machine_info); Paint_rightScreen_main_slow(&Machine_info); // Paint_leftScreen_main_quick(&Machine_info); // Paint_rightScreen_main_quick(&Machine_info); if( (Machine_info.power_status == 1) && (Machine_info.paired == 1)) { //判断当前开机 是否配对 继续执行时间片操作 sleep_timer_start(100); //开始进入倒计时休眠 } } } if(button_info == POWER_ON_INTO_DIS_RIGHT) { if(xQueueSend(right_screen_queue,&Machine_info,portMAX_DELAY) != true) { ESP_LOGE(LOG_TAG,"queue:right_screen_queue"); } } if(button_info == POWER_ON_INTO_OTA_VALUE) //进入OTA模式 { beep_blink(50,3); printf("into ota mode\r\n"); esp_ble_ota(); } if(button_info == POWER_ON_INTO_RESET_VALUE) //进入配网模式 { beep_blink(2000,1); printf("into reset mode\r\n"); font_exit_sleep(); lora_set_power_level(1); uart_sleep_out_config(); #include "user_sleep.h" //#include "esp_sleep.h" extern void sleep_timer_stop(); extern void Already_send_timer_stop(); sleep_timer_stop(); Already_send_timer_stop(); // //修改信道前修改设备ID 及 设备ID // dymatic_change_device_id(0x00000001); // dymatic_change_dst_device_id(0xFFFFFFFF); // //切换信道 // dymatic_change_chanel(Machine_info.lora_factory_channel); //切换信道 // // spiffs_read(&Machine_info); vTaskDelay(300 / portTICK_PERIOD_MS); reset_default(); reset_lora(); vTaskDelay(300 / portTICK_PERIOD_MS); } } } } } static void business_logic_task(void* arg) { //YC_DATA_T tmp; int len = 0; bool is_refresh =false; for(;;) { if(xQueueReceive(yc_data_queue, &len, (TickType_t)portMAX_DELAY)) { #if 1 is_refresh = subcontract(&yc_data); if(is_refresh) { screen_display(); }else { printf("not display fresh\r\n"); } #endif free(yc_data.data); //释放内存 yc_data.data = NULL; yc_data.len = 0; yc_data.index = 0; } } } static void unpack_task(void* arg) { LORA_DATA_T tmp_data; extern esp_timer_handle_t lora_timer; for(;;) { if(xQueueReceive(lora_data_queue, &tmp_data, (TickType_t)portMAX_DELAY)) { if(!esp_timer_is_active(lora_timer)) { lora_timer_start(); } else { lora_timer_restart(); } yc_data.len += tmp_data.data_len; memcpy(yc_data.data+yc_data.index,tmp_data.data_buf,tmp_data.data_len); yc_data.index += tmp_data.data_len; } } } static void lora_task(void* arg) { lora_event_task(arg); } // /********************************************************************************* // * function : Sendlist_task_callback_handler // * Description : 发送处理链表函数 // * Input : // * Output : // * Author : 祁鑫 Data : 2023 9.12 // **********************************************************************************/ // void Sendlist_task_callback_handler() // { // int length = 0; // uint8_t* result = (uint8_t*) malloc(buffer_size+1); // TickType_t xLastWakeTime; // #if 0 // const TickType_t xFrequency = 400/10; // 定时通知的间隔 // #else // const TickType_t xFrequency = 500/10; // 定时通知的间隔 // #endif // // 初始化xLastWakeTime // xLastWakeTime = xTaskGetTickCount(); // int receive_times = 0; // int user_size = 0; // int result_length = 0; // //int result_length = 0; // static int result_index = 0; // int result_data_len = 0; // while (1) { // #if 0 // //定时通知数据处理任务有新数据可用 // vTaskDelayUntil(&xLastWakeTime, xFrequency); // #endif // if(xQueueReceive(Send_Data_queue, &length, portMAX_DELAY) == pdPASS) // { // //int len = countNodes(Send_list); /* returns the number of nodes in the list */ // Node *list = Send_list; //发送数据链表 // int len = countNodes(Send_list); /* returns the number of nodes in the list */ // if(len!=0) // { // printf("current wait send num data=%d\r\n",len); // #if 1 // //int len = countNodes(list); /* returns the number of nodes in the list */ // while(len) // { // //int busy = get_lora_busy_pin(); // //printf("busy = %d\r\n",busy); // printf("send times\r\n"); // //if() // lora_send_data((char *)list->data,list->len); // list=list->next; // len--; // } // //Send_list = deleteList(Send_list); // free(list); // #endif // } // #if 0 // for (int i = 0; i < len; i++) // { // printf("%02x",result[i]); // } // #endif // } // } // } /********************************************************************************* * function : uart_task_callback_handler * Description : 串口0函数 * Input : * Output : * Author : 祁鑫 Data : 2023 9.12 **********************************************************************************/ void uart_task_callback_handler() { // #include "driver/uart.h" // uint8_t dtmp[200]= {0}; // while (1) // { // printf("uart 0 rev = "); // int len = uart_read_bytes(UART_NUM_0, dtmp, 1024,200/portTICK_PERIOD_MS); // if(len) // { // for(int i = 0;i=0) #endif if(user_size>0) { #if 0 for (int i = 0; i < len; i++) { printf("%02x",result[i]); } #endif printf("times comming length=%d\r\n",user_size); if(user_size == 36) { y_ringbuf_read_clear(lora_ringbuf, result, user_size); //读取并清除数据 } #if 1 int len = y_ringbuf_read_clear(lora_ringbuf, result, user_size); //读取并清除数据 yc_data.len = user_size; yc_data.data = malloc(sizeof(uint8_t)*user_size);//分配内存 memcpy(yc_data.data,result,user_size); //lora_send_queue_callback(result,len); //发送消息处理函数 if(xQueueSend(yc_data_queue,&len,0) != true) { ESP_LOGE(LOG_TAG,"yc_data_queue send is fail"); } #endif #if USER_OTA if((user_size>1024)||(user_size == 0) || (((user_size<1024))&&(is_ota ==true)) ) if(xQueueSend(ota_queue,&user_size,0) != true) { ESP_LOGE(LOG_TAG,"ota_queue send is fail"); } #endif } } #else int length = 0; uint8_t* result = (uint8_t*) malloc(buffer_size+1); int user_size = 0; while(1){ if(xQueueReceive(lora_dealhandle, &length, portMAX_DELAY) == pdPASS) { if(rssi!=0) { Machine_info.rssi = rssi; } //printf("deal data\r\n"); user_size = y_ringbuf_get_used_size(lora_ringbuf); if(user_size>0) { printf("times comming length=%d\r\n",user_size); #if 0 if(user_size == 36) { y_ringbuf_read_clear(lora_ringbuf, result, user_size); //读取并清除数据 #if 1 for (int i = 0; i < user_size; i++) { printf("%02x",result[i]); } #endif }else #endif { #if 1 int len = y_ringbuf_read_clear(lora_ringbuf, result, user_size); //读取并清除数据 #if 1 for (int i = 0; i < user_size; i++) { printf("%02x",result[i]); } printf("\r\n"); #endif yc_data.len = user_size; yc_data.data = malloc(sizeof(uint8_t)*user_size);//分配内存 memcpy(yc_data.data,result,user_size); //lora_send_queue_callback(result,len); //发送消息处理函数 if(xQueueSend(yc_data_queue,&len,(TickType_t)portMAX_DELAY) != true) { ESP_LOGE(LOG_TAG,"yc_data_queue send is fail"); } #endif } } } } #endif } // #define MY_DISP_HOR_RES 648 // #define MY_DISP_VER_RES 480 // #define DISP_BUF_SIZE (480 * 648) // volatile bool disp_flush_enabled = true; // /* Enable updating the screen (the flushing process) when disp_flush() is called by LVGL // */ // void disp_enable_update(void) // { // disp_flush_enabled = true; // } // /* Disable updating the screen (the flushing process) when disp_flush() is called by LVGL // */ // void disp_disable_update(void) // { // disp_flush_enabled = false; // } // /*Flush the content of the internal buffer the specific area on the display. // *`px_map` contains the rendered image as raw pixel map and it should be copied to `area` on the display. // *You can use DMA or any hardware acceleration to do this operation in the background but // *'lv_display_flush_ready()' has to be called when it's finished.*/ // void disp_driver_flush(lv_disp_drv_t * drv, const lv_area_t * area, lv_color_t * color_map) // // static void disp_flush(lv_display_t * disp_drv, const lv_area_t * area, lv_color_t * px_map) // { // //printf("-------------------disp_flush \r\n"); // if(disp_flush_enabled) { // /*The most simple case (but also the slowest) to put all pixels to the screen one-by-one*/ // int32_t x; // int32_t y; // printf("%d,%d,%d,%d\r\n",area->x1, area->y1, area->x2, area->y2); // epd_partial_cache1( area->x1, area->y1, area->x2, area->y2,SCREEN_LEFT,color_map); // epd_powerOn_refresh(SCREEN_LEFT); // #if 0 // for(y = area->y1; y <= area->y2; y++) { // for(x = area->x1; x <= area->x2; x++) { // printf("%ld,%ld\r\n",x,y); // /*Put a pixel to the display. For example:*/ // /*put_px(x, y, *px_map)*/ // px_map++; // } // } // #endif // } // /*IMPORTANT!!! // *Inform the graphics library that you are ready with the flushing*/ // #if 0 // lv_display_flush_ready(disp_drv); // #else // lv_disp_flush_ready(drv); // #endif // } // #if 0 // static uint8_t *buf_3_1; // static uint8_t *buf_3_2; // #else // static uint8_t *buf; // #endif // static void gui_task(void* pvParameter) // { // #if 0 // lv_init(); // //buf= heap_caps_malloc(DISP_BUF_SIZE * sizeof(lv_color_t), MALLOC_CAP_DMA|MALLOC_CAP_SPIRAM); // //assert(buf != NULL); // /*------------------------------------ // * Create a display and set a flush_cb // * -----------------------------------*/ // lv_display_t * disp = lv_display_create(MY_DISP_HOR_RES, MY_DISP_VER_RES); // lv_display_set_flush_cb(disp, disp_flush); // /* Example 3 // * Two buffers screen sized buffer for double buffering. // * Both LV_DISPLAY_RENDER_MODE_DIRECT and LV_DISPLAY_RENDER_MODE_FULL works, see their comments*/ // buf_3_1= heap_caps_malloc(MY_DISP_HOR_RES *MY_DISP_VER_RES, MALLOC_CAP_8BIT); // buf_3_2= heap_caps_malloc(MY_DISP_HOR_RES *MY_DISP_VER_RES, MALLOC_CAP_8BIT); // if(buf_3_1 ==NULL) // { // printf("-------------------buf_3_1 \r\n"); // } // if(buf_3_2 ==NULL) // { // printf("-------------------buf_3_2 \r\n"); // } // lv_display_set_draw_buffers(disp, buf_3_1, buf_3_2, sizeof(buf_3_1)*MY_DISP_HOR_RES *MY_DISP_VER_RES, LV_DISPLAY_RENDER_MODE_DIRECT); // lv_theme_t * th = lv_theme_mono_init(disp, true, &lv_font_montserrat_14); // bool is = lv_theme_mono_is_inited(); // if(is)printf("========================ok=================\r\n"); // else printf("========================fail=================\r\n"); // lv_disp_set_theme(disp, th); /*Assign the theme to the display*/ // /*Create a white label, set its text and align it to the center*/ // lv_obj_t * label = lv_label_create(lv_scr_act()); // lv_label_set_text(label, "Hello world"); // lv_obj_set_style_text_color(lv_scr_act(), lv_color_hex(0xffffff), LV_PART_MAIN); // lv_obj_align(label, LV_ALIGN_CENTER, 0, 0); // #else // lv_init(); // //disp_driver_init(); // static lv_disp_draw_buf_t disp_buf; // uint32_t size_in_px = DISP_BUF_SIZE; // buf= heap_caps_malloc(MY_DISP_HOR_RES *MY_DISP_VER_RES, MALLOC_CAP_8BIT); // lv_disp_draw_buf_init(&disp_buf, buf, NULL, size_in_px); // lv_disp_drv_t disp_drv; // lv_disp_drv_init(&disp_drv); // disp_drv.flush_cb = disp_driver_flush; // disp_drv.hor_res = 648; // disp_drv.ver_res = 480; // disp_drv.full_refresh = 1; // disp_drv.draw_buf = &disp_buf; // lv_disp_t * disp = lv_disp_drv_register(&disp_drv); // lv_disp_rot_t dir = lv_disp_get_rotation(disp); // lv_disp_set_rotation(disp, LV_DISP_ROT_180); // printf("dir=%d\r\n",dir); // /*Create a white label, set its text and align it to the center*/ // lv_obj_t * label = lv_label_create(lv_scr_act()); // lv_label_set_text(label, "Hello world"); // lv_obj_set_style_bg_color(lv_scr_act(), lv_color_make(0,0,0), 0);//设置背景颜色为白色 // lv_obj_set_style_text_color(lv_scr_act(), lv_color_hex(0xffffff), LV_PART_MAIN); // lv_obj_align(label, LV_ALIGN_CENTER, 0, 0); // lv_obj_t * label1 = lv_label_create(lv_scr_act()); // lv_label_set_text(label1, "world"); // //lv_obj_set_style_bg_color(lv_scr_act(), lv_color_make(0,0,0), 0);//设置背景颜色为白色 // lv_obj_set_style_text_color(lv_scr_act(), lv_color_hex(0xffffff), LV_PART_MAIN); // //lv_obj_align(label, LV_ALIGN_CENTER, 0, 0); // lv_obj_set_pos(label1,0,20); // //sgf_lvgl_display(&info); // lv_refr_now(NULL); // // if (wait_second != 0) { // // ESP_LOGI(TAG, "wait=%ds", wait_second); // // vTaskDelay(pdMS_TO_TICKS(1000 * wait_second)); // // } // // gpio_weekup_init_s(sleep_second); // #endif // //lv_refr_now(disp); // for(;;) { // lv_tick_inc(10); /*Use a not round number to cover more anim states */ // lv_timer_handler(); // vTaskDelay(10 / portTICK_PERIOD_MS); // } // }