312 lines
9.2 KiB
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;
|
|
}
|
|
|
|
}
|