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.

153 lines
4.4 KiB

  1. #include "h2o2_sensor.hpp"
  2. #include <stdio.h>
  3. #include <string.h>
  4. #include "adc.h"
  5. #ifdef HAL_CAN_MODULE_ENABLED
  6. using namespace iflytop;
  7. using namespace zcr;
  8. #define TAG "H2O2Sensor"
  9. void H2O2Sensor::initialize(ZCanReceiver* zcanReceiver) {
  10. zcanReceiver->registerListener(this);
  11. m_zcanReceiver = zcanReceiver;
  12. }
  13. void H2O2Sensor::regSubmodule(int id, UART_HandleTypeDef* huart, uint8_t modbusid) {
  14. ZASSERT(huart != NULL);
  15. m_sensorId = id;
  16. m_modbusid = modbusid;
  17. modbusBlockHost.initialize(huart);
  18. readSensorData();
  19. }
  20. uint32_t H2O2Sensor::readAvgAdcVal() {
  21. // 读取15次,取中间十个数取平均值
  22. uint32_t adcv[15] = {0}; // 15次采样
  23. for (int i = 0; i < 15; i++) {
  24. adcv[i] = readAdcVal();
  25. }
  26. // 冒泡排序
  27. for (int i = 0; i < 15; i++) {
  28. for (int j = 0; j < 15 - i - 1; j++) {
  29. if (adcv[j] > adcv[j + 1]) {
  30. uint32_t temp = adcv[j];
  31. adcv[j] = adcv[j + 1];
  32. adcv[j + 1] = temp;
  33. }
  34. }
  35. }
  36. uint32_t sum = 0;
  37. for (int i = 2; i < 12; i++) {
  38. sum += adcv[i];
  39. }
  40. return sum / 10;
  41. }
  42. uint32_t H2O2Sensor::readAdcVal() {
  43. ADC_ChannelConfTypeDef sConfig; // 通道初始化
  44. uint8_t id;
  45. sConfig.Channel = ADC_CHANNEL_9;
  46. sConfig.SamplingTime = ADC_SAMPLETIME_480CYCLES; // 采用周期239.5周期
  47. sConfig.Rank = 1;
  48. HAL_ADC_ConfigChannel(&hadc1, &sConfig);
  49. uint32_t adcv = 0; //
  50. HAL_ADC_Start(&hadc1); // 启动转换
  51. HAL_ADC_PollForConversion(&hadc1, 30); // 等待转化结束
  52. adcv = HAL_ADC_GetValue(&hadc1); // 求和
  53. HAL_ADC_Stop(&hadc1); // 停止转换
  54. return adcv; // 返回平均值
  55. }
  56. typedef struct {
  57. int16_t rh; // Relative humidity %RH * 10
  58. int16_t temp; // Temperature °C * 10
  59. int16_t df_ptemp; // Dew/frost point temperature °C * 10
  60. int16_t ah; // Absolute humidity g/m3 * 10
  61. int16_t mr; // Mixing ratio g/kg * 10
  62. int16_t wet_bulb_temp; // Wet-bulb temperature °C * 10
  63. int16_t enthalpy; // Enthalpy kJ/kg * 10
  64. } hmp110_sensordata_t;
  65. hpp272_data_t* H2O2Sensor::readSensorData() {
  66. sensordatacache.hydrogen_peroxide_volume = 0;
  67. sensordatacache.h2o_h2o2_rs = 1 * 100;
  68. sensordatacache.temperature1 = 20 * 100;
  69. sensordatacache.relative_humidity = 31 * 100;
  70. static uint16_t rxbuf[128];
  71. static hmp110_sensordata_t sensordata;
  72. memset(rxbuf, 0, sizeof(rxbuf));
  73. bool suc = modbusBlockHost.readReg03Muti(1, 0x0100, rxbuf, 7, 300);
  74. if (suc) {
  75. sensordata.rh = rxbuf[0];
  76. sensordata.temp = rxbuf[1];
  77. sensordata.df_ptemp = rxbuf[2];
  78. sensordata.ah = rxbuf[3];
  79. sensordata.mr = rxbuf[4];
  80. sensordata.wet_bulb_temp = rxbuf[5];
  81. sensordata.enthalpy = rxbuf[6];
  82. sensordatacache.temperature1 = sensordata.temp * 10;
  83. sensordatacache.relative_humidity = sensordata.rh * 10;
  84. } else {
  85. ZLOGI(TAG, "readSensorData fail");
  86. sensordatacache.temperature1 = 0;
  87. sensordatacache.relative_humidity = 0;
  88. }
  89. uint32_t adcv = readAvgAdcVal();
  90. float mv = adcv / 4095.0 * 3.3 * 1000;
  91. float ma = mv / 150.0;
  92. float ppm = (ma - 4) / (20 - 4) * 2000;
  93. if (ppm < 0) ppm = 0;
  94. ZLOGI(TAG, " i:%f ppm:%f temp:%d rh:%d", ma, ppm, sensordatacache.temperature1, sensordatacache.relative_humidity);
  95. sensordatacache.hydrogen_peroxide_volume = ppm;
  96. if (sensordatacache.hydrogen_peroxide_volume < 10) {
  97. sensordatacache.hydrogen_peroxide_volume = 0;
  98. }
  99. // sensordatacache.hydrogen_peroxide_volume = 9973;
  100. return &sensordatacache;
  101. }
  102. void H2O2Sensor::onRceivePacket(Cmdheader_t* cmdheader, int sensorId) {
  103. if (sensorId != m_sensorId) {
  104. return;
  105. }
  106. hpp272_data_t* sensordata = readSensorData();
  107. if (sensordata) {
  108. txbuff[0] = sensorId;
  109. txbuff[1] = 0;
  110. memcpy(txbuff + 2, sensordata, sizeof(hpp272_data_t));
  111. m_zcanReceiver->sendAck(cmdheader, txbuff, sizeof(hpp272_data_t) + 2);
  112. } else {
  113. ZLOGE(TAG, "hpp272 is null");
  114. int16_t errcode = 1002; // 设备不在线
  115. m_zcanReceiver->sendErrorAck(cmdheader, errcode);
  116. }
  117. return;
  118. }
  119. void H2O2Sensor::onRceivePacket(CanPacketRxBuffer* rxbuf, uint8_t* packet, size_t len) {
  120. Cmdheader_t* cmdheader = (Cmdheader_t*)packet;
  121. if (cmdheader->cmdid == kcmd_m211887_operation && cmdheader->subcmdid == 0) {
  122. uint8_t id = cmdheader->data[0];
  123. onRceivePacket(cmdheader, id);
  124. }
  125. }
  126. #endif