STS_E2/AirQuality/Src/sensor.c

312 lines
9.2 KiB
C

#include "main.h"
#include "sensor.h"
#include "string.h"
#include "sht3x.h"
#include "usart_user.h"
//PM2.5命令
const uint8_t cmd_pm25_duqu[7] = {0x42,0x4D,0xE2,0x00,0x00,0x01,0x71};//主动读取数据
const uint8_t cmd_pm25_beidong[7] = {0x42,0x4D,0xE1,0x00,0x00,0x01,0x70};//设置传感器为应答模式
const uint8_t cmd_pm25_zhudong[7] = {0x42,0x4D,0xE1,0x00,0x01,0x01,0x71};//设置传感器为主动上传模式
const uint8_t cmd_pm25_daiji[7] = {0x42,0x4D,0xE4,0x00,0x00,0x01,0x73};//设置传感器进入待机模式
const uint8_t cmd_pm25_zhengchang[7] = {0x42,0x4D,0xE4,0x00,0x01,0x01,0x74};//设置传感器进入正常模式
//CO2命令
const uint8_t cmd_co2_duqu[9] = {0xFF,0x01,0x86,0x00,0x00,0x00,0x00,0x00,0x79};//主动读取数据
const uint8_t cmd_co2_liangcheng2[9] = {0xFF,0x01,0x99,0x00,0x00,0x00,0x07,0xD0,0x8F};//设置二氧化碳量程为0-2000ppm
const uint8_t cmd_co2_liangcheng5[9] = {0xFF,0x01,0x99,0x00,0x00,0x00,0x13,0x88,0xCB};//设置二氧化碳量程为0-5000ppm
const uint8_t cmd_co2_liangcheng10[9] = {0xFF,0x01,0x99,0x00,0x00,0x00,0x27,0x10,0x2F};//设置二氧化碳量程为0-10000ppm
//NH3/H2S命令
const uint8_t cmd_nh3_h2s_duqu[9] = {0xFF,0x01,0x86,0x00,0x00,0x00,0x00,0x00,0x79};//主动读取数据
const uint8_t cmd_nh3_h2s_beidong[9] = {0xFF,0x01,0x78,0x04,0x00,0x00,0x00,0x00,0x83};//设置传感器为应答模式
const uint8_t cmd_nh3_h2s_zhudong[9] = {0xFF,0x01,0x86,0x03,0x00,0x00,0x00,0x00,0x84};//设置传感器为主动上传模式
//CH2O命令
const uint8_t cmd_CH2O_duqu[9] = {0xFF,0x01,0x86,0x00,0x00,0x00,0x00,0x00,0x79};//主动读取数据
const uint8_t cmd_CH2O_beidong[9] = {0xFF,0x01,0x78,0x41,0x00,0x00,0x00,0x00,0x46};//设置传感器为应答模式
const uint8_t cmd_CH2O_zhudong[9] = {0xFF,0x01,0x78,0x40,0x00,0x00,0x00,0x00,0x47};//设置传感器为主动上传模式
//O3命令
const uint8_t cmd_O3_duqu[9] = {0xFF,0x01,0x86,0x00,0x00,0x00,0x00,0x00,0x79};//主动读取数据
const uint8_t cmd_O3_beidong[9] = {0xFF,0x01,0x78,0x41,0x00,0x00,0x00,0x00,0x46};//设置传感器为应答模式
const uint8_t cmd_O3_zhudong[9] = {0xFF,0x01,0x78,0x40,0x00,0x00,0x00,0x00,0x47};//设置传感器为主动上传模式
sensor_parse_ctrl_t nh3;
sensor_parse_ctrl_t h2s;
sensor_parse_ctrl_t co2;
sensor_parse_ctrl_t pm25;
sensor_parse_ctrl_t ch2o;
sensor_parse_ctrl_t o3;
SensorDataTypeDef sensorData;
void InitSonsorData(SensorDataTypeDef *sensorData)
{
sensorData->temperature = 26.00;
sensorData->humidity = 50.00;
sensorData->nh3 = 1.00;
sensorData->h2s = 0.01;
sensorData->ch2o = 0.01;
sensorData->co2 = 400;
sensorData->tvoc = 0;
sensorData->pm25 = 20;
sensorData->pm10 = 25;
sensorData->temperature1 = 25;
sensorData->temperature2 = 55;
sensorData->humidity1 = 43;
sensorData->humidity2 = 46;
sensorData->nh31 = 5;
sensorData->nh32 = 4;
sensorData->h2s1 = 7;
sensorData->h2s2 = 18;
sensorData->ch2o1 = 4;
sensorData->ch2o2 = 78;
sensorData->co21 = 4;
sensorData->co22 = 112;
sensorData->o31 = 0;
sensorData->o32 = 0;
sensorData->tvoca = 1;
sensorData->tvocb = 1;
sensorData->pm251 = 2;
sensorData->pm252 = 45;
sensorData->pm101 = 5;
sensorData->pm102 = 45;
}
//初始化结构体
void InitSonsorCtrlData(sensor_parse_ctrl_t *sensor_parse_ctrl, uint8_t data_length, uint8_t type)
{
sensor_parse_ctrl->type = type;
RingBuff_Init(&sensor_parse_ctrl->recvRingBuff);
sensor_parse_ctrl->data_length = data_length;
sensor_parse_ctrl->function = NULL;
}
void SensorModeInitSet(void)
{
//PM25设置为应答模式
LL_mDelay(50);
UsartxSendDataStr(PM25_USART,cmd_pm25_beidong,sizeof(cmd_pm25_beidong));
//CH2O设置为应答模式
LL_mDelay(50);
UsartxSendDataStr(CH2O_USART,cmd_CH2O_beidong,sizeof(cmd_CH2O_beidong));
//H2S设置为应答模式
LL_mDelay(50);
UsartxSendDataStr(H2S_USART,cmd_nh3_h2s_beidong,sizeof(cmd_nh3_h2s_beidong));
//NH3设置为应答模式
LL_mDelay(50);
UsartxSendDataStr(NH3_USART,cmd_nh3_h2s_beidong,sizeof(cmd_nh3_h2s_beidong));
//CO2设置为应答模式
LL_mDelay(50);
UsartxSendDataStr(CO2_USART,cmd_co2_liangcheng2,sizeof(cmd_co2_liangcheng2));
//O3设置为应答模式
LL_mDelay(50);
UsartxSendDataStr(O3_USART,cmd_O3_beidong,sizeof(cmd_O3_beidong));
//init sht3x sensor
LL_mDelay(50);
SHT3X_Init(0x44);
LL_mDelay(50);
}
void GetSensorData(void)
{
//PM2.5发送获取数据命令
LL_mDelay(50);
UsartxSendDataStr(USART4, cmd_pm25_duqu, sizeof(cmd_pm25_duqu));
//CO2发送获取数据命令
LL_mDelay(50);
UsartxSendDataStr(CO2_USART, cmd_co2_duqu, sizeof(cmd_co2_duqu));
//O3发送获取数据命令
LL_mDelay(50);
UsartxSendDataStr(O3_USART, cmd_O3_duqu, sizeof(cmd_O3_duqu));
//CH2O发送获取数据命令
LL_mDelay(50);
UsartxSendDataStr(CH2O_USART,cmd_CH2O_duqu,sizeof(cmd_CH2O_duqu));
//H2S发送获取数据命令
LL_mDelay(50);
UsartxSendDataStr(H2S_USART,cmd_nh3_h2s_duqu,sizeof(cmd_nh3_h2s_duqu));
//NH3发送获取数据命令
LL_mDelay(50);
UsartxSendDataStr(NH3_USART,cmd_nh3_h2s_duqu,sizeof(cmd_nh3_h2s_duqu));
//获取温湿度数据
LL_mDelay(50);
SHT3X_GetTempAndHumi(&sensorData.temperature, &sensorData.humidity, REPEATAB_HIGH, MODE_POLLING, 50);
if(sensorData.temperature >= 0)
{
sensorData.symbol = 1&0xFF;
}
else
{
sensorData.symbol = 0&0xFF;
}
sensorData.temperature1 = ((int)sensorData.temperature)&0xFF;
sensorData.temperature2 = ((int)((sensorData.temperature)*100)%100)&0xFF;
sensorData.humidity1 = ((int)sensorData.humidity)&0xFF;
sensorData.humidity2 = ((int)((sensorData.humidity)*100)%100)&0xFF;
sensorData.tvoca = LL_GPIO_IsInputPinSet(GPIOB,LL_GPIO_PIN_10);
sensorData.tvocb = LL_GPIO_IsInputPinSet(GPIOB,LL_GPIO_PIN_10);
if(sensorData.tvoca == 0 & sensorData.tvocb == 0)
sensorData.tvoc = 0;
if(sensorData.tvoca == 0 & sensorData.tvocb == 1)
sensorData.tvoc = 1;
if(sensorData.tvoca == 1 & sensorData.tvocb == 0)
sensorData.tvoc = 2;
if(sensorData.tvoca == 1 & sensorData.tvocb == 1)
sensorData.tvoc = 3;
}
void ReadSensorData(sensor_parse_ctrl_t *sensor_parse_ctrl)
{
uint8_t recdata[1];
uint32_t data_length = 0;
if(Read_Length_RingBuff(&sensor_parse_ctrl->recvRingBuff) < sensor_parse_ctrl->data_length)
{
while(Read_RingBuff(&sensor_parse_ctrl->recvRingBuff,recdata)){};
}
else
{
while(Read_RingBuff(&sensor_parse_ctrl->recvRingBuff,recdata))
{
sensor_parse_ctrl->sensorData[data_length] = recdata[0];
data_length++;
if(data_length >= sensor_parse_ctrl->data_length)
{
while(Read_RingBuff(&sensor_parse_ctrl->recvRingBuff,recdata)){};
}
}
}
}
static void general_data_check(sensor_parse_ctrl_t *sensor_parse_ctrl)
{
if((sensor_parse_ctrl->sensorData[0] != 0xFF) || (sensor_parse_ctrl->sensorData[1] != 0x86))
{
return;
}
uint8_t temp = 0x00;
for(int i = 1; i<sensor_parse_ctrl->data_length-1; i++)
{
temp += sensor_parse_ctrl->sensorData[i];
}
temp = (~temp)+1;
if((temp&0xFF) == sensor_parse_ctrl->sensorData[sensor_parse_ctrl->data_length-1])
{
switch (sensor_parse_ctrl->type)
{
case CO2_TYPE:
sensorData.co2 = (sensor_parse_ctrl->sensorData[2]*256+sensor_parse_ctrl->sensorData[3]);
sensorData.co21 = ((sensorData.co2)>>8)&0xFF;
sensorData.co22 = (sensorData.co2)&0xFF;
break;
case O3_TYPE:
sensorData.o3 = (sensor_parse_ctrl->sensorData[2]*256+sensor_parse_ctrl->sensorData[3]);
sensorData.o31 = ((sensorData.o3)>>8)&0xFF;
sensorData.o32 = (sensorData.o3)&0xFF;
break;
case CH2O_TYPE:
sensorData.ch2o = (sensor_parse_ctrl->sensorData[6]*256+sensor_parse_ctrl->sensorData[7])/1000.00;
sensorData.ch2o1 = ((int)sensorData.ch2o)&0xFF;
sensorData.ch2o2 = ((int)((sensorData.ch2o)*100)%100)&0xFF;
break;
case NH3_TYPE:
sensorData.nh3 = (sensor_parse_ctrl->sensorData[2]*256+sensor_parse_ctrl->sensorData[3])/100.00;
sensorData.nh31 = ((int)sensorData.nh3)&0xFF;
sensorData.nh32 = ((int)((sensorData.nh3)*100)%100)&0xFF;
break;
case H2S_TYPE:
sensorData.h2s = (sensor_parse_ctrl->sensorData[2]*256+sensor_parse_ctrl->sensorData[3])/100.00;
sensorData.h2s1 = ((int)sensorData.h2s)&0xFF;
sensorData.h2s2 = ((int)((sensorData.h2s)*100)%100)&0xFF;
break;
default:
break;
}
}
memset(sensor_parse_ctrl->sensorData, 0, sizeof(sensor_parse_ctrl->sensorData));
}
static void pm25_data_check(sensor_parse_ctrl_t *sensor_parse_ctrl)
{
//PM25数据校验
uint16_t PM25_temp = 0x0000;
if((sensor_parse_ctrl->sensorData[0] != 0x42) || (sensor_parse_ctrl->sensorData[1] != 0x4D))
{
return;
}
for(int i = 0; i < sensor_parse_ctrl->data_length-2; i++)
{
PM25_temp += sensor_parse_ctrl->sensorData[i];
}
if((PM25_temp>>8) == sensor_parse_ctrl->sensorData[30] && (PM25_temp&0xFF)==sensor_parse_ctrl->sensorData[31])
{
sensorData.pm25 = (sensor_parse_ctrl->sensorData[12]*256+sensor_parse_ctrl->sensorData[13]);
sensorData.pm10 = (sensor_parse_ctrl->sensorData[14]*256+sensor_parse_ctrl->sensorData[15]);
sensorData.pm251 = ((sensorData.pm25)>>8)&0xFF;
sensorData.pm252 = ((sensorData.pm25))&0xFF;
sensorData.pm101 = ((sensorData.pm10)>>8)&0xFF;
sensorData.pm102 = (sensorData.pm10)&0xFF;
}
memset(sensor_parse_ctrl->sensorData, 0, sizeof(sensor_parse_ctrl->sensorData));
}
void AnalysisSensorData(sensor_parse_ctrl_t *sensor_parse_ctrl)
{
switch (sensor_parse_ctrl->type)
{
case H2S_TYPE:
case CO2_TYPE:
case O3_TYPE:
case NH3_TYPE:
case CH2O_TYPE:
general_data_check(sensor_parse_ctrl);
break;
case PM25_TYPE:
pm25_data_check(sensor_parse_ctrl);
break;
}
}