You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
incubator_embeded/myfreertos/myfreertos.c

561 lines
17 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

#include "myfreertos.h"
#define SENSOR_ADDRESS 0x02
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 0
// 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);
// 10seconds delay
#define SENSOR_DATA_REQUEST_PERIOD pdMS_TO_TICKS(5000)
// 60seconds delay
#define SYNC_ENVIRONMENT_DATA_REQUEST_PERIOD pdMS_TO_TICKS(60000)
/**
* sensor data request: 02 03
*/
void SensorDataRequestTask(void *pvParameters);
/**
* sync environment data: EE B5 01
*/
void SyncEnvironmentDataRequestTask(void *pvParameters);
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
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);
// 创建传感器数据请求任务
xTaskCreate(SensorDataRequestTask, "SensorDataRequestTask", configMINIMAL_STACK_SIZE, NULL, tskIDLE_PRIORITY + 1, NULL);
xTaskCreate(SyncEnvironmentDataRequestTask, "SyncEnvironmentDataRequestTask", configMINIMAL_STACK_SIZE, NULL, tskIDLE_PRIORITY + 2, NULL);
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(); // 进入临界区
// 创建与传感器通信任务
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 SensorDataRequestTask(void *pvParameters) {
while (1) {
// 发送传感器数据请求的操作
RS485_1_Send_Data_1(rs485buf, 8);
vTaskDelay(SENSOR_DATA_REQUEST_PERIOD);
}
}
void SyncEnvironmentDataRequestTask(void *pvParameters) {
while (1) {
// 发送传感器数据请求的操作
RS485_1_Send_Data_3();
vTaskDelay(SYNC_ENVIRONMENT_DATA_REQUEST_PERIOD);
}
}
u8 temp[4] = {0xaa,0xbb,0xcc,0xdd};
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已被注释)
// delay_xms(50);
// // RX_BUF_Printf(128);
// if (sync_cnt <= 0)
// {
// RS485_1_Send_Data_3();
// sync_cnt = 10;
// }
// else
// {
// sync_cnt--;
// }
delay_xms(50);
// RX_BUF_Printf(128);
bufcut_Init(RS485_RX_BUF_COPY, RS485_RX_BUF, 0, 128);
RS485_RX_CNT = 0;
while (isAllZeros(RS485_RX_BUF_COPY, 128) == 0)
{
if (RS485_RX_BUF_COPY[0] == 0x02 && RS485_RX_BUF_COPY[1] == 0x03 && CRC16_check(RS485_RX_BUF_COPY, 21) == 1)
{
// 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_sensor_data(temp_data);
RX_BUF_Transfer(0, 23);
}
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
// if (CRC16_check(RS485_RX_BUF_COPY, 16) == 1) {
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);
bufcut_Init(RS485_DATA_TMP + 8, RS485_SUFFIX, 18, 22);
// 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
// if (CRC16_check(RS485_RX_BUF_COPY, 7) == 1) {
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
// if (CRC16_check(RS485_RX_BUF_COPY, 4) == 1) {
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_Send_Data_2(); // 上传参数
// }
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 && CRC16_check(RS485_RX_BUF_COPY, 4) == 1)
{
// change pid params
// total length: 8
// if (CRC16_check(RS485_RX_BUF_COPY, 4) == 1) {
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;
}
}
Write_Init();
bufcut_Init(RS485_DATA_TMP, RS485_RX_BUF_COPY, 0, 8);
bufcut_Init(RS485_DATA_TMP + 8, RS485_SUFFIX, 8, 12);
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)
{
// btn down or up
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;
}
}
/**
* process sensor data
*/
void process_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;
}
if (T < 600 && T > -400)
{
diff = current_T - T;
if (diff < 0)
diff = -diff;
if (diff < 100 || current_T == 0) // 最近两次温差相差10℃,消除传感器感应出错的影响
{
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_Send_Data_2(); // 上传参数
delay_xms(200);
}
/**
* 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();
delay_ms(10);
RS485_1_Send_Data_2(); // 上传参数
}
break;
}
}
}
// void Host_Computer_Communication(void)
//{
// if(RS485_RX_BUF_COPY[0]==0xEE&&RS485_RX_BUF_COPY[1]==0xB6)
// {
// if(RS485_RX_BUF_COPY[2]==0x03)//单个同步
// {
// Analysis(&n,&i,RS485_RX_BUF_COPY);
// //printf("B6 03 cmd: batch sync\r\n");
// Array(&now_stage,&hour,&min,&tem,&hum,&red,&blue,&white);//更新对应阶段号的参数
// Write_Init();
// RX_BUF_Transfer(0,11);
//
// }
// if(RS485_RX_BUF_COPY[2]==0x04)//阶段切换
// {
// change_stage_rev1=RS485_RX_BUF_COPY[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_Transfer(0,8);
// }
// if(RS485_RX_BUF_COPY[2]==0x01)//批量同步
// {
// Batch_synchronization(&n,RS485_RX_BUF_COPY);
// //printf("B6 01 cmd: get one %d\r\n", n);
// Array(&now_stage,&hour,&min,&tem,&hum,&red,&blue,&white);//更新对应阶段号的参数
// //Write_Init();减少擦写的次数
// RX_BUF_Transfer(0,20);
// }
// }
// else if(RS485_RX_BUF_COPY[0]==0xEE&&RS485_RX_BUF_COPY[1]==0xB1)
// {
// if(RS485_RX_BUF_COPY[2]==0x11&&RS485_RX_BUF_COPY[15]==0xFF&&RS485_RX_BUF[16]==0xFF)//单个同步默认带的数据
// {
// //printf("cut overdata of B6 03 \r\n");
// RX_BUF_Transfer(0,17);
// }
// if(RS485_RX_BUF_COPY[2]==0x11&&RS485_RX_BUF_COPY[14]==0xFF&&RS485_RX_BUF[15]==0xFF)//单个同步默认带的数据
// {
// //printf("cut overdata of B6 03 \r\n");
// //RX_BUF_Printf(128);
// RX_BUF_Transfer(0,16);
// //RX_BUF_Printf(128);
// }
// if(RS485_RX_BUF_COPY[2]==0x11&&RS485_RX_BUF_COPY[12]==0xFF&&RS485_RX_BUF_COPY[13]==0xFF)//阶段切换默认带的数据
// {
// //printf("cut overdata of B6 04 \r\n");
// //RX_BUF_Printf(128);
// RX_BUF_Transfer(0,14);
// }
// if(RS485_RX_BUF_COPY[2]==0x01&&RS485_RX_BUF_COPY[7]==0xFF&&RS485_RX_BUF_COPY[8]==0xFF)//上位机默认带的数据
// {
// //printf("cut overdata of Upper computer \r\n");
// //RX_BUF_Printf(128);
// RX_BUF_Transfer(0,9);
// //RX_BUF_Printf(128);
//
// }
// }
// else
// {
// //int ZERO_Count=0;
// //if()与while()的顺序不能变
//// if((RS485_RX_BUF_COPY[0]!=0x00))//不为0处理掉
//// {
//// RX_BUF_Transfer(0,1);
//// //printf("the number is no zero\r\n");
//// }
////
//// while(RS485_RX_BUF_COPY[ZERO_Count]==0x00)
//// {
//// ZERO_Count++;
//// }
//// RX_BUF_Transfer(0,ZERO_Count);
//
// RX_BUF_Transfer(0,1);
// //printf("previous array cut\r\n");
// }
//}