#include "weight_read.h" #include "math.h" #include "string.h" #include "soft_flow.h" #include "main.h" typedef struct MeanFilter_s { bool init; //input float input[SAMPLE_NUM]; uint8_t index; //sum float sum; //output float output; } MeanFilter_t; static MeanFilter_t _mean_filter[SENSOR_NUM] = {0}; // 满额输出688.128mv(128倍增益) // weight = AD/50KG量程 *128增益 * 2^24 位数 * 5.376mV(3.36V * 1.6mV/V) AD/weight 1g对应AD值136.88 // static uint32_t databuf[SENSOR_NUM][SAMPLE_NUM] = {0}; /*输出范围:0x800000 - 0x7FFFFF(补码) 宽度为 -8388608 ~ 8388607 */ static void Get_All_GrossWeight(void); static float Get_Weight(void); static void Processing_Data(void); static void Filter_Init(void); // static void Calib_Creep(WEIGHING_PARAM* param, float* buff ,float total_weight); // static float Get_Compare(WEIGHING_PARAM* param, float total_weight); // static uint8_t Check_No_Impact(WEIGHING_PARAM* param); // static void Analog_Value(WEIGHING_PARAM* param, uint8_t num, float* buf); /*参数列表*/ static struct SENSOR sensor1 = { .SCK_GPIO_Port = PD_SCK1_GPIO_Port, .SCK_Pin = PD_SCK1_Pin, .DOUT_GPIO_Port = DOUT1_GPIO_Port, .DOUT_Pin = DOUT1_Pin, .K.f = 112.000f, .base_k = 112.0f, }; static struct SENSOR sensor2 = { .SCK_GPIO_Port = PD_SCK2_GPIO_Port, .SCK_Pin = PD_SCK2_Pin, .DOUT_GPIO_Port = DOUT2_GPIO_Port, .DOUT_Pin = DOUT2_Pin, .K.f = 112.000f, .base_k = 112.0f, .Num = 1, }; static struct SENSOR sensor3 = { .SCK_GPIO_Port = PD_SCK3_GPIO_Port, .SCK_Pin = PD_SCK3_Pin, .DOUT_GPIO_Port = DOUT3_GPIO_Port, .DOUT_Pin = DOUT3_Pin, .K.f = 112.000f, .base_k = 112.0f, .Num = 2, }; static WEIGHING_OPS __ops = { .get_allgrossweight = Get_All_GrossWeight, .get_weight = Get_Weight, .processing_data = Processing_Data, .filter_init = Filter_Init, }; static WEIGHING_DEVICE _device = { .sensor = {&sensor1, &sensor2, &sensor3}, .sensor_num_mask = 4, .correct_k = 1, ._ops = &__ops, }; uint32_t (*read)(struct SENSOR *sensor) = Read_Value; WEIGHING_DEVICE *Get_Device_Handle(void) { return &_device; } uint32_t Read_Value(struct SENSOR *sensor) { uint32_t Value; uint8_t CycleIndex; Value = 0; // sensor->DOUT_GPIO_Port->BSRR = sensor->DOUT_Pin; // sensor->SCK_GPIO_Port->BSRR = (uint32_t)sensor->SCK_Pin << 16; // delay(20); HAL_GPIO_WritePin(sensor->SCK_GPIO_Port, sensor->SCK_Pin, 0); uint32_t time = HAL_GetTick(); /*等待HX711准备好数据*/ while (HAL_GPIO_ReadPin(sensor->DOUT_GPIO_Port, sensor->DOUT_Pin)) { /*大量采集时做了延迟保护*/ if (HAL_GetTick() - time > 100) { return 0; } } for (CycleIndex = 0; CycleIndex < 24; ++CycleIndex) { // sensor->SCK_GPIO_Port->BSRR = (uint32_t)sensor->SCK_Pin; HAL_GPIO_WritePin(sensor->SCK_GPIO_Port, sensor->SCK_Pin, 1); delay_us(5); Value = Value << 1; // sensor->SCK_GPIO_Port->BSRR = (uint32_t)sensor->SCK_Pin << 16; HAL_GPIO_WritePin(sensor->SCK_GPIO_Port, sensor->SCK_Pin, 0); delay_us(5); if (HAL_GPIO_ReadPin(sensor->DOUT_GPIO_Port, sensor->DOUT_Pin)) { Value++; } } /*第25个时钟脉冲选择128倍增益通道*/ // sensor->SCK_GPIO_Port->BSRR = (uint32_t)sensor->SCK_Pin ; HAL_GPIO_WritePin(sensor->SCK_GPIO_Port, sensor->SCK_Pin, 1); Value = Value ^ BASE_VALUE; // 异或取原码防止过零 Value = Value & 0xFFFFC0; // 后7位太抖,根据手册取无噪声有效位17位,且0x7F只有1g大小,放弃使用 // sensor->SCK_GPIO_Port->BSRR = (uint32_t)sensor->SCK_Pin << 16; HAL_GPIO_WritePin(sensor->SCK_GPIO_Port, sensor->SCK_Pin, 0); return (Value); } //============ 均值滤波器 ================== static void MeanFilterInit( MeanFilter_t *filter, uint8_t coef_size, float def ) { for(uint8_t i = 0; i < coef_size; i++) { filter->input[i] = def; } filter->index = 0; filter->sum = def * coef_size; filter->output = def; filter->init = true; } static bool wait_front_data(void) { static uint8_t wait_count = 0; wait_count++; if(wait_count >= SAMPLE_NUM * SENSOR_NUM) { wait_count = SAMPLE_NUM * SENSOR_NUM; return false; } return true; } /* Computes a MeanFilter_t filter on a sample */ static float meanApply( MeanFilter_t *filter, float input, uint8_t size) { filter->sum -= filter->input[filter->index]; filter->sum += input; filter->output = filter->sum / size; filter->input[filter->index] = input; filter->index++; filter->index = filter->index % size; return filter->output; } static void Filter_Init(void) { for(uint8_t i = 0; i < SENSOR_NUM; i++) { MeanFilterInit(&_mean_filter[i], SAMPLE_NUM, 0); } } static void old_Filter_Value(uint32_t data_tmp[][SAMPLE_NUM]) { WEIGHING_DEVICE *device = &_device; uint8_t sensor_num_c; uint32_t tmp1 = 0; for (sensor_num_c = 0; sensor_num_c < SENSOR_NUM; sensor_num_c++) { if (sensor_num_c == device->sensor_num_mask) { continue; } for (uint8_t j = 0; j < SAMPLE_NUM - 1; j++) { for (uint8_t k = j + 1; k < SAMPLE_NUM; k++) { if (data_tmp[sensor_num_c][j] > data_tmp[sensor_num_c][k]) { tmp1 = data_tmp[sensor_num_c][j]; data_tmp[sensor_num_c][j] = data_tmp[sensor_num_c][k]; data_tmp[sensor_num_c][k] = tmp1; } } } } for (sensor_num_c = 0; sensor_num_c < SENSOR_NUM; sensor_num_c++) { if (sensor_num_c == device->sensor_num_mask) { continue; } struct SENSOR *sensor = device->sensor[sensor_num_c]; sensor->Raw_Value = 0; for (uint8_t i = SAMPLE_NUM - 18; i < SAMPLE_NUM - 2; i++) { // sensor->Raw_Value += *((uint32_t*)tmp + sensor_num_c * SAMPLE_NUM + i); sensor->Raw_Value += data_tmp[sensor_num_c][i]; } // sensor->Raw_Value = *((uint32_t*)tmp + sensor_num_c * SAMPLE_NUM + VALUE_MID); sensor->Raw_Value = sensor->Raw_Value / (SAMPLE_NUM - 4); if ((sensor->GrossWeight) < sensor->Raw_Value) { sensor->Real_Variation = -(float)(sensor->Raw_Value - sensor->GrossWeight); } else if ((sensor->GrossWeight) >= sensor->Raw_Value) { sensor->Real_Variation = (float)(sensor->GrossWeight - sensor->Raw_Value); } } } void Filter_Value(uint32_t* data) { WEIGHING_DEVICE *device = &_device; uint8_t sensor_num_c; for (sensor_num_c = 0; sensor_num_c < SENSOR_NUM; sensor_num_c++) { if (sensor_num_c == device->sensor_num_mask) { continue; } struct SENSOR *sensor = device->sensor[sensor_num_c]; sensor->Raw_Value = meanApply(&_mean_filter[sensor_num_c] , data[sensor_num_c], SAMPLE_NUM); if(wait_front_data()) { sensor->Raw_Value = sensor->GrossWeight; } if ((sensor->GrossWeight) < sensor->Raw_Value) { sensor->Real_Variation = -(float)(sensor->Raw_Value - sensor->GrossWeight); } else if ((sensor->GrossWeight) >= sensor->Raw_Value) { sensor->Real_Variation = (float)(sensor->GrossWeight - sensor->Raw_Value); } } } /*转重量*/ void Convert_Into_Weight(void) { WEIGHING_DEVICE *device = &_device; uint8_t sensor_num_c; for (sensor_num_c = 0; sensor_num_c < SENSOR_NUM; sensor_num_c++) { if (sensor_num_c == device->sensor_num_mask) { continue; } struct SENSOR *sensor = device->sensor[sensor_num_c]; if (sensor->Real_Variation < 0) { sensor->Real_Variation = fabsf(sensor->Real_Variation); } sensor->Real_Weight = sensor->Real_Variation / sensor->base_k; // if(sensor->Real_Variation < 0) // { // sensor->Real_Weight = 0; // } } } static void Processing_Data(void) { uint8_t sensor_num_c; uint8_t err_count = 0; WEIGHING_DEVICE *device = &_device; // static uint8_t index = 0; uint32_t data[SENSOR_NUM] = {0}; // // static uint32_t** pdata = NULL; // if(pdata == NULL) // { // pdata = (uint32_t**)malloc(sizeof(uint32_t*) * device->sensor_num); // for(sensor_num_c = 0; sensor_num_c < device->sensor_num; sensor_num_c++) // { // if(sensor_num_c == device->sensor_num_mask) // { // continue; // } // pdata[sensor_num_c] = (uint32_t*)malloc(sizeof(uint32_t) * SAMPLE_NUM); // } // } for (sensor_num_c = 0; sensor_num_c < SENSOR_NUM; sensor_num_c++) { if (sensor_num_c == device->sensor_num_mask) { continue; } data[sensor_num_c] = read(device->sensor[sensor_num_c]); while (data[sensor_num_c] == 0) { data[sensor_num_c] = read(device->sensor[sensor_num_c]); err_count++; if (err_count > 10 && device->sensor_num_mask == 4) { device->sensor[sensor_num_c]->err_flag = true; device->sensor_num_mask = sensor_num_c; err_count = 0; return; } } } // index++; // if (index == SAMPLE_NUM) { Filter_Value(data); Convert_Into_Weight(); // for(sensor_num_c = 0; sensor_num_c < SENSOR_NUM; sensor_num_c++) // { // // if(sensor_num_c == device->sensor_num_mask) // // { // // continue; // // } // free(pdata[sensor_num_c]); // } // free(pdata); // pdata = NULL; // memset(databuf, 0, sizeof(databuf)); // index = 0; } } static float Deal_With_Jitter(WEIGHING_DEVICE *_device, float *buff) { WEIGHING_DEVICE *device = _device; static uint32_t deal_drift = 0; static float last_total = 0; static float buff_snapshot[SENSOR_NUM] = {0.0f}; float total = 0; uint8_t sensor_num_c; last_total = 0; /*赋值*/ for (sensor_num_c = 0; sensor_num_c < SENSOR_NUM; sensor_num_c++) { if (sensor_num_c == device->sensor_num_mask) { continue; } total += buff[sensor_num_c]; last_total += buff_snapshot[sensor_num_c]; } if (device->Weight_last != 0) { for (sensor_num_c = 0; sensor_num_c < SENSOR_NUM; sensor_num_c++) { if (sensor_num_c == device->sensor_num_mask) { continue; } /*限幅消抖*/ if (fabsf(last_total - total) < ALLOW_VALUE) { deal_drift++; if (deal_drift > N) { buff[sensor_num_c] = buff_snapshot[sensor_num_c]; } } else { deal_drift = 0; } } } // /*清零*/ total = 0; /*重新赋值*/ for (sensor_num_c = 0; sensor_num_c < SENSOR_NUM; sensor_num_c++) { if (sensor_num_c == device->sensor_num_mask) { continue; } if ((buff[sensor_num_c] < MAX_ZERO && buff[sensor_num_c] > MIN_ZERO)) { buff[sensor_num_c] = 0.f; } total += buff[sensor_num_c]; } memcpy(buff_snapshot, buff, sizeof(buff_snapshot)); return total; } static float Get_Weight(void) { WEIGHING_DEVICE *device = &_device; uint8_t sensor_num_c; // float Total = 0.f; float allot = 0.f; float buff[SENSOR_NUM] = {0.f}; for (sensor_num_c = 0; sensor_num_c < SENSOR_NUM; sensor_num_c++) { if (sensor_num_c == device->sensor_num_mask) { continue; } buff[sensor_num_c] = device->sensor[sensor_num_c]->Real_Weight; allot += buff[sensor_num_c]; } allot = allot / device->correct_k; /*用于校准时分配偏移量*/ // for (sensor_num_c = 0; sensor_num_c < SENSOR_NUM; sensor_num_c++) // { // if (sensor_num_c == device->sensor_num_mask) // { // continue; // } // device->sensor[sensor_num_c]->Scale = buff[sensor_num_c] / allot; // // if(device->sensor[sensor_num_c]->Scale <= 0.1f) // // { // // device->sensor[sensor_num_c]->Scale = NAN; // // } // } // Total = Deal_With_Jitter(device ,buff); return allot; } // static void Analog_Value(WEIGHING_DEVICE* _device, uint8_t num, float* buf) // { // float tmp = 0.f; // if(num) // { // WEIGHING_DEVICE* device = _device; // for(uint8_t sensor_num_c = 0; sensor_num_c < SENSOR_NUM; sensor_num_c++) // { // tmp += buf[sensor_num_c]; // } // buf[num - 1] = tmp / (SENSOR_NUM - 1); // tmp = 0; // for(uint8_t sensor_num_c = 0; sensor_num_c < SENSOR_NUM; sensor_num_c++) // { // tmp += device->sensor[sensor_num_c]->Scale; // } // device->sensor[num - 1]->Scale = tmp / SENSOR_NUM; // Err_Check_And_Set(GOWRONG); // } // else if(Check_No_Impact(device) == 0) // { // Err_Check_And_Set(0); // } // } static uint32_t Get_GrossWeight(struct SENSOR *sensor) { uint32_t GrossWeight = 0; int i, j, tmp1; uint32_t sum = 0; uint32_t tmp[5] = {0}; uint8_t err_count = 0; /*采集零点*/ for (i = 0; i < 5; ++i) { tmp[i] = read(sensor); if (tmp[i] <= 10) { WEIGHING_DEVICE *device = Get_Device_Handle(); err_count++; if (err_count > 10) { if (device->sensor_num_mask != 4) { sensor->err_flag = true; err_count = 0; return 0.f; } device->sensor_num_mask = sensor->Num; return 0.f; } i--; } } for (i = 0; i < 4; ++i) { for (j = i + 1; j < 5; ++j) { if (tmp[i] > tmp[j]) { tmp1 = tmp[i]; tmp[i] = tmp[j]; tmp[j] = tmp1; } } } for (i = 1; i < 4; i++) { sum += tmp[i]; } GrossWeight = sum / 3; return GrossWeight; } static void Get_All_GrossWeight(void) { WEIGHING_DEVICE *device = &_device; uint8_t sensor_num_c; /*上电后读取数据作为零点*/ for (sensor_num_c = 0; sensor_num_c < SENSOR_NUM; sensor_num_c++) { if (sensor_num_c == device->sensor_num_mask) { continue; } read(device->sensor[sensor_num_c]); } for (sensor_num_c = 0; sensor_num_c < SENSOR_NUM; sensor_num_c++) { if (sensor_num_c == device->sensor_num_mask) { continue; } device->sensor[sensor_num_c]->GrossWeight = Get_GrossWeight(device->sensor[sensor_num_c]); } device->check_self_flag = true; // 自检标志位 } #if 0 static void Calib_Creep(WEIGHING_DEVICE* _device, float* buf, float total_weight) { WEIGHING_DEVICE* device = _device; uint8_t sensor_num_c; float creep_value = 0.f; if(HAL_GetTick() - device->creep_time >= HALF_HOUR) { device->creep_count++; device->creep_time = HAL_GetTick(); for(sensor_num_c = 0; sensor_num_c < SENSOR_NUM; sensor_num_c++) { device->creep_snap += device->sensor[sensor_num_c]->Real_Weight; } creep_value = Get_Compare(device, total_weight); } if(device->creep_count) { for(sensor_num_c = 0; sensor_num_c < SENSOR_NUM; sensor_num_c++) { buf[sensor_num_c] += creep_value * device->creep_count; } // total_weight += creep_value * SENSOR_NUM * device->creep_count; } } static float Get_Compare(WEIGHING_DEVICE* _device, float total_weight) { return _device->creep_snap >= total_weight ? CREEP_VALUE : -CREEP_VALUE; } #endif