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

592 lines
16 KiB

#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("<22><EFBFBD><EBB4AB><EFBFBD><EFBFBD>ͨ<EFBFBD><CDA8><EFBFBD><EFBFBD><EFBFBD>񴴽<EFBFBD><F1B4B4BD>ɹ<EFBFBD>\r\n");}
// else{printf("<22><EFBFBD><EBB4AB><EFBFBD><EFBFBD>ͨ<EFBFBD><CDA8><EFBFBD><EFBFBD><EFBFBD>񴴽<EFBFBD>ʧ<EFBFBD><CAA7>\r\n");}
// //<2F><><EFBFBD><EFBFBD><EFBFBD>ص<EFBFBD><D8B5><EFBFBD><EFBFBD><EFBFBD>
// 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("<22>ص<EFBFBD><D8B5><EFBFBD><EFBFBD>񴴽<EFBFBD><F1B4B4BD>ɹ<EFBFBD>\r\n");}
// else{printf("<22>ص<EFBFBD><D8B5><EFBFBD><EFBFBD>񴴽<EFBFBD>ʧ<EFBFBD><CAA7>\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); //<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
// //sprintf(wet_temp,"{\"method\":\"thing.event.property.post\",\"params\":{\"Humidity\":%.2f,\"temperature\":%.2f,\"CO2\":%d},\"version\":\"1.0.0\"}",Humidity,temperature,C); //<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
// 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);
}