/* USER CODE BEGIN Header */ /** ****************************************************************************** * @file yunhorn_sts_aq_o3.c * * @author Yunhorn (r) Technology Limited Application Team * * @brief Yunhorn (r) SmarToilets (r) Product configuration file. * ****************************************************************************** * @attention * * Copyright (c) 2025 Yunhorn Technology Limited. * Copyright (c) 2025 Shenzhen Yunhorn Technology Co., Ltd. * All rights reserved. * * This software is licensed under terms that can be found in the LICENSE file * in the root directory of this software component. * If no LICENSE file comes with this software, it is provided AS-IS. * ****************************************************************************** */ /* USER CODE END Header */ #include "main.h" #include "usart.h" #include "stdio.h" #include "sts_aq_o3.h" uint8_t aTxBuffer[9] = {0x0}; uint8_t aRxBuffer[9] = {0x0}; uint8_t querymode[9] = {0xff, 0x01, 0x78,0x41,0x00,0x00,0x00,0x00,0x46}; uint8_t queryonce[9] = {0xff, 0x01, 0x86,0x00,0x00,0x00,0x00,0x00,0x79}; uint8_t autonymode[9] = {0xff, 0x01, 0x78,0x40,0x00,0x00,0x00,0x00,0x47}; volatile sts_sensor_o3_t sts_sensor_data; void sts_aq_o3_init(void) { } int sts_aq_o3_start_autony_mode(void) { printf("change to autony mode\r\n"); if (HAL_UART_Transmit_IT(&huart1, (uint8_t *)autonymode, 9) != HAL_OK) { printf("\r\n Transmit anony mode failure \r\n"); return -1; } else { printf("\r\n Change to anony mode success \r\n"); } return 0; } int sts_aq_o3_start_pooling_mode(void) { printf("change to querymode\r\n"); if (HAL_UART_Transmit_IT(&huart1, (uint8_t *)querymode, 9) != HAL_OK) { printf("\r\n Transmit pooling mode failure \r\n"); return -1; } return 0; } void sts_aq_o3_autony_run_mode(sts_sensor_o3_t *sts_sensor_data) { /*##-1- Put UART peripheral in reception process ###########################*/ if (HAL_UART_Receive_IT(&huart1, (uint8_t *)aRxBuffer, 9) != HAL_OK) { printf("\r\n Periodic Receiving data failure ...........\r\n"); return ; } printf("\nSensor data = "); for (uint8_t j=0; jo3_ppb = (int)(aRxBuffer[4]*256+aRxBuffer[5]); sts_sensor_data->o3_range = (int)(aRxBuffer[6]*256+aRxBuffer[7]); sts_sensor_data->o3_unit = (uint8_t)aRxBuffer[2]; sts_sensor_data->o3_mg_per_m3 = (float)(2.140*(float)((aRxBuffer[4]*256+aRxBuffer[5])/1000.0)); // printf("\r\n O3 = %04d (max:%4d) %3s %.2f mg/m3 \r\n", (int)(aRxBuffer[4]*256+aRxBuffer[5]), // (int)(aRxBuffer[6]*256+aRxBuffer[7]),(aRxBuffer[2]==0x04)?"ppb":"ppm", (float)(2.140*(float)((aRxBuffer[4]*256+aRxBuffer[5])/1000.0))); } int sts_aq_o3_query(sts_sensor_o3_t *sts_sensor_data) { uint8_t i=0; if (HAL_UART_Transmit_IT(&huart1, (uint8_t *)queryonce, 9) != HAL_OK) { printf("\r\n Transmit query once failure \r\n"); return -1; } else { printf("\r\n Query cmd sent out = "); for (i=0; i< sizeof(queryonce); i++) printf("%02x ",*(queryonce+i)); } if (HAL_UART_Receive_IT(&huart1, (uint8_t *)aRxBuffer, 9) != HAL_OK) { printf("\r\n UART Receiving data failure \r\n"); return -2; } printf("\n Received data = "); for (uint8_t j=0; jo3_ppb = (int)(aRxBuffer[4]*256+aRxBuffer[5]); sts_sensor_data->o3_range = (int)(aRxBuffer[6]*256+aRxBuffer[7]); sts_sensor_data->o3_unit = (uint8_t)aRxBuffer[2]; sts_sensor_data->o3_mg_per_m3 = (float)(2.140*(float)((aRxBuffer[4]*256+aRxBuffer[5])/1000.0)); } else { printf("\r\n Received data invalid xxxxx \r\n"); return -3; } return 0; // printf("\r\n Seq:=%5d Read O3 = %d (ppb) [Range=%d unit=%s ] | == %.2f mg/m3 \r\n", i, (int)(aRxBuffer[4]*256+aRxBuffer[5]), // (int)(aRxBuffer[6]*256+aRxBuffer[7]),(aRxBuffer[2]==0x04)?"ppb":"ppm", (float)(2.140*(float)((aRxBuffer[4]*256+aRxBuffer[5])/1000.0))); } /************************************************************************************ *************************************************************************************/ uint32_t KalmanFilter(uint32_t inData) { static float prevData = 0; //先前数值 static float p = 10, q = 0.001, r = 0.001, kGain = 0; // q控制误差 r控制响应速度 p = p + q; kGain = p / ( p + r ); //计算卡尔曼增益 inData = prevData + ( kGain * ( inData - prevData ) ); //计算本次滤波估计值 p = ( 1 - kGain ) * p; //更新测量方差 prevData = inData; return inData; //返回滤波值 }