CozIR-LP3

LOW Power CO2 Sensor의 사용법 및 예제 코드를 설명.

1. Cozir-LP2에서 추가된 기능

  • 알람 기능

- 사용자 알람 값을 설정하였을 경우 알람 값에 도달 하면 디지털 출력으로 사용자에게 알려줌

  • 알람 UART Command

CommandDescriptionResponse

V #####

알람 값 설정

V #####

v

현재 알람 값 읽기

v 15000

- 알람 값은 센서 전원을 껐다 켜도 유지됨

- 초기에는 알람 설정이 꺼져있음

  • PWM 기능

- 통신 프로토콜을 이용하여 Prescalar, Resolution, mode, pulses setting, pwm on/off 설정 가능

  • PWM UART Command

CommandDescriptionResponse

J ###

PWM 설정( Prescalar, Resolution, mode, pulses setting, on/off)

J ###

j

현재 PWM 값 읽기

j

  • J ###\r\n Command

- J ###\r\n에서 ### 은 Bit [7:0] 까지 설정한 값이 들어감

  • 센서 자기 진단 테스트

CommandDescriptionResponse

i

센서 자가 진단 테스트

i ###

Response: ### = 170 - Sensor error

### = 85 - no Sensor error

2. 특징

  • 최첨단 Solid-State LED 광학 기술 이용한 초 저전력 NDIR CO2 센서

  • 디지털(UART) 및 I2C 출력

  • 높은 CO2 측정 정확도

  • 내장형 자동 영점 조정

  • 30 ppm(일반) 정확도

3. 애플리케이션

  • 난방, 환기 및 공기 조절(HVAC)

  • 건물 관리 시스템(BMS)

  • 환기 조절 시스템(DCV)

  • 차량 내 공기 질

  • 무선 장비를 이용한 IoT 및 Smart Technology

  • 실내 공기 질(IAQ)

  • 계측

  • 농업

  • 항공우주

4. 사양

항목내용

측정 범위

CozIR-LP3-2000: 0-2000ppm CozIR-LP3-5000: 0-5000ppm CozIR-LP3-1: 0-10,000ppm (1%)

센서 내부

Solid-State, 가열된 필라멘트 없음

통신 방식

UART 또는 I²C

전원 전압

3.25-5.5V

소모 전류

측정 모드: 15mA 절전 모드: 0.01mA

응답 시간

30.5ms

동작 온도

0~50℃

센서 치수 및 무게

L x W x H(31mm x 19.5mm x 8.7mm), Weight(2.5g)

센서 내구성

진동 및 충격에 강하고 비가열성

센서 교정

자동 영점교정 기능 내장

센서 수명

15년

헤더 핀 크기

2.54mm

5. 제품 크기 및 핀 특성

PINNAMEFunction

1

GND

VSS

2

VDD

Positive Supply

5

ALARM

ALARM Output

7

PWM_RS485

PWM or RS485 transceiver

8

I2C_ENABLE

Digital Input

9

I2C_SCL

I2C clock

10

I2C_SDA

I2C data

11

Tx_out

Digital Input

12

Rx_ In

Digital Output

6. 디바이스 연결 방법

Connection DIAGRAM (UART)

Connection DIAGRAM (I2C)

7. 통신 프로토콜

  • 통신 환경

PARAMETERTYPUNIT

Buad Rate

9600

Bits/s

Data Bits

8

Parity

None

Stop Bits

1

Hardware Flow Control

None

  • UART Command

CommandDescriptionResponse

K 0

Command를 기다리는 상태, 측정 X

K 00000

K 1

연속적으로 값을 측정

K 00001

K 2

센서 값 요청시에만 응답

K 00002

Z

가장 최근에 측정한 CO2 필터 된 값

Z 00521

z

가장 최근에 측정한 CO2 필터 되지 않은 값

z 00521

A ###

CO2 필터 값 설정

A 00016

a

CO2 필터 값 확인

a 00016

U

질소를 사용하여 제로 교정

U 33000

u

초기 설정 값으로 제로 교정

u

G

Fresh Air를 사용하여 제로 교정

G 33000

X #####

현재 값으로 스팬 교정

X 11000

P 10###

P 11###

Fresh Air에서 사용할 대기 중 농도를 설정(default 400ppm)

Fresh Air에서 사용할 대기 중 농도를 설정(default 400ppm)

S ###

고도 설정

S 08192

s

고도 설정 값 확인

s 08192

M ###

측정 데이터 문자열로 전송

M 6

모드 설정 및 CO2 값 읽기

모드

1. COMMAND 모드

- COMMAND를 기다리는 상태, 측정 X

2. Streaming 모드(default)

- 연속적으로 값을 측정함(초당 2회 측정), 측정 외 다른 Command시 100ms delay가 필요함

