#include "h2o2_sensor.hpp" #include #include #include "adc.h" #ifdef HAL_CAN_MODULE_ENABLED using namespace iflytop; using namespace zcr; #define TAG "H2O2Sensor" void H2O2Sensor::initialize(ZCanReceiver* zcanReceiver) { zcanReceiver->registerListener(this); m_zcanReceiver = zcanReceiver; } void H2O2Sensor::regSubmodule(int id, UART_HandleTypeDef* huart, uint8_t modbusid) { ZASSERT(huart != NULL); m_sensorId = id; m_modbusid = modbusid; modbusBlockHost.initialize(huart); readSensorData(); } uint32_t H2O2Sensor::readAvgAdcVal() { // 读取15次,取中间十个数取平均值 uint32_t adcv[15] = {0}; // 15次采样 for (int i = 0; i < 15; i++) { adcv[i] = readAdcVal(); } // 冒泡排序 for (int i = 0; i < 15; i++) { for (int j = 0; j < 15 - i - 1; j++) { if (adcv[j] > adcv[j + 1]) { uint32_t temp = adcv[j]; adcv[j] = adcv[j + 1]; adcv[j + 1] = temp; } } } uint32_t sum = 0; for (int i = 2; i < 12; i++) { sum += adcv[i]; } return sum / 10; } uint32_t H2O2Sensor::readAdcVal() { ADC_ChannelConfTypeDef sConfig; // 通道初始化 uint8_t id; sConfig.Channel = ADC_CHANNEL_9; sConfig.SamplingTime = ADC_SAMPLETIME_480CYCLES; // 采用周期239.5周期 sConfig.Rank = 1; HAL_ADC_ConfigChannel(&hadc1, &sConfig); uint32_t adcv = 0; // HAL_ADC_Start(&hadc1); // 启动转换 HAL_ADC_PollForConversion(&hadc1, 30); // 等待转化结束 adcv = HAL_ADC_GetValue(&hadc1); // 求和 HAL_ADC_Stop(&hadc1); // 停止转换 return adcv; // 返回平均值 } typedef struct { int16_t rh; // Relative humidity %RH * 10 int16_t temp; // Temperature °C * 10 int16_t df_ptemp; // Dew/frost point temperature °C * 10 int16_t ah; // Absolute humidity g/m3 * 10 int16_t mr; // Mixing ratio g/kg * 10 int16_t wet_bulb_temp; // Wet-bulb temperature °C * 10 int16_t enthalpy; // Enthalpy kJ/kg * 10 } hmp110_sensordata_t; hpp272_data_t* H2O2Sensor::readSensorData() { sensordatacache.hydrogen_peroxide_volume = 0; sensordatacache.h2o_h2o2_rs = 1 * 100; sensordatacache.temperature1 = 20 * 100; sensordatacache.relative_humidity = 31 * 100; static uint16_t rxbuf[128]; static hmp110_sensordata_t sensordata; memset(rxbuf, 0, sizeof(rxbuf)); bool suc = modbusBlockHost.readReg03Muti(1, 0x0100, rxbuf, 7, 300); if (suc) { sensordata.rh = rxbuf[0]; sensordata.temp = rxbuf[1]; sensordata.df_ptemp = rxbuf[2]; sensordata.ah = rxbuf[3]; sensordata.mr = rxbuf[4]; sensordata.wet_bulb_temp = rxbuf[5]; sensordata.enthalpy = rxbuf[6]; sensordatacache.temperature1 = sensordata.temp * 10; sensordatacache.relative_humidity = sensordata.rh * 10; } else { ZLOGI(TAG, "readSensorData fail"); sensordatacache.temperature1 = 0; sensordatacache.relative_humidity = 0; } uint32_t adcv = readAvgAdcVal(); float mv = adcv / 4095.0 * 3.3 * 1000; float ma = mv / 150.0; float ppm = (ma - 4) / (20 - 4) * 2000; if (ppm < 0) ppm = 0; ZLOGI(TAG, " i:%f ppm:%f temp:%d rh:%d", ma, ppm, sensordatacache.temperature1, sensordatacache.relative_humidity); sensordatacache.hydrogen_peroxide_volume = ppm; if (sensordatacache.hydrogen_peroxide_volume < 10) { sensordatacache.hydrogen_peroxide_volume = 0; } // sensordatacache.hydrogen_peroxide_volume = 9973; return &sensordatacache; } void H2O2Sensor::onRceivePacket(Cmdheader_t* cmdheader, int sensorId) { if (sensorId != m_sensorId) { return; } hpp272_data_t* sensordata = readSensorData(); if (sensordata) { txbuff[0] = sensorId; txbuff[1] = 0; memcpy(txbuff + 2, sensordata, sizeof(hpp272_data_t)); m_zcanReceiver->sendAck(cmdheader, txbuff, sizeof(hpp272_data_t) + 2); } else { ZLOGE(TAG, "hpp272 is null"); int16_t errcode = 1002; // 设备不在线 m_zcanReceiver->sendErrorAck(cmdheader, errcode); } return; } void H2O2Sensor::onRceivePacket(CanPacketRxBuffer* rxbuf, uint8_t* packet, size_t len) { Cmdheader_t* cmdheader = (Cmdheader_t*)packet; if (cmdheader->cmdid == kcmd_m211887_operation && cmdheader->subcmdid == 0) { uint8_t id = cmdheader->data[0]; onRceivePacket(cmdheader, id); } } #endif