#include "myfreertos.h" #define SENSOR_ADDRESS 0x02 #define INNER_SENSOR_ADDRESS 0x02 #define OUTER_SENSOR_ADDRESS 0x04 char pubTopic[512] = "/sys/hp8oQhMZJ67/Device1/thing/event/property/post"; // Publish topic char subTopic[512] = "/sys/hp8oQhMZJ67/Device1/thing/service/property/set"; // Subscribe topic #define MQTT_SOCK 5 // task priority #define START_TASK_PRIO 1 // Task stack size #define START_STK_SIZE 128 // task handle TaskHandle_t StartTask_Handler; // task function void start_task(void *pvParameters); // task priority #define Sensor_Communication_TASK_PRIO 1 // Communication with sensors // Task stack size #define Sensor_Communication_STK_SIZE 512 // task handle TaskHandle_t Sensor_CommunicationTask_Handler; // task function void Sensor_Communication_task(void *pvParameters); void Host_Computer_Communication(void); // 5seconds delay #define SENSOR_DATA_REQUEST_PERIOD pdMS_TO_TICKS(5000) // 60seconds delay #define SYNC_ENVIRONMENT_DATA_REQUEST_PERIOD pdMS_TO_TICKS(60000) // 1seconds delay #define MAIN_TASK_PERIOD pdMS_TO_TICKS(1000) /** * sensor data request: 02 03 */ void SensorDataRequestTask(void *pvParameters); // task handle TaskHandle_t SensorDataRequestTask_Handler; /** * sync environment data: EE B5 01 */ void SyncEnvironmentDataRequestTask(void *pvParameters); // task handle TaskHandle_t SyncEnvironmentDataRequestTask_Handler; /** * 定时制热test */ void HotTestRequestTask(void *pvParameters); // task handle TaskHandle_t HotTestRequestTask_Handler; int isZeros(u8 arr[]); u8 RS485_RX_BUF_COPY[128] = {0}; u8 RS485_DATA_TMP[128] = {0}; u8 RS485_SUFFIX[4] = {0xFF, 0xFC, 0xFF, 0xFF}; u8 cnt_flag = 0, sub_flag = 0, pub_flag = 0; u16 time = 0; // Record the time of pinging the server char wet_temp[256]; // Cache area for subscription and publication of messages u8 store_stage = 1; // Write the stage number of the flash, and after a power outage and restart, it can run immediately following the previous stage and status extern PID pid; extern float kd; extern float ki; u8 batch_sync_buf[11]; // Array obtained by single synchronous cutting u8 ins_1 = 0; int diff = 0; u8 gpio_state = 0x00; // relay status u8 NUM = 1; // 批量同步发送的阶段号 u8 n; // 阶段号 u16 i; // 序列号 u8 chour; // 已运行小时数 u8 cminute; // 运行分钟数 u8 hot_clod_flag = 0; // 加热制冷标志位。hot_clod_flag=0, 不加热不制冷;hot_clod_flag=2,加热;hot_clod_flag=1,制冷 u8 humidity_flag = 0; // 加湿除湿标志位。 humidity_flag=0,不加湿不除湿; humidity_flag=2,加湿; humidity_flag=1,除湿 u8 ALARM = 0; // 报警标志位。ALARM=0,不报警;ALARM=1,报警 u16 tick = 0; // tick大于600,触发报警条件会报警;小于600则不报警 u8 Feed_Dog_Count = 0; // Feeding dog timing u8 now_stage = 1; // Current operational phase u16 tem, hum, red, blue, white; u8 hour, min; // u8 rs485buf[8] = {SENSOR_ADDRESS, 0x03, 0x00, 0x01, 0x00, 0x09, 0xD4, 0x3F}; // Sensor exchange data u8 INNER_SENSOR_485_REQUEST_COMMAND[8] = {INNER_SENSOR_ADDRESS, 0x03, 0x00, 0x01, 0x00, 0x09, 0xD4, 0x3F}; // Inner sensor exchange data u8 OUTER_SENSOR_485_REQUEST_COMMAND[8] = {OUTER_SENSOR_ADDRESS, 0x03, 0x00, 0x00, 0x00, 0x02, 0xC4, 0x5E}; // Outer sensor exchange data u16 sync_cnt = 0; // 同步环境控制参数的计数器,到0同步 int T = 0, H = 0, C = 0, G = 0, current_T = 0; extern u8 total[]; float Humidity = 0; float temperature = 0; // pages in hmi #define page_index 43 #define page_curve 45 #define page_setting 46 #define page_upgrade 23 #define page_scan_wifi 48 #define page_wifi_setting 49 #define page_param_adjust 50 #define page_status 51 // u8 RS485_RX_BUF[64]; /********************* ********************** entry function ********************** *********************/ void os_init(void) { // printf("Entry function call successful\r\n"); xTaskCreate((TaskFunction_t)start_task, (char *)"start_task", (uint16_t)START_STK_SIZE, (void *)NULL, (UBaseType_t)START_TASK_PRIO, (TaskHandle_t *)&StartTask_Handler); vTaskStartScheduler(); } /********************* ********************** Create handles for tasks, queues, signal sets, etc., which can also be tested using ********************** *********************/ BaseType_t handler = 0; BaseType_t handler1 = 0; BaseType_t handler2 = 0; BaseType_t handler3 = 0; BaseType_t handler4 = 0; BaseType_t handler5 = 0; BaseType_t handler6 = 0; BaseType_t handler7 = 0; BaseType_t handler8 = 0; BaseType_t handler9 = 0; BaseType_t handler10 = 0; BaseType_t handler11 = 0; /* Start function: Create other functions and timers */ void start_task(void *pvParameters) { taskENTER_CRITICAL(); // 进入临界区 // 创建与传感器通信任务 xTaskCreate( (TaskFunction_t)Sensor_Communication_task, (const char *)"Sensor_Communication_task", (uint16_t)Sensor_Communication_STK_SIZE, (void *)NULL, (UBaseType_t)Sensor_Communication_TASK_PRIO, (TaskHandle_t *)&Sensor_CommunicationTask_Handler); // if(handler==pdPASS){printf("与传感器通信任务创建成功\r\n");} // else{printf("与传感器通信任务创建失败\r\n");} // //创建控灯任务 // handler4=xTaskCreate((TaskFunction_t )led_task, // (const char* )"led_task", // (uint16_t )LED_STK_SIZE, // (void* )NULL, // (UBaseType_t )LED_TASK_PRIO, // (TaskHandle_t* )&LEDTask_Handler); // if(handler4==pdPASS){printf("控灯任务创建成功\r\n");} // else{printf("控灯任务创建失败\r\n");} // 创建传感器数据请求任务 xTaskCreate( (TaskFunction_t)SensorDataRequestTask, (const char *)"SensorDataRequestTask", (uint16_t)configMINIMAL_STACK_SIZE, (void *)NULL, (UBaseType_t)tskIDLE_PRIORITY + 2, (TaskHandle_t* )&SensorDataRequestTask_Handler); xTaskCreate( (TaskFunction_t)SyncEnvironmentDataRequestTask, (const char *)"SyncEnvironmentDataRequestTask", (uint16_t)configMINIMAL_STACK_SIZE, (void *)NULL, (UBaseType_t)tskIDLE_PRIORITY + 3, (TaskHandle_t* )&SyncEnvironmentDataRequestTask_Handler); xTaskCreate( (TaskFunction_t)HotTestRequestTask, (const char *)"HotTestRequestTask", (uint16_t)configMINIMAL_STACK_SIZE, (void *)NULL, (UBaseType_t)tskIDLE_PRIORITY + 4, (TaskHandle_t* )&HotTestRequestTask_Handler); vTaskDelete(StartTask_Handler); // 删除开始任务 taskEXIT_CRITICAL(); // 退出临界区 } void SensorDataRequestTask(void *pvParameters) { while (1) { // 发送传感器数据请求的操作 RS485_1_Send_Data_1(INNER_SENSOR_485_REQUEST_COMMAND, 8); vTaskDelay(100); RS485_1_Send_Data_1(OUTER_SENSOR_485_REQUEST_COMMAND, 8); vTaskDelay(100); // RS485_1_Send_Data_1(RS485_RX_BUF, 48); vTaskDelay(SENSOR_DATA_REQUEST_PERIOD - 200); } } void SyncEnvironmentDataRequestTask(void *pvParameters) { while (1) { RS485_1_sync_env_params(); vTaskDelay(SYNC_ENVIRONMENT_DATA_REQUEST_PERIOD); } } int hot = 0; /** * pid计算,每5秒一次 */ void HotTestRequestTask(void *pvParameters) { while (1) { if (!(T == 0 && H == 0)) { PID_Calc(); } vTaskDelay(5000); } } void Sensor_Communication_task(void *pvParameters) { while (1) { // HC595_Send_Byte(0x00); // cnt_flag=do_mqtt(MQTT_SOCK,NET_CONFIG.rip,1883,5500); // Humidity=H*0.1; // temperature=T*0.1; // delay_ms(50); // sprintf(wet_temp,"{\"method\":\"thing.event.property.post\",\"params\":{\"Humidity\":%.2f,\"temperature\":%.2f,\"CO2\":%d,\"red_light\":%d,\"white_light\":%d,\"blue_light\":%d},\"version\":\"1.0.0\"}",Humidity,temperature,C,red/10,white/10,blue/10); //构建数据 // //sprintf(wet_temp,"{\"method\":\"thing.event.property.post\",\"params\":{\"Humidity\":%.2f,\"temperature\":%.2f,\"CO2\":%d},\"version\":\"1.0.0\"}",Humidity,temperature,C); //构建数据 // if(cnt_flag==0){sub_flag=0;pub_flag=0;time=0;} // if(cnt_flag&&sub_flag==0)sub_flag=!subscribMqtt(MQTT_SOCK,subTopic); // if(cnt_flag&&sub_flag&&pub_flag==0)pub_flag=!publishMqtt(MQTT_SOCK,pubTopic,wet_temp); // if(cnt_flag)time++; // if(time==50){ // time=0; // pingMqtt(MQTT_SOCK); // } now_stage = timelong_Compare(); Array(&now_stage, &hour, &min, &tem, &hum, &red, &blue, &white); // 更新对应阶段号的参数 delay_xms(50); bufcut_Init(RS485_RX_BUF_COPY, RS485_RX_BUF, 0, 128); u8 c = 0; RS485_RX_CNT = 0; while (isAllZeros(RS485_RX_BUF_COPY, 128) == 0) { if (RS485_RX_BUF_COPY[0] == INNER_SENSOR_ADDRESS && RS485_RX_BUF_COPY[1] == 0x03 && CRC16_check(RS485_RX_BUF_COPY, 21) == 1) { c++; // receive message from sensor u8 temp_data[23] = {0}; for (int i=0;i<23;i++) { temp_data[i] = RS485_RX_BUF_COPY[i]; } process_inner_sensor_data(temp_data); RX_BUF_Transfer(0, 23); // u8 tmpaaa[] = {c}; // RS485_1_Send_Data_1(tmpaaa, 1); } else if (RS485_RX_BUF_COPY[0] == OUTER_SENSOR_ADDRESS && RS485_RX_BUF_COPY[1] == 0x03 && CRC16_check(RS485_RX_BUF_COPY, 7) == 1) { // receive message from sensor u8 temp_data[9] = {0}; for (int i = 0; i < 9; i++) { temp_data[i] = RS485_RX_BUF_COPY[i]; } process_outer_sensor_data(temp_data); RX_BUF_Transfer(0, 9); } else if (RS485_RX_BUF_COPY[0] == 0xEE && RS485_RX_BUF_COPY[1] == 0xB6 && RS485_RX_BUF_COPY[2] == 0x01 && CRC16_check(RS485_RX_BUF_COPY, 16) == 1) { // batch update params in a stage // total length: 18 Batch_synchronization(&n, RS485_RX_BUF_COPY); Array(&now_stage, &hour, &min, &tem, &hum, &red, &blue, &white); // update param correspond to current stage bufcut_Init(RS485_DATA_TMP, RS485_RX_BUF_COPY, 0, 18); RS485_DATA_TMP[18] = 0xFF; RS485_DATA_TMP[19] = 0xFC; RS485_DATA_TMP[20] = 0xFF; RS485_DATA_TMP[21] = 0xFF; RS485_1_Send_Data_1(RS485_DATA_TMP, 22); RX_BUF_Transfer(0, 18); } else if (RS485_RX_BUF_COPY[0] == 0xEE && RS485_RX_BUF_COPY[1] == 0xB6 && RS485_RX_BUF_COPY[2] == 0x03 && CRC16_check(RS485_RX_BUF_COPY, 7) == 1) { // update single environment param // total length: 9 Analysis(&n, &i, RS485_RX_BUF_COPY); Array(&now_stage, &hour, &min, &tem, &hum, &red, &blue, &white); // update param correspond to current stage Write_Init(); bufcut_Init(RS485_DATA_TMP, RS485_RX_BUF_COPY, 0, 9); bufcut_Init(RS485_DATA_TMP + 8, RS485_SUFFIX, 9, 13); RS485_1_Send_Data_1(RS485_DATA_TMP, 13); RX_BUF_Transfer(0, 9); } else if (RS485_RX_BUF_COPY[0] == 0xEE && RS485_RX_BUF_COPY[1] == 0xB6 && RS485_RX_BUF_COPY[2] == 0x04 && CRC16_check(RS485_RX_BUF_COPY, 4) == 1) { // change running stage // total length: 6 int target_stage = RS485_RX_BUF_COPY[3]; RTC_synchronization_ins(2023, 9, 1, 0, 00, 00); now_stage = target_stage; store_stage = target_stage; Write_Init(); bufcut_Init(RS485_DATA_TMP, RS485_RX_BUF_COPY, 0, 6); bufcut_Init(RS485_DATA_TMP + 8, RS485_SUFFIX, 6, 10); RS485_1_Send_Data_1(RS485_DATA_TMP, 10); // delay_ms(10); RS485_1_Upload_Params(); // 上传参数 RX_BUF_Transfer(0, 6); } else if (RS485_RX_BUF_COPY[0] == 0xEE && RS485_RX_BUF_COPY[1] == 0xB6 && RS485_RX_BUF_COPY[2] == 0x05) { // change pid params // total length: 8 int param_index = RS485_RX_BUF_COPY[3]; switch(param_index) { case 0x01: { pid.Kp = RS485_RX_BUF_COPY[4] * 256.0 + RS485_RX_BUF_COPY[5]; break; } case 0x02: { pid.Ki = (RS485_RX_BUF_COPY[4] * 256.0 + RS485_RX_BUF_COPY[5]) / 100000.0; break; } case 0x03: { pid.Kd = RS485_RX_BUF_COPY[4] * 256.0 + RS485_RX_BUF_COPY[5]; break; } case 0x04: { int tem_offset_10times = RS485_RX_BUF_COPY[4] * 256.0 + RS485_RX_BUF_COPY[5]; // Negative tem offset treatment if (tem_offset_10times & 0x8000) { tem_offset_10times = ((~tem_offset_10times + 1) & 0xFFFF); } pid.tem_offset = tem_offset_10times / 10.0; break; } case 0x05: { pid.tem_threshold = (RS485_RX_BUF_COPY[4] * 256.0 + RS485_RX_BUF_COPY[5]) / 10.0; break; } } Write_Init(); bufcut_Init(RS485_DATA_TMP, RS485_RX_BUF_COPY, 0, 8); RS485_DATA_TMP[8] = 0xFF; RS485_DATA_TMP[9] = 0xFC; RS485_DATA_TMP[10] = 0xFF; RS485_DATA_TMP[11] = 0xFF; RS485_1_Send_Data_1(RS485_DATA_TMP, 12); RX_BUF_Transfer(0, 8); } else if (RS485_RX_BUF_COPY[0] == 0xEE && RS485_RX_BUF_COPY[1] == 0xB1 && RS485_RX_BUF_COPY[2] == 0x11 && RS485_RX_BUF_COPY[15] == 0xFF && RS485_RX_BUF[16] == 0xFF) { RX_BUF_Transfer(0, 17); } else if (RS485_RX_BUF_COPY[0] == 0xEE && RS485_RX_BUF_COPY[1] == 0xB1 && RS485_RX_BUF_COPY[2] == 0x11 && RS485_RX_BUF_COPY[14] == 0xFF && RS485_RX_BUF[15] == 0xFF) { RX_BUF_Transfer(0, 16); } else if (RS485_RX_BUF_COPY[0] == 0xEE && RS485_RX_BUF_COPY[1] == 0xB1 && RS485_RX_BUF_COPY[2] == 0x11 && RS485_RX_BUF_COPY[12] == 0xFF && RS485_RX_BUF[13] == 0xFF) { process_hmi_btn_event(RS485_RX_BUF_COPY[3] * 256 + RS485_RX_BUF_COPY[4], RS485_RX_BUF_COPY[5] * 256 + RS485_RX_BUF_COPY[6], RS485_RX_BUF_COPY[9]); RX_BUF_Transfer(0, 14); } else if (RS485_RX_BUF_COPY[0] == 0xEE && RS485_RX_BUF_COPY[1] == 0xB1 && RS485_RX_BUF_COPY[2] == 0x01 && RS485_RX_BUF_COPY[7] == 0xFF && RS485_RX_BUF_COPY[8] == 0xFF) { RX_BUF_Transfer(0, 9); } else { int ZERO_Count = 0; if ((RS485_RX_BUF_COPY[0] != 0x00)) { RX_BUF_Transfer(0, 1); } while (RS485_RX_BUF_COPY[ZERO_Count] == 0x00) { ZERO_Count++; } RX_BUF_Transfer(0, ZERO_Count); } } // if (red <= 1000 && blue <= 1000) // { // PWM_SetCompare1((red / 100.0 * 3.5 + 28)); // J9 // PWM_SetCompare2((blue / 100.0 * 3.5 + 28)); // J11 // PWM_SetCompare4((white / 100.0 * 3.5 + 28)); // J10 // } RS485_RX_CNT = 0; vTaskDelay(MAIN_TASK_PERIOD); } } /** * process sensor data */ void process_inner_sensor_data(u8 *data) { T = data[3]; T = T << 8 | data[4]; // Negative temperature treatment if (T & 0x8000) { T = ((~T + 1) & 0xFFFF); } H = data[5]; H = H << 8 | data[6]; C = data[19]; C = C << 8 | data[20]; /*GPIO1->报警铃 GPIO3->加热棒 GPIO4—>新风风扇 GPIO5->加湿器 GPIO6->压缩机 */ if ((T < (tem - 20) || T > (tem + 20) || H < (hum - 100) || H > (hum + 100)) && (tick > 600)) // 温度偏差2℃报警,湿度偏差10报警 { // HC595_Send_Byte(gpio_state |= 0x01); // 打开报警铃 GPIO1->PB1 |=0000 0001 0x01 gpio_state |= 0x01; ALARM = 1; } else { // HC595_Send_Byte(gpio_state &= 0xFE); // 关闭报警铃 &=1111 1110 0xFE gpio_state &= 0xFE; ALARM = 0; } pid.set_tem = tem / 10.0; pid.now_tem = T / 10.0; // PID_Calc(); // send sign to 485 // out: 0-200 current_T = T; if (H > (hum + 50)) // 湿度高于设定值5,打开新风风扇 GPIO4->PD1 { // HC595_Send_Byte(gpio_state |= 0x08); // 打开新风风扇 |=0000 1000 0x08 gpio_state |= 0x08; // HC595_Send_Byte(gpio_state &= 0xEF); // 关闭加湿器 &=1110 1111 0xEF gpio_state &= 0xEF; humidity_flag = 1; // 除湿 } if (H < (hum - 50)) // 湿度低于设定值5,打开加湿器 GPIO5->PD0 { // HC595_Send_Byte(gpio_state |= 0x10); // 启动加湿器 |=0001 0000 0x10 gpio_state |= 0x10; // HC595_Send_Byte(gpio_state &= 0xF7); // 关闭风扇 &=1111 0111 0xF7 gpio_state &= 0xF7; humidity_flag = 2; } if (humidity_flag == 1 && H <= hum) { // HC595_Send_Byte(gpio_state &= 0xE7); // 关闭风扇 关闭加湿器 &=1110 0111 0xE7 gpio_state &= 0xE7; humidity_flag = 0; } if (humidity_flag == 2 && H >= hum) { // HC595_Send_Byte(gpio_state &= 0xE7); // 关闭加湿器 关闭风扇 &=1110 0111 0xE7 gpio_state &= 0xE7; humidity_flag = 0; } // HC595_Send_Byte(gpio_state); RS485_1_Upload_Params(); // 上传参数 // delay_xms(200); } /** * process outer sensor data */ void process_outer_sensor_data(u8 *data) { int out_tem = data[3]; out_tem = out_tem << 8 | data[4]; // Negative temperature treatment if (out_tem & 0x8000) { out_tem = ((~out_tem + 1) & 0xFFFF); } pid.out_tem = (float)out_tem / 10; int out_humidity = data[5]; out_humidity = out_humidity << 8 | data[6]; // Negative temperature treatment if (out_humidity & 0x8000) { out_humidity = ((~out_humidity + 1) & 0xFFFF); } pid.out_humidity = out_humidity; } /** * hmi event process */ void process_hmi_btn_event(u8 page, u8 btn_index, u8 value) { switch(page) { case page_param_adjust: { // change current stage if (btn_index >= 45 && btn_index <= 50 && value == 0x01) { int target_stage = btn_index - 44; RTC_synchronization_ins(2023, 9, 1, 0, 00, 00); now_stage = target_stage; store_stage = target_stage; Write_Init(); RS485_1_Upload_Params(); // 上传参数 } break; } } }