3. Polling 모드

- 센서 값 요청 시에만 응답, 센서 값 요청하지 않을 때에는 백그라운드에서 계속 측정을 수행함

ModeCommandDescriptionResponse

Command

K 0

명령어 기다리는 상태

K 00000

Streaming

K 1

연속적으로 값 측정

K 00001

Polling

K 2

센서 값 요청 시 에만 응답

K 00002

소스 코드

  • Streaming mode에서 CO2 값 읽기

#include <SoftwareSerial.h>
SoftwareSerial mySerial(12, 13); //Uno Rx Tx (12 13) = SoftwareSerial
const char* Polling_mode = "K 2\r\n";
const char* Stream_mode = "K 1\r\n";
const char* Standby_mode = "K 0\r\n";  
bool tx_ready;
bool rx_ready; 
String str;
void setup() {
  Serial.begin(9600); //시리얼 통신 초기화
  mySerial.begin(9600); 
  while(!mySerial){} //시리얼 통신 포트가 연결되기 전까지 대기
  delay(14); // power on data ready
  mySerial.print(Stream_mode); //Polling 모드로 변경
  mySerial.print("Z\r\n");  //CO2값 읽기 명령
}                              
 
void loop() 
{
 if(rx_ready == 0) // overflow 처리
 {
   delay(31); // Measurement data ready
   if(mySerial.available()>0) //수신받은 데이터가 0 초과, 즉 데이터가 존재한다면
   { //버퍼에서 읽어드린 char의 데이터를 String 형태로 반환
    str = "";
    str = mySerial.readStringUntil('\n'); 
    Serial.println(str);
    rx_ready = 1;   
    tx_ready = 1;
   }
 }
 else if(tx_ready == 1)
  {
     mySerial.print("Z\r\n"); //CO2값 읽기 명령
     tx_ready = 0;
     rx_ready = 0;
  }
}

+시리얼 모니터

  • Polling mode에서 CO2값 읽기

#include <SoftwareSerial.h>
SoftwareSerial mySerial(12, 13); //Uno Rx Tx (12 13) = SoftwareSerial
const char* Polling_mode = "K 2\r\n";
const char* Stream_mode = "K 1\r\n";
const char* Standby_mode = "K 0\r\n";   
String str;
void setup() {
  Serial.begin(9600); //시리얼 통신 초기화
  mySerial.begin(9600); 
  while(!mySerial){} //시리얼 통신 포트가 연결되기 전까지 대기
  delay(14); // power on data ready
  mySerial.print(Polling_mode); //Polling 모드로 변경
}                              
 
void loop() 
{
 if(Serial.read() == 'R') 
 {
  mySerial.print("Z\r\n"); //CO2값 읽기 명령
 }
  if(mySerial.available()>0) //수신받은 데이터가 0 초과, 즉 데이터가 존재한다면
   { //버퍼에서 읽어드린 char의 데이터를 String 형태로 반환
    str = "";
    str = mySerial.readStringUntil('\n'); 
    Serial.println(str);
   }
}
  • 시리얼 모니터

  • 시리얼 모니터에 'R' 입력 후 엔터

  • 응답

인터페이스 유형별(UART,I2C) CO2값 읽기

  • I2C

#include <Wire.h>
#define Slave_adddress 0x41
#define CO2_READ_command 0x34
#define CO2_READ_and_test_command 0x02

void setup() {
  Wire.begin();
  Serial.begin(9600);   
}
void loop() {    
int CO2_value = 0;
 Wire.beginTransmission(Slave_adddress); // transmit to slave address
 Wire.write(CO2_READ_and_test_command);  // transmit to register address
 Wire.endTransmission();    // stop transmitting
 Wire.requestFrom(Slave_adddress, 3); //from slave request 2byte  
  while ( Wire.available()) {
    int CO2_high_value = Wire.read();
    int CO2_low_value = Wire.read();
   /* CO2_Self_test value = 85(DEC) : Sensor is nominal , 
   CO2_Self_test value = 170(DEC): Sensor error */
    int CO2_self_test = Wire.read(); 
    CO2_high_value = CO2_high_value <<8;
    CO2_value = CO2_high_value + CO2_low_value;
    Serial.print("CO2_value : ");
    Serial.print(CO2_value);   //reading CO2 value  
    Serial.println(" PPM ");
  }   
  delay(1000);
}
  • UART

