• 작동 전압 : 4.5~5.25V
  • 통신 방법 : UART, Modbus
  • 보드 레이트 : 9600bps
  • 측정 범위 : 400~2000ppm (PWM). 0~10000ppm (UART)
  • 정확도 : ±40ppm ±3%
  • 측정 간격 : 4초
  • 소비 전력 : 최대 300mA, 평균 18mA 이하
  • 마스터에서만 트랜잭션 시작 가능 (마스터에서 슬레이브로 명령어를 전송해야 슬레이브가 응답하는 방식)
  • 센서가 결함이 감지되지 않고 작동 중인지 확인하기 위해 주기적으로 센서의 상태를 체크해야 할 필요가 있음
  • ABC(Automatic Baseline Correction) 알고리즘 내장으로 일반적인 환경 하에선 유지보수로부터 자유로움
  • 미리 설정된 시간 간격동안 최하 판독값을 지속적으로 추적하고 예상된 신선한 공기에서의 CO2 값인 400ppm과 비교해 감지된 장기간 흐름을 천천히 수정함

 

[UART 설정]

  • 데이터 비트 길이 : 8비트 (패리티 비트 사용 X)
  • 스탑 비트 길이는 1, 2 비트 둘 다 사용 가능

  • 인터럽트 활용해 데이터 전송 및 수신

 

[데이터 전송 방법]

  • 기본적으로 마스터에서 센서로 데이터 버퍼를 보내면 센서가 이에 응답하는 방식
  • 센서의 각 레지스터는 16비트로 구성되어 있다
  • 센서로 보내는 데이터 버퍼는
  • 센서 주소(1) + 명령어(1) + 레지스터 시작 주소(2) + 읽어들일 레지스터 갯수(2) + CRC(2) 형태를 갖춘다
  • (괄호 안은 데이터의 크기 (바이트 기준))
  • 레지스터 시작 주소, 읽어들일 레지스터의 갯수, CRC는 상위1+하위1 총 2바이트로 나누어 전송해야 한다
  • 센서에서 마스터로 전송되는 데이터 버퍼는
  • 센서 주소(1) + 명령어(1) + 수신될 데이터의 바이트 크기(1) + 레지스터 데이터(레지스터 갯수*2) + CRC(2)
  • (읽어들일 레지스터 갯수에 맞춰 버퍼의 크기를 설정해야 한다)
  • CRC 값은 해당 데이터 버퍼의 0~CRC 직전까지의 데이터를 계산한 결과이므로 센서 응답의 CRC값은 유동적이다

1. CO2 값만을 읽어 올 때

  • 다음의 8바이트를 센서로 전송
  • <FE><04><00><03><00><01><C5><D5>
  • 센서 주소 : 0xFE
  • 명령어 : 0x04 (CO2 값이 저장된 인풋 레지스터를 읽어오는데 사용하는 명령어)
  • 레지스터 시작 주소 : 0x0003 (CO2 값이 저장된 인풋 레지스터3(0x03))
  • 레지스터 갯수 : 1 (0x0001)
  • CRC : D5C5 (하위 바이트인 C5 먼저 전송)
  • 예) 인풋 레지스터4(0x03)에 저장된 CO2 값(ppm 400(0x190h)이라 가정)을 읽어올 때
  • <FE><04><00><03><00><01><C5><D5> -총 8바이트를 전송
  • 센서는 이에 대한 응답으로
  • <FE><04><02><01><90><C5><D5> - 총 7바이트를 마스터로 전송
  • 센서 주소 + 명령어 + 전송되는 바이트 수(레지스터 갯수*2) + CO2 값 Hi + CO2 값 Lo + CRC Hi + CRC Lo

 

2. 센서 상태만을 읽어 올 때

  • 다음의 8바이트를 센서로 전송
  • <FE><04><00><00><00><01><25><C5>
  • 센서 상태는 인풋 레지스터1(0x00)에 저장되어 있으므로 인풋 레지스터를 읽는데 사용되는 0x04 명령어와 시작 주소 0x0000를 2바이트로 나누어 전송
  • 인풋 레지스터1에만 센서 상태가 저장되어 있으므로 읽어 올 레지스터의 갯수는 1 (0x0001)
  • CRC값 C525는 하위 25부터 전송
  • 센서는 다음과 같은 7바이트 데이터로 응답한다
  • <FE><04><02><00><00><AD><24>
  • 02는 전송되는 바이트의 수(레지스터 갯수*2)
  • 4,5번째의 <00><00>은 현재 센서의 에러 상태를 나타낸다

 

3. 센서와 CO2값을 한번에 읽어 올 때

  • 센서 상태는 인풋 레지스터1, CO2값은 인풋 레지스터4에 저장되므로 0x00~0x03까지 4개의 레지스터를 읽어와야 한다
  • <FE><04><00><00><00><04><E5><C6>
  • <FE>는 센서 주소(254), <04>는 인풋 레지스터 읽기 명령어인 0x04
  • 3,4 번째 <00><00>은 시작 주소 인풋 레지스터1 주소인 0x0000을 나타냄
  • 5,6 번째 <00><04>는 읽어 올 레지스터의 갯수인 4를 나타냄
  • <E5><C6>은 CRC 값
  • 센서는 다음과 같은 13바이트 데이터로 응답
  • <FE><04><08><00><00><00><00><00><00><01><90><16><E6>
  • 3번째 <08>은 전송될 데이터의 바이트 크기가 8바이트임을 의미 (레지스터 갯수 4*2)
  • 4,5번째 <00><00>은 인풋 레지스터1에 저장된 센서 상태를 나타냄
  • 6~7, 8~9는 각각 인풋 레지스터2(알람 상태), 3(아웃풋 상태)을 나타냄
  • 10,11번째 <01><90>은 측정된 CO2값을 나타냄 (0x190=400ppm)
  • <16><E6>은 CRC값

