#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; 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; u8 NUM = 1; u8 n; u16 i; u8 chour; u8 cminute; u8 hot_clod_flag = 0; u8 humidity_flag = 0; u8 ALARM = 0; u16 tick = 0; u8 Feed_Dog_Count = 0; // Feeding dog timing u8 now_stage = 1; // Current operational phase u16 tem, hum; u8 lights[9]; u8 lights_addresses[9] = { 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29 }; 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; 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); delay_xms(100); // 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; void HotTestRequestTask(void *pvParameters) { while (1) { // if (!(T == 0 && H == 0)) { // // if (!(abs(pid.out_tem) < 1e-5 && abs(pid.out_humidity) < 1e-5)) { // // } // PID_Calc(); // RS485_1_Upload_Params(); // } 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, lights); 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, lights); // 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); light_set_all(); RS485_1_Upload_Params(); } 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, lights); // update param correspond to current stage Write_Init(); RX_BUF_Transfer(0, 9); light_set_all(); // if temp or humidity is been change, then calc pid right now, and upload params if (i == 4 || i == 5) { // take tem to set_tem immediately pid.set_tem = tem / 10.0; PID_Calc(); } RS485_1_Upload_Params(); } 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); PID_Calc(); 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[17] == 0xFF && RS485_RX_BUF[18] == 0xFF) { RX_BUF_Transfer(0, 19); } 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) { 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, 16); } else if (RS485_RX_BUF_COPY[0] == 0xEE && RS485_RX_BUF_COPY[1] == 0xB1 && RS485_RX_BUF_COPY[2] == 0x01 && RS485_RX_BUF_COPY[8] == 0xFF && RS485_RX_BUF_COPY[9] == 0xFF) { RX_BUF_Transfer(0, 10); } 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]; if ((T < (tem - 20) || T > (tem + 20) || H < (hum - 100) || H > (hum + 100)) && (tick > 600)) { gpio_state |= 0x01; ALARM = 1; } else { gpio_state &= 0xFE; ALARM = 0; } // check current set temp and perv set temp, if diff is greater then 3degree, then reInit pid if (abs(pid.set_tem - tem / 10.0) > 3) { PID_Init(); } 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)) { gpio_state |= 0x08; gpio_state &= 0xEF; humidity_flag = 1; } if (H < (hum - 50)) { gpio_state |= 0x10; gpio_state &= 0xF7; humidity_flag = 2; } if (humidity_flag == 1 && H <= hum) { gpio_state &= 0xE7; humidity_flag = 0; } if (humidity_flag == 2 && H >= hum) { gpio_state &= 0xE7; humidity_flag = 0; } PID_Calc(); // 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 = (float)out_humidity / 10; } /** * 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(); PID_Calc(); RS485_1_Upload_Params(); } break; } } } void light_set(u8 address, u8 value) { u8 data[8] = { address, 0x06, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00 }; if (value > 100) { value = 100; } data[4] = value / 256; data[5] = value % 256; GetCRC16(data, 6, data + 6, data + 7); delay_xms(10); RS485_1_Send_Data(data, 8); } void light_set_all(void) { // RS485_2_Init(9600); RS485_3_Init(9600); delay_xms(30); for (int i = 0; i < 9; i++) { // set light i light_set(lights_addresses[i], lights[i]); } // RS485_1_Init(9600); delay_xms(30); RS485_1_Init(9600); }