#include <SoftwareSerial.h>
SoftwareSerial mySerial(12, 13); //Uno Rx Tx (12 13) = SoftwareSerial
const char* Polling_mode = "K 2\r\n";
const char* Stream_mode = "K 1\r\n";
const char* Standby_mode = "K 0\r\n";  
bool tx_ready;
bool rx_ready; 
String str;
void setup() {
  Serial.begin(9600); //시리얼 통신 초기화
  mySerial.begin(9600); 
  while(!mySerial){} //시리얼 통신 포트가 연결되기 전까지 대기
  delay(14); // power on data ready
  mySerial.print(Stream_mode); //Polling 모드로 변경
  mySerial.print("Z\r\n");  //CO2값 읽기 명령
}                              
 
void loop() 
{
 if(rx_ready == 0) // overflow 처리
 {
   delay(31); // Measurement data ready
   if(mySerial.available()>0) //수신받은 데이터가 0 초과, 즉 데이터가 존재한다면
   { //버퍼에서 읽어드린 char의 데이터를 String 형태로 반환
    str = "";
    str = mySerial.readStringUntil('\n'); 
    Serial.println(str);
    rx_ready = 1;   
    tx_ready = 1;
   }
 }
 else if(tx_ready == 1)
  {
     mySerial.print("Z\r\n"); //CO2값 읽기 명령
     tx_ready = 0;
     rx_ready = 0;
  }
}

Serial Monitor

  • I2C

  • UART

Digital filter

  • 필터(Filtered)된 값과 필터 되지 않은(Unfiltered) CO2 값의 차이는 아래 그림과 같음

  • 필터된(Filtered) CO2 값은 노이즈를 제거하여 더 정확한 값을 제공함

Digital filter 설정

  • 필터 설정 범위: 1~255( 1= Unfiltered)

  • 필터의 설정 값이 증가하면 측정 출력 응답 시간이 늘어남

  • A=필터 설정 값

  • A = 32 가 A = 16(default) 보다 T90에 도달하는 시간이 늘어남

Digital filter Command

CommandDescriptionExampleResponse

A ###

CO2 필터 값 설정

A 16

A 00016

a

CO2 필터 값 확인

a

a 00016

소스코드

  • CO2 필터 값 확인

#include <SoftwareSerial.h>
SoftwareSerial mySerial(12, 13); //Uno Rx Tx (12 13) = SoftwareSerial
const char* Polling_mode = "K 2\r\n";
const char* Stream_mode = "K 1\r\n";
const char* Standby_mode = "K 0\r\n";  
bool tx_ready;
bool rx_ready; 
String str;
void setup() {
  Serial.begin(9600); //시리얼 통신 초기화
  mySerial.begin(9600); 
  while(!mySerial){} //시리얼 통신 포트가 연결되기 전까지 대기
  delay(14); // power on data ready
  mySerial.print(Stream_mode); //Polling 모드로 변경
}                              
 
void loop() 
{
 if(rx_ready == 0) // overflow 처리
 {
   delay(31); // Measurement data ready
   if(mySerial.available()>0) //수신받은 데이터가 0 초과, 즉 데이터가 존재한다면
   { //버퍼에서 읽어드린 char의 데이터를 String 형태로 반환
    str = "";
    str = mySerial.readStringUntil('\n'); 
    Serial.println(str);
    rx_ready = 1;   
    tx_ready = 1;
   }
 }
 else if(tx_ready == 1)
  {
     mySerial.print("a\r\n"); //현재 설정된 필터 값 읽기 명령어
     tx_ready = 0;
     rx_ready = 0;
  }
}++
  • 시리얼 모니터

  • CO2 필터 값 설정

#include <SoftwareSerial.h>
SoftwareSerial mySerial(12, 13); //Uno Rx Tx (12 13) = SoftwareSerial
const char* Polling_mode = "K 2\r\n";
const char* Stream_mode = "K 1\r\n";
const char* Standby_mode = "K 0\r\n";  
bool tx_ready;
bool rx_ready; 
String str;
void setup() {
  Serial.begin(9600); //시리얼 통신 초기화
  mySerial.begin(9600); 
  while(!mySerial){} //시리얼 통신 포트가 연결되기 전까지 대기
  delay(14); // power on data ready
  mySerial.print(Stream_mode); //Polling 모드로 변경
}                              
 
void loop() 
{
 if(rx_ready == 0) // overflow 처리
 {
   delay(31); // Measurement data ready
   if(mySerial.available()>0) //수신받은 데이터가 0 초과, 즉 데이터가 존재한다면
   { //버퍼에서 읽어드린 char의 데이터를 String 형태로 반환
    str = "";
    str = mySerial.readStringUntil('\n'); 
    Serial.println(str);
    rx_ready = 1;   
    tx_ready = 1;
   }
 }
 else if(tx_ready == 1)
  {
     mySerial.print("A 32\r\n"); //필터 값 변경 명령어 
     tx_ready = 0;
     rx_ready = 0;
  }
}
  • 시리얼 모니터

Last updated