[코드]

- STM32Cube - Repository 내 Examples 중 UART_TwoBoards_ComIT 를 참조

- 센서의 CO2 측정 간격은 4초이므로 CO2 값을 4초 미만의 간격으로 읽어 올 필요는 없다

 

- CO2값을 읽어 올 때

//CO2 값을 읽기 위해 S8 센서로 보내는 데이터 버퍼
uint8_t send_Buffer[8]={0xFE, 0x04, 0x00, 0x03, 0x00, 0x01, 0xD5, 0xC5};

//S8 센서로부터 받아오는 데이터를 저장하기 위한 13바이트 데이터 버퍼
uint8_t receive_Buffer[7]={0};	

//상,하 1바이트씩 나뉘어 수신되는 CO2 값을 하나로 합치는데 사용
uint16_t co2_Value;	

//CO2 값 읽어오기 위한 데이터 버퍼를 센서로 전송
//데이터 전송에 사용할 UART, 전송할 버퍼, 전송할 데이터의 바이트 크기
if(HAL_UART_Transmit_IT(&hlpuart1,(uint8_t*)send_Buffer,8)!=HAL_OK) 
{
	Error_Handler();
}
//버퍼 전송 완료되기 전까지 대기
while(HAL_UART_GetState(&hlpuart1)==HAL_UART_STATE_BUSY_TX)
{
}
//버퍼 전송 완료 후, 센서 응답을 수신하기 위해 사용 중인 UART를 수신 상태로 둠
//데이터 수신에 사용할 UART, 전송된 데이터를 저장할 버퍼, 수신할 데이터의 바이트 크기
if(HAL_UART_Receive_IT(&hlpuart1,(uint8_t*)receive_Buffer,7)!=HAL_OK)
{
	Error_Handler();
}
//센서 응답 수신 완료까지 대기
while(HAL_UART_GetState(&hlpuart1)==HAL_UART_STATE_BUSY_RX)
{
}

//센서로부터 전달 받은 CO2 값의 상위 1바이트는 receive_Buffer[3], 하위 1바이트는 receive_Buffer[4]에 저장됨
//비트시프트를 사용하여 16비트 변수 co2_Value에 CO2 값을 하나로 합침
co2_Value=(receive_Buffer[3]<<8)|(receive_Buffer[4]);

CO2 측정 결과

 

-센서 상태를 읽어 올 때

//센서 상태를 읽기 위해 S8 센서로 보내는 데이터 버퍼
uint8_t send_Buffer[8]={0xFE, 0x04, 0x00, 0x00, 0x00, 0x01, 0x25, 0xC5};

//S8 센서로부터 받아오는 데이터를 저장하기 위한 7바이트 데이터 버퍼
uint8_t receive_Buffer[7]={0};	

//센서 상태 값 읽어오기 위한 데이터 버퍼를 센서로 전송
//데이터 전송에 사용할 UART, 전송할 버퍼, 전송할 데이터의 바이트 크기
if(HAL_UART_Transmit_IT(&hlpuart1,(uint8_t*)send_Buffer,8)!=HAL_OK) 
{
	Error_Handler();
}
//버퍼 전송 완료되기 전까지 대기
while(HAL_UART_GetState(&hlpuart1)==HAL_UART_STATE_BUSY_TX)
{
}
//버퍼 전송 완료 후, 센서 응답을 수신하기 위해 사용 중인 UART를 수신 상태로 둠
//데이터 수신에 사용할 UART, 전송된 데이터를 저장할 버퍼, 수신할 데이터의 바이트 크기
if(HAL_UART_Receive_IT(&hlpuart1,(uint8_t*)receive_Buffer,7)!=HAL_OK)
{
	Error_Handler();
}
//센서 응답 수신 완료까지 대기
while(HAL_UART_GetState(&hlpuart1)==HAL_UART_STATE_BUSY_RX)
{
}

//receive_Buffer[4]에 저장된 0~6 비트를 데이터 시트를 참고해 어떤 종류의 에러인지를 판단
if((receive_Buffer[4]&&1)==1)
{
	//Fatal error
}
else if((receive_Buffer[4]>>1)&&1==1)
{
	//Offset regulation error
}
else if((receive_Buffer[4]>>2)&&1==1)
{
	//Algorithm error
}
else if((receive_Buffer[4]>>3)&&1==1)
{
	//Output error
}    
else if((receive_Buffer[4]>>4)&&1==1)
{
	//Self diagnostics error
}
else if((receive_Buffer[4]>>5)&&1==1)
{
	//Out of Range
}
else if((receive_Buffer[4]>>6)&&1==1)
{
	//Memory error
}
else
{
	//No error
}

S8 센서 상태 확인 결과

+ Recent posts