diff --git a/App/Inc/anemometer_dev.h b/App/Inc/anemometer_dev.h index 4ab94bc..04ea94b 100644 --- a/App/Inc/anemometer_dev.h +++ b/App/Inc/anemometer_dev.h @@ -64,16 +64,12 @@ extern int16_t adc_val1[ADC_VAL_LEN]; //滑动平均值结构体 typedef struct { float speed_data[3]; // 存储数据点的数组 - float direction_data[3]; // 存储数据点的数组 + float direction_data[3]; // 存储数据点的数组 + float ave_speed_data; // 存储数据点平均值 + float ave_direction_data; // 存储数据点平均值 int index; // 指向队列头部的索引(实际上是最近添加的元素) int count; // 当前队列中的元素数量 } SlidingWindow_3s; -typedef struct { - float speed_data[60]; // 存储数据点的数组 - float direction_data[60]; // 存储数据点的数组 - int index; // 指向队列头部的索引(实际上是最近添加的元素) - int count; // 当前队列中的元素数量 -} SlidingWindow_1mim; typedef struct { float speed_data[600]; // 存储数据点的数组 float direction_data[600]; // 存储数据点的数组 @@ -104,14 +100,20 @@ typedef struct __weather_param float32_t humidity; // 降雨量 float32_t precipitation; + // 算法出来的瞬时风速 + float32_t instantaneous_wind_speed; + // 算法出来的瞬时风向 + float32_t instantaneous_wind_direction; } Weather_param; extern Weather_param weather_info; typedef struct _mcs_para{ float32_t min_wind_direction; /* 最小风向 */ + float32_t trough_wind_direction; /* 极小风向 */ float32_t average_wind_direction; /* 平均风向 */ float32_t instantaneous_wind_direction; /* 瞬时风向 */ + float32_t peak_wind_direction; /* 极大风向 */ float32_t max_wind_direction; /* 最大风向 */ float32_t min_wind_speed; /* 最小风速 */ float32_t trough_wind_speed; /* 极小风速 */ diff --git a/App/Inc/frt_protocol.h b/App/Inc/frt_protocol.h index efe9998..5bd7905 100644 --- a/App/Inc/frt_protocol.h +++ b/App/Inc/frt_protocol.h @@ -23,20 +23,22 @@ typedef enum typedef enum { FRT_REGISTER_MIN_WIND_DIRECTION = 0, /* С */ - FRT_REGISTER_AVERAGE_WIND_DIRECTION = 1, /* ƽ */ - FRT_REGISTER_INSTANTANEOUS_WIND_DIRECTION = 2, /* ˲ʱ */ - FRT_REGISTER_MAX_WIND_DIRECTION = 3, /* */ - FRT_REGISTER_MIN_WIND_SPEED = 4, /* С */ - FRT_REGISTER_THROUGH_WIND_SPEED = 5, /* С */ - FRT_REGISTER_AVERAGE_WIND_SPEED = 6, /* ƽ */ - FRT_REGISTER_INSTANTANEOUS_WIND_SPEED = 7, /* ˲ʱ */ - FRT_REGISTER_PEAK_WIND_SPEED = 8, /* */ - FRT_REGISTER_MAX_WIND_SPEED = 9, /* */ - FRT_REGISTER_TEMPERATURE = 10, /* ¶ */ - FRT_REGISTER_HUMIDITY = 11, /* ʪ */ - FRT_REGISTER_PRESSURE = 12, /* ѹ */ - FRT_REGISTER_RAIN = 13, /* */ - FRT_REGISTER_PRECIPITATION_INTENSITY = 14, /* ܷ */ + FRT_REGISTER_THROUGH_WIND_DIRECTION = 1, /* С */ + FRT_REGISTER_AVERAGE_WIND_DIRECTION = 2, /* ƽ */ + FRT_REGISTER_INSTANTANEOUS_WIND_DIRECTION = 3, /* ˲ʱ */ + FRT_REGISTER_PEAK_WIND_DIRECTION = 4, /* */ + FRT_REGISTER_MAX_WIND_DIRECTION = 5, /* */ + FRT_REGISTER_MIN_WIND_SPEED = 6, /* С */ + FRT_REGISTER_THROUGH_WIND_SPEED = 7, /* С */ + FRT_REGISTER_AVERAGE_WIND_SPEED = 8, /* ƽ */ + FRT_REGISTER_INSTANTANEOUS_WIND_SPEED = 9, /* ˲ʱ */ + FRT_REGISTER_PEAK_WIND_SPEED = 10, /* */ + FRT_REGISTER_MAX_WIND_SPEED = 11, /* */ + FRT_REGISTER_TEMPERATURE = 12, /* ¶ */ + FRT_REGISTER_HUMIDITY = 13, /* ʪ */ + FRT_REGISTER_PRESSURE = 14, /* ѹ */ + FRT_REGISTER_RAIN = 15, /* */ + FRT_REGISTER_PRECIPITATION_INTENSITY = 16, /* ܷ */ FRT_REGISTER_DEVICE_ADDR = 20, /* 豸ַ */ FRT_REGISTER_COMMU_BAUDRATE = 21, /* */ diff --git a/App/Src/anemometer_dev.c b/App/Src/anemometer_dev.c index c9770a4..7b32747 100644 --- a/App/Src/anemometer_dev.c +++ b/App/Src/anemometer_dev.c @@ -550,8 +550,8 @@ void wind_task(void const * argument) /// term_printf("x:%.2f y:%.2f win_speed %.2f m/s angle %.2f \r\n",av_speedx,av_speedy,av_speed,av_angle); } //瞬时风速风向 - g_stMcs_Para.instantaneous_wind_direction = av_angle; - g_stMcs_Para.instantaneous_wind_speed = av_speed; + weather_info.instantaneous_wind_direction = av_angle; + weather_info.instantaneous_wind_speed = av_speed; ///term_printf("win_speed %.2f \r\n",weather_info.wind_velocity); //HAL_Delay(1); //osDelay(3// @@ -715,7 +715,7 @@ void update_mcs_param(float new_wind_speed, float new_wind_dirction) } SlidingWindow_10min win_10min = {0}; - +SlidingWindow_3s win_3s = {0}; //求和函数 float sum(float arr[], int n) { @@ -791,9 +791,52 @@ float linear_interpolation(float x) { void my_update_mcs_param(float new_wind_speed, float new_wind_dirction) { -// 十分钟滑动平均值 - win_10min.speed_data[win_10min.index] = new_wind_speed; //添加新数据 - win_10min.direction_data[win_10min.index] = new_wind_dirction; +/// 三秒滑动平均 + win_3s.speed_data[win_3s.index] = new_wind_speed; + win_3s.direction_data[win_3s.index] = new_wind_dirction; + if(win_3s.count < 3) + { + win_3s.count++; + } + //计算三秒风速滑动平均值当作瞬时值 + win_3s.ave_speed_data = sum(win_3s.speed_data, win_3s.count) / win_3s.count; + //计算三秒风向滑动平均值,风向滑动平均值需要过零算法 + float temp_sin_sum_3s = 0; + float temp_cos_sum_3s = 0; + for(int i = 0; i < win_3s.count; i++) + { + temp_sin_sum_3s += sinf(win_3s.direction_data[i] * PI/180); + temp_cos_sum_3s += cosf(win_3s.direction_data[i] * PI/180); + } + win_3s.ave_direction_data = atanf(temp_sin_sum_3s / (temp_cos_sum_3s + 0.00001)) * 180/PI; + // 不同象限不一样 + // 1象限真实角度=本身 + // 2象限真实角度=+180 + // 3象限真实角度=+180 + // 4象限真实角度=+360 + if((temp_sin_sum_3s > 0 && temp_cos_sum_3s < 0) || (temp_sin_sum_3s < 0 && temp_cos_sum_3s < 0)) + { + win_3s.ave_direction_data += 180; + }else if (temp_sin_sum_3s < 0 && temp_cos_sum_3s > 0) + { + win_3s.ave_direction_data += 360; + } + g_stMcs_Para.instantaneous_wind_direction = win_3s.ave_direction_data; + + /** 线性插值 **/ + /** win_3s.ave_speed_data[win_3s.index]为风速 **/ + /** win_3s.ave_direction_data[win_3s.index]为风向 **/ + /** 风向不要插值 **/ + /** 只用插值瞬时风速,10min便会是插值后的值 **/ + g_stMcs_Para.instantaneous_wind_speed = linear_interpolation(win_3s.ave_speed_data); + /** 线性插值 **/ +// 更新索引 + win_3s.index = (win_3s.index + 1) % 3; + + +/// 十分钟滑动平均值 + win_10min.speed_data[win_10min.index] = g_stMcs_Para.instantaneous_wind_speed; //添加新数据 + win_10min.direction_data[win_10min.index] = g_stMcs_Para.instantaneous_wind_direction; if(win_10min.count < g_usrConfigInfo.speed_average_time /*AVE_TIME*/) { @@ -825,20 +868,15 @@ void my_update_mcs_param(float new_wind_speed, float new_wind_dirction) win_10min.ave_direction_data[win_10min.index] += 360; } - /** 线性插值 **/ - /** win_10min.ave_speed_data[win_10min.index]为风速 **/ - /** win_10min.ave_direction_data[win_10min.index]为风向 **/ - /** 风向不要插值 **/ - win_10min.ave_speed_data[win_10min.index] = linear_interpolation(win_10min.ave_speed_data[win_10min.index]); - /** 线性插值 **/ - //默认第一个数据为最大或者最小 float temp_min_direction = win_10min.ave_direction_data[0]; float temp_max_direction = win_10min.ave_direction_data[0]; float temp_min_speed = win_10min.ave_speed_data[0]; float temp_max_speed = win_10min.ave_speed_data[0]; - float temp_trough_min_speed = win_10min.ave_speed_data[0]; - float temp_peak_max_speed = win_10min.ave_speed_data[0]; + float temp_trough_min_speed = win_10min.speed_data[0]; + float temp_peak_max_speed = win_10min.speed_data[0]; + float temp_trough_min_direction = win_10min.direction_data[0]; + float temp_peak_max_direction = win_10min.direction_data[0]; //遍历10min内所有数据寻找最大最小极大极小 for (int i = 0; i < win_10min.count; i++) { // 最大最小 @@ -861,6 +899,12 @@ void my_update_mcs_param(float new_wind_speed, float new_wind_dirction) else if (win_10min.speed_data[i] > temp_peak_max_speed) { temp_peak_max_speed = win_10min.speed_data[i]; // 更新风速极大值 } + if (win_10min.direction_data[i] < temp_trough_min_direction) { + temp_trough_min_direction = win_10min.direction_data[i]; // 更新风向极小值 + } + else if (win_10min.direction_data[i] > temp_peak_max_direction) { + temp_peak_max_direction = win_10min.direction_data[i]; // 更新风向极大值 + } } // 更新最大最小极大极小风速风向 g_stMcs_Para.min_wind_direction = temp_min_direction; @@ -871,11 +915,13 @@ void my_update_mcs_param(float new_wind_speed, float new_wind_dirction) g_stMcs_Para.average_wind_speed = win_10min.ave_speed_data[win_10min.index]; g_stMcs_Para.max_wind_speed = temp_max_speed; -// 极大极小风速 +// 极大极小风速与极大极小风向 g_stMcs_Para.trough_wind_speed = temp_trough_min_speed; g_stMcs_Para.peak_wind_speed = temp_peak_max_speed; + g_stMcs_Para.trough_wind_direction = temp_trough_min_direction; + g_stMcs_Para.peak_wind_direction = temp_peak_max_direction; - win_10min.index = (win_10min.index + 1) % /*AVE_TIME*/g_usrConfigInfo.speed_average_time; //更新索引 + win_10min.index = (win_10min.index + 1) % /*AVE_TIME*/g_usrConfigInfo.speed_average_time;//更新索引 } void tem_hum_update_task(void const * argument) @@ -943,7 +989,7 @@ void tem_hum_update_task(void const * argument) NVIC_SystemReset(); } // 风速风向更新 - my_update_mcs_param(g_stMcs_Para.instantaneous_wind_speed, g_stMcs_Para.instantaneous_wind_direction); + my_update_mcs_param(weather_info.instantaneous_wind_speed, weather_info.instantaneous_wind_direction); } } diff --git a/App/Src/frt_protocol.c b/App/Src/frt_protocol.c index 9f014df..632b5e3 100644 --- a/App/Src/frt_protocol.c +++ b/App/Src/frt_protocol.c @@ -16,8 +16,10 @@ static void FRT_MsgProc_WriteRegister(device_handle device, void *pMsg); static u_int16_t FRT_ReadReg(unsigned char regId); /* 读 */ static u_int16_t FRT_ReadRegMinWindDiretion(void *pMsg); +static u_int16_t FRT_ReadRegThroughWindDiretion(void *pMsg); static u_int16_t FRT_ReadRegAverageWindDirection(void *pMsg); static u_int16_t FRT_ReadRegInstantaneousWindDirection(void *pMsg); +static u_int16_t FRT_ReadRegPeakWindDiretion(void *pMsg); static u_int16_t FRT_ReadRegMaxWindDirection(void *pMsg); static u_int16_t FRT_ReadRegMinWindSpeed(void *pMsg); static u_int16_t FRT_ReadRegThroughWindSpeed(void *pMsg); @@ -88,8 +90,10 @@ FRT_FuncionMsgProcTable_s g_MsgTbl[] = FRT_RegProcTable_s g_RegTbl[] = { { FRT_REGISTER_MIN_WIND_DIRECTION, FRT_ReadRegMinWindDiretion }, /* 最小风向 */ + { FRT_REGISTER_THROUGH_WIND_DIRECTION, FRT_ReadRegThroughWindDiretion }, /* 极小风向 */ { FRT_REGISTER_AVERAGE_WIND_DIRECTION, FRT_ReadRegAverageWindDirection }, /* 平均风向 */ { FRT_REGISTER_INSTANTANEOUS_WIND_DIRECTION, FRT_ReadRegInstantaneousWindDirection }, /* 瞬时风向 */ + { FRT_REGISTER_PEAK_WIND_DIRECTION, FRT_ReadRegPeakWindDiretion }, /* 极大风向 */ { FRT_REGISTER_MAX_WIND_DIRECTION, FRT_ReadRegMaxWindDirection }, /* 最大风向 */ { FRT_REGISTER_MIN_WIND_SPEED, FRT_ReadRegMinWindSpeed }, /* 最小风速 */ { FRT_REGISTER_THROUGH_WIND_SPEED, FRT_ReadRegThroughWindSpeed }, /* 极小风速 */ @@ -194,6 +198,17 @@ static u_int16_t FRT_ReadRegMinWindDiretion(void *pMsg) return FRT_swap_endian_16(value); } +/** + * @brief 读极小风向寄存器值 + * @param + * @retval + */ +static u_int16_t FRT_ReadRegThroughWindDiretion(void *pMsg) +{ + u_int16_t value = (u_int16_t)(g_stMcs_Para.trough_wind_direction *10); + return FRT_swap_endian_16(value); +} + /** * @brief 读平均风向寄存器值 * @param @@ -216,6 +231,17 @@ static u_int16_t FRT_ReadRegInstantaneousWindDirection(void *pMsg) return FRT_swap_endian_16(value); } +/** + * @brief 读极大风向寄存器值 + * @param + * @retval + */ +static u_int16_t FRT_ReadRegPeakWindDiretion(void *pMsg) +{ + u_int16_t value = (u_int16_t)(g_stMcs_Para.peak_wind_direction *10); + return FRT_swap_endian_16(value); +} + /** * @brief 读最大风向寄存器值 * @param diff --git a/App/Src/inflash.c b/App/Src/inflash.c index 020f69f..2f7736d 100644 --- a/App/Src/inflash.c +++ b/App/Src/inflash.c @@ -162,11 +162,8 @@ BOOL read_factory_config_info() */ BOOL read_config_info() { - if(read_usr_config_info&&read_factory_config_info) - { - return TRUE; - } - return FALSE; + read_usr_config_info(); + read_factory_config_info(); } /**