GSS CO2 Sensor 예제 코드

GSS CO2 가스 센서의 연결 방법 및 예제 코드
Feb 22, 2024
GSS CO2 Sensor 예제 코드

| 연결 방법

PIN
기능
Rx_ In
Digital Input
Tx_out
Digital Output
I2C_ENABLE
Digital Input
I2C_SCL
I2C clock
I2C_SDA
I2C data

아두이노 우노: UART

notion image

아두이노 우노: I2C

notion image

UART 설정

매개변수
설명
Buad Rate
9600 Bits/s
Data Bits
8
Parity
None
Stop Bits
1
Hardware Flow Control
None

UART COMMAND

명령어
설명
K 0
Command를 기다리는 상태, 측정
K 1
연속적으로 값을 측정
K 2
센서 값 요청시에만 응답
Z
가장 최근에 측정한 CO2 필터 된 값
z
가장 최근에 측정한 CO2 필터 되지 않은 값
A ###
CO2 필터 값 설정
a
CO2 필터 값 확인
U
질소를 사용하여 제로 교정
u
초기 설정 값으로 제로 교정
G
Fresh Air를 사용하여 제로 교정
X #####
현재 값으로 스팬 교정
P 10###
Fresh Air에서 사용할 대기 중 농도를 설정 (기본값 400ppm)
P 11###
Fresh Air에서 사용할 대기 중 농도를 설정 (기본값 400ppm)
S ###
고도 설정
s
고도 설정 값 확인
M ###
측정 데이터 문자열로 전송

| 예제 코드

모드 설정

  • COMMAND 모드
    • COMMAND를 기다리는 상태, 측정 X
  • Streaming 모드(default)
    • 연속적으로 값을 측정함(초당 2회 측정), 측정 외 다른 Command시 100ms delay가 필요함
  • Polling 모드
    • 센서 값 요청 시에만 응답, 센서 값 요청하지 않을 때에는 백그라운드에서 계속 측정을 수행함
모드 명령어
설명
K 0
명령어 기다리는 상태, 측정
K 1
연속적으로 값 측정
K 2
센서 값 요청 시에만 응답

UART 통신 센서 값 읽기

notion image

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; } }
notion image

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); } }
notion image
notion image
 

I2C 통신 센서 값 읽기

notion image
#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); }
notion image
 

디지털 필터(Digital filter)

💡
필터(Filtered)된 값과 필터 되지 않은(Unfiltered) CO2 값의 차이는 아래 그림과 같음
필터(Filtered)된 CO2 값은 노이즈를 제거하여 더 정확한 값을 제공함
 
notion image
Digital filter 설정
  • 필터 설정 범위: 1~255( 1= Unfiltered)
  • 필터의 설정 값이 증가하면 측정 출력 응답 시간이 늘어남
notion image
  • A=필터 설정 값
  • A = 32 가 A = 16(default) 보다 T90에 도달하는 시간이 늘어남
 
Digital filter Command
명령어
설명
A ###
CO2 필터 값 설정 (예: A 16)
a
CO2 필터 값 확인
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; } }
notion image
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; } }
notion image
Share article

Allsensing Blog