#include "myfreertos.h" char pubTopic[512]="/sys/hp8oQhMZJ67/Device1/thing/event/property/post";//发布的主题 char subTopic[512]="/sys/hp8oQhMZJ67/Device1/thing/service/property/set";//订阅的主题 #define MQTT_SOCK 5 u8 cnt_flag=0,sub_flag=0,pub_flag=0; u16 time=0;//记录ping服务器的时间 char wet_temp[256];//订阅与发布消息的缓存区 u8 store_stage=1;//写入flash的阶段号,断电重启后读取可以紧接着上次的阶段运行 extern PID pid; extern float kd; extern float ki; u8 batch_sync_buf[11];//单个同步剪切得到的数组 u8 ins_1=0; int diff=0; u8 gpio_state=0x02;//继电器状态 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 now_stage=1;//当前运行阶段 u16 tem,hum,red,blue,white; u8 hour,min; u8 change_stage_rev1=0; u8 change_stage_rev2=0; u8 change_stage_rev3=0; u8 rs485buf[8]={0x01,0x03,0x00,0x01,0x00,0x09,0xD4,0x0C};//传感器交换数据 int T=0,H=0,C=0,G=0, current_T=0; extern u8 total[]; float Humidity=0; float temperature=0; unsigned int num=0; //u8 RS485_RX_BUF[64]; //任务优先级 #define START_TASK_PRIO 0 //任务堆栈大小 #define START_STK_SIZE 128 //任务句柄 TaskHandle_t StartTask_Handler; //任务函数 void start_task(void *pvParameters); //任务优先级 #define Sensor_Communication_TASK_PRIO 1//与传感器通信 //任务堆栈大小 #define Sensor_Communication_STK_SIZE 512 //任务句柄 TaskHandle_t Sensor_CommunicationTask_Handler; //任务函数 void Sensor_Communication_task(void *pvParameters); /********************* ********************** 入口函数 ********************** *********************/ void os_init(void) { printf("入口函数调用成功\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(); } /********************* ********************** 创建 任务,队列,信号集等句柄,也可以测试用 ********************** *********************/ 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; /* 开始函数:创建其他函数与定时器 */ void start_task(void*pvParameters) { taskENTER_CRITICAL(); //进入临界区 //创建与传感器通信任务 handler=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");} vTaskDelete(StartTask_Handler); //删除开始任务 taskEXIT_CRITICAL(); //退出临界区 } void Sensor_Communication_task(void *pvParameters) { while(1) { // 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();// printf("%d %d\r\n",chour,cminute); Array(&now_stage,&hour,&min,&tem,&hum,&red,&blue,&white);//更新对应阶段号的参数 printf("current stage: %d\r\n",now_stage); RS485_1_Send_Data_1(rs485buf,8);//(RS485_RX_CNT=0已被注释) printf("send finish\r\n"); delay_xms(500); RX_BUF_Printf(128); RS485_1_Send_Data_3(); delay_xms(500); RX_BUF_Printf(128); while(!(RS485_RX_BUF[0]==0 && RS485_RX_BUF[1]==0 && RS485_RX_BUF[2]==0 && RS485_RX_BUF[3]==0 && RS485_RX_BUF[4]==0)) { printf("enter while\r\n"); if(RS485_RX_BUF[0]==0x01 && RS485_RX_BUF[1]==0x03) // 判断是否校验成功 { T = RS485_RX_BUF[3]; T = T<<8|RS485_RX_BUF[4]; H = RS485_RX_BUF[5]; H = H<<8|RS485_RX_BUF[6]; C= RS485_RX_BUF[19]; C = C<<8|RS485_RX_BUF[20]; printf("now_tem=%d.%d℃,now_hum=%d.%d%% ,co2=%d\r\n",T/10,T%10,H/10,H%10,C); /*GPIO1->报警铃 GPIO2->压缩机 GPIO3->四通阀 GPIO4—>新风风扇 GPIO5->加湿器 */ if((T<(tem-20)||T>(tem+20)||H<(hum-100)||H>(hum+100))&&(tick>610))//温度偏差2℃报警,湿度偏差10报警 { HC595_Send_Byte(gpio_state|=0x01); //GPIO_SetBits(GPIOB,GPIO_Pin_1);//打开报警铃 GPIO1->PB1 |=0000 0001 0x01 ALARM=1; } else { HC595_Send_Byte(gpio_state&=0xFE); //GPIO_ResetBits(GPIOB,GPIO_Pin_1);//关闭报警铃 &=1111 1110 0xFE ALARM=0; } if(T<600&&T>-30) { diff=current_T-T; if(diff<0)diff=-diff; if(diff<3||current_T==0) //最近两次温差相差0.3℃,消除传感器感应出错的影响 { pid.set_tem=tem/10.0; pid.now_tem=T/10.0; PID_Calc(); num=(((pid.OUT*400)/pid.pwmcycle)-1);//请问这个pid.OUT与pwm占空比的值是如何换算过来的 TIM_SetCompare4(TIM4,0.845*num); //0-200对应0-100%,如果pid.out=50,占空比就是25%,//num=50*400/200=100,100/400=25% //printf("%d ,%d ,%d ,%d ,%f ,%f ,%f ,%f ,%f ,%f ,%f ,%.3f\r\n",T,H,C,num,(pid.set_tem*10),pid.Kp,ki,kd,pid.Pout,pid.Iout,pid.Dout,num/399.0); current_T=T; } } if(H>(hum+50))//湿度高于设定值5,打开新风风扇 GPIO4->PD1 { HC595_Send_Byte(gpio_state|=0x08); HC595_Send_Byte(gpio_state&=0xEF); // GPIO_SetBits(GPIOD,GPIO_Pin_1);//打开新风风扇 |=0000 1000 0x08 // GPIO_ResetBits(GPIOD,GPIO_Pin_0);//关闭加湿器 &=1110 1111 0xEF humidity_flag=1; //除湿 } if(H<(hum-50))//湿度低于设定值5,打开加湿器 GPIO5->PD0 { HC595_Send_Byte(gpio_state|=0x10); HC595_Send_Byte(gpio_state&=0xF7); // GPIO_SetBits(GPIOD,GPIO_Pin_0);//启动加湿器 |=0001 0000 0x10 // GPIO_ResetBits(GPIOD,GPIO_Pin_1);//关闭风扇 &=1111 0111 0xF7 humidity_flag=2; } if( humidity_flag==1 && H<=hum) { HC595_Send_Byte(gpio_state&=0xE7); // GPIO_ResetBits(GPIOD,GPIO_Pin_1);//关闭风扇 &=1110 0111 0xE7 // GPIO_ResetBits(GPIOD,GPIO_Pin_0);//关闭加湿器 humidity_flag=0; } if( humidity_flag==2 && H>=hum) { HC595_Send_Byte(gpio_state&=0xE7); // GPIO_ResetBits(GPIOD,GPIO_Pin_0);//关闭加湿器 &=1110 0111 0xE7 // GPIO_ResetBits(GPIOD,GPIO_Pin_1);//关闭风扇 humidity_flag=0; } printf("!!!"); RS485_1_Send_Data_2(); //上传参数 RX_BUF_ZERO(23); //printf(" \r\n"); RX_BUF_Transfer(0,23); //printf("\r\n"); RX_BUF_Printf(128); // printf("\r\n"); } else if(RS485_RX_BUF[0]==0xEE&&RS485_RX_BUF[1]==0xB6&&RS485_RX_BUF[2]==0x03)//单个同步 { Analysis(&n,&i,RS485_RX_BUF); printf("B6 03 cmd: batch sync\r\n"); Array(&now_stage,&hour,&min,&tem,&hum,&red,&blue,&white);//更新对应阶段号的参数 Write_Init(); RX_BUF_ZERO(11); printf(" \r\n"); RX_BUF_Transfer(0,11); printf("\r\n"); RX_BUF_Printf(128); printf("\r\n"); } else if(RS485_RX_BUF[0]==0xEE&&RS485_RX_BUF[1]==0xB6&&RS485_RX_BUF[2]==0x04)//切换阶段 { change_stage_rev1=RS485_RX_BUF[3]; printf("B6 04 cmd: change stage\r\n"); RTC_synchronization_ins(2023,9,1,0,00,00); now_stage=change_stage_rev1; store_stage=change_stage_rev1; Write_Init(); RX_BUF_ZERO(8); printf(" \r\n"); RX_BUF_Transfer(0,8); printf("\r\n"); //RX_BUF_Printf(128); printf("\r\n"); } else if(RS485_RX_BUF[0]==0xEE&&RS485_RX_BUF[1]==0xB6&&RS485_RX_BUF[2]==0x01)//批量同步 { Batch_synchronization(&n,RS485_RX_BUF); printf("B6 01 cmd: get one %d\r\n", n); Array(&now_stage,&hour,&min,&tem,&hum,&red,&blue,&white);//更新对应阶段号的参数 //Write_Init();减少擦写的次数 RX_BUF_ZERO(20); printf(" \r\n"); RX_BUF_Transfer(0,20); printf("\r\n"); //RX_BUF_Printf(128); printf("\r\n"); } else if(RS485_RX_BUF[0]==0xEE&&RS485_RX_BUF[1]==0xB1&&RS485_RX_BUF[2]==0x11&&RS485_RX_BUF[15]==0xFF&&RS485_RX_BUF[16]==0xFF)//单个同步默认带的数据 { RX_BUF_ZERO(17); printf(" \r\n"); printf("cut overdata of B6 03 \r\n"); //RX_BUF_Printf(128); RX_BUF_Transfer(0,17); //RX_BUF_Printf(128); } else if(RS485_RX_BUF[0]==0xEE&&RS485_RX_BUF[1]==0xB1&&RS485_RX_BUF[2]==0x11&&RS485_RX_BUF[14]==0xFF&&RS485_RX_BUF[15]==0xFF)//单个同步默认带的数据 { RX_BUF_ZERO(16); printf("cut overdata of B6 03 \r\n"); printf(" \r\n"); //RX_BUF_Printf(128); RX_BUF_Transfer(0,16); //RX_BUF_Printf(128); } else if(RS485_RX_BUF[0]==0xEE&&RS485_RX_BUF[1]==0xB1&&RS485_RX_BUF[2]==0x11&&RS485_RX_BUF[12]==0xFF&&RS485_RX_BUF[13]==0xFF)//阶段切换默认带的数据 { RX_BUF_ZERO(14); printf("cut overdata of B6 04 \r\n"); printf(" \r\n"); //RX_BUF_Printf(128); RX_BUF_Transfer(0,14); //RX_BUF_Printf(128); } else if(RS485_RX_BUF[0]==0xEE&&RS485_RX_BUF[1]==0xB1&&RS485_RX_BUF[2]==0x01&&RS485_RX_BUF[7]==0xFF&&RS485_RX_BUF[8]==0xFF)//上位机默认带的数据 { RX_BUF_ZERO(9); printf("cut overdata of Upper computer \r\n"); printf(" \r\n"); //RX_BUF_Printf(128); RX_BUF_Transfer(0,9); //RX_BUF_Printf(128); } else { printf("previous array cut\r\n"); RX_BUF_Transfer(0,1); printf(" \r\n"); printf("\r\n"); //RX_BUF_Printf(128); printf("\r\n"); } } printf("%d %d %d\r\n",T,H,C); printf("current params: %d:%d,hot or cold flag:%d, humidity flag:%d, alarm: %d\r\n",chour, cminute, hot_clod_flag, humidity_flag, ALARM); printf("led!!!\r\n"); 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((blue/100.0*3.5+28));//J10 //printf("red=%d\r\n",red); //printf("bule=%d\r\n",blue); } RS485_RX_CNT=0; printf("end data to serial monitor end"); } } //void led_task(void *pvParameters) //{ // while(1) // { // printf("led!!!\r\n"); // if(red<=1000&&blue<=1000) // { // PWM_SetCompare1((red/10));//J9 // PWM_SetCompare2((blue/10));//J11 // //PWM_SetCompare4((white/10));//J10 // } // vTaskDelay(5000); // // } //}