| 목차
| 목차| 연결 방법(UART)TB600B, TB600CTB200BUART 설정UART COMMAND| 예제 코드모듈 정보 읽기모듈 정보 읽기 CodeMode 설정가스 센서 값 + 온습도 값 읽기Passive mode 센서값 읽기ActvIe mode에서 센서 값 읽기
디지털 출력(UART)을 지원하는 가스 센서의 구동 방법 및 예제 코드
| 연결 방법(UART)
TB600B, TB600C
TB200B
UART 설정
매개변수 | 설명 |
Buad Rate | 9600 Bits/s |
Data Bits | 8 |
Parity | None |
Stop Bits | 1 |
Hardware Flow Control | None |
UART COMMAND
| 예제 코드
모듈 정보 읽기
- 요청
기능 | Command (HEX) |
모듈 정보 읽기 | D7 |
- 응답
가스 값 응답 데이터의 소수점(자리수) 예제
Ex) 01 ->정수로 표시
Ex) 11 ->가스 값 응답 데이터/10
Ex) 21 ->가스 값 응답 데이터/100
Ex) 31 ->가스 값 응답 데이터/1000
모듈 정보 읽기 Code
#include <SoftwareSerial.h> SoftwareSerial mySerial(12, 13); //Uno Rx Tx (13 12) = mySerial void setup() { Serial.begin(9600); //시리얼 통신 초기화 delay(1000); while(!mySerial){} //시리얼 통신 포트가 연결되기 전까지 대기 mySerial.begin(9600); } void loop() { unsigned char receive_data[9] = { 0x00, }; //모든 수를 양수로 값을 저장(0x00~0xFF) char Modlue_information_request = 0xD7; mySerial.write(Modlue_information_request); //데이터 요청 패킷 송신 delay(500); //0.5초 지연 int packetIndex = 0; //packetIndex 0으로 초기화 while(mySerial.available()>0){ //수신받은 데이터가 0 초과, 즉 데이터가 존재한다면 코드수행 int ch = mySerial.read(); //시리얼 데이터를 정수형 ch에 저장 Serial.print(ch, HEX); //시리얼 모니터에 입력받은 데이터 출력 Serial.print(' '); receive_data[packetIndex] = ch; packetIndex += 1; } // 패킷을 모두 수신 후 체크섬을 이용하여 데이터의 유효성을 체크 if( (packetIndex == 9) && (1 + (0xFF ^ (byte)(receive_data[1] + receive_data[2] + receive_data[3] + receive_data[4] + receive_data[5] + receive_data[6] + receive_data[7]))) == receive_data[8]) { //체크섬=1~7자리 데이터를 더하여 8비트 데이터를 생성하고 각 비트를 반전시키고 끝에 1을 더함 Serial.println(" "); Serial.print(receive_data[2],HEX); // 가스 종류 ex) co = 0x19 ("가스 종류"별 인식 코드 표 참고) Serial.print(" <--- gas type : "); unsigned char gas_type_flag = 0x00; unsigned char gas_type_compare = 0x24; String gas_type = ""; gas_type_flag = gas_type_compare - receive_data[2]; switch (gas_type_flag){ case 13: gas_type = "HCHO+"; break; case 12: gas_type = "VOC"; break; case 11: gas_type = "CO"; break; case 10: gas_type = "CL2"; break; case 9: gas_type = "H2"; break; case 8: gas_type = "H2S"; break; case 7: gas_type = "HCL"; break; case 6: gas_type = "HCN"; break; case 5: gas_type = "HF"; break; case 4: gas_type = "NH3"; break; case 3: gas_type = "NO2"; break; case 2: gas_type = "O2"; break; case 1: gas_type = "O3"; break; case 0: gas_type = "SO2"; break; default: break; } Serial.println(gas_type); // 측정 범위 상위 바이트 Serial.print(receive_data[3],HEX); // 측정 범위 상위 바이트 Serial.print(receive_data[4],HEX); // 측정 범위 하위 바이트 Serial.print(" <--- measurement range : "); Serial.println((receive_data[3]*256) + receive_data[4]); Serial.print(receive_data[5]); // 단위 Serial.print(" <--- unit : "); if(receive_data[5] == 2) Serial.println(" mg/m^3 and ppm "); else if(receive_data[5] == 4) Serial.println(" um/m^3 and ppb "); else if(receive_data[5] == 8) Serial.println(" 10g/m^3 and % "); Serial.print(receive_data[6],HEX); // 자리수, 양/음 Serial.print(" <--- Number of digits : "); char digits_check; digits_check = receive_data[6] >> 4; // HEX 값 십의 자리수(자리수) switch (digits_check) { case 0: Serial.print(" gas value expressed as an integer , "); break; case 1: Serial.print(" gas value/10,"); break; case 2: Serial.print(" gas value/100,"); break; case 3: Serial.print(" gas value/1000,"); break; default: break; } char output_signs; output_signs = receive_data[6] & 0x0f; // HEX 값 일의 자리 수(양/음) if(output_signs == 0) Serial.println(" output signs positive"); else if(output_signs == 1) Serial.println(" output signs negative"); } Serial.println("------------------------------------------------"); delay(1000); }
Mode 설정
- 초기 Mode default 설정: Passive Mode
- 전원 off 후에도 변경된 통신 모드로 저장됨
- Sleep Mode 나올 경우, 모듈 정상동작에 5초 소요 (5초 동안 data x)
Mode | Command (HEX) | Description | Response |
Passive(Q&A) | FF 01 78 40 00 00 00 00 47 | 센서 값 요청시에만 데이터 값 전송 | ㅤ |
Active | FF 01 78 41 00 00 00 00 46 | 연속적으로 데이터 값을 전송 | ㅤ |
Sleep 들어가기 | AF 53 6C 65 65 70 | Sleep mode 들어감 | 4F 4B |
Sleep 나오기 | AF 45 78 69 74 | Sleep mode 나옴 | 4F 4B |
가스 센서 값 + 온습도 값 읽기
- 요청
기 능 | Command (HEX) |
가스+온도+습도 | FF 01 87 00 00 00 00 00 78 |
- 가스 센서 값 + 온습도 값 읽기 응답
온도 습도 예제
0B 24 : 0x0B(11256=2816) + 0x24(36) = 2852 / 100 => 28.52 ℃ (온도)
06 DB : 0x06(6256=1536) + 0xDB(219) = 1755 / 100 => 17.55 %RH (습도)
Passive mode 센서값 읽기
#include <SoftwareSerial.h> SoftwareSerial mySerial(12, 13); //Uno Rx Tx (13 12) = mySerial byte Passive_mode[9] = {0xFF, 0x01, 0x78, 0x41, 0x00, 0x00, 0x00, 0x00, 0x46}; byte Gas_value_request[9] = {0xFF, 0x01, 0x86, 0x00, 0x00, 0x00, 0x00, 0x00, 0x79}; // 가스 값 요청 void setup() { Serial.begin(9600); //시리얼 통신 초기화 delay(1000); while(!mySerial){} //시리얼 통신 포트가 연결되기 전까지 대기 mySerial.begin(9600); mySerial.write(Passive_mode, 9); // mode set delay(100); } void loop() { unsigned char receive_data[9] = { 0x00, }; //모든 수를 양수로 값을 저장(0x00~0xFF) mySerial.write(Gas_value_request, 9); //데이터 요청 패킷 송신 delay(500); int packetIndex = 0; //packetIndex 0으로 초기화 while(mySerial.available()>0){ //수신받은 데이터가 0 초과, 즉 데이터가 존재한다면 코드수행 int ch = mySerial.read(); //시리얼 데이터를 정수형 ch에 저장 receive_data[packetIndex] = ch; Serial.print(ch, HEX); //시리얼 모니터에 입력받은 데이터 출력 Serial.print(' '); packetIndex += 1; } // 패킷을 모두 수신 후 체크섬을 이용하여 데이터의 유효성을 체크 // 응답 ex) FF 86 2C 88 3 E8 27 10 A4, 0x2710 = 10000 /* - 예제에 사용된 센서 TB600C-CO-1000 */ if( (packetIndex == 9) &&(1 + (0xFF ^ (byte)(receive_data[1] + re-ceive_data[2] + receive_data[3] + receive_data[4] + receive_data[5] + receive_data[6] + receive_data[7]))) == receive_data[8]) //체크섬=1~7자리 데이터를 더하여 8비트 데이터를 생성하고 각 비트를 반전시키고 끝에 1을 더함 { Serial.println(" "); Serial.print(receive_data[6],HEX); Serial.println(" <--- CO High byte "); Serial.print(receive_data[7],HEX); Serial.println(" <--- CO Low byte "); float CO_value = ((receive_data[6] * 256) + receive_data[7]); CO_value = CO_value/10; // /10은 센서의 종류나 측정범위에 따라 달라질 수 있으니 모듈 정보 읽기에서 자리수 확인 하는 것을 권장 Serial.print("CO : "); Serial.print(CO_value); Serial.println("ppm"); // 단위는 모듈 정보 읽기 (0xD7) 커맨드로 확인 할 수 있음 Serial.println("------------------------------------------------"); delay(500); } }
ActvIe mode에서 센서 값 읽기
#include <SoftwareSerial.h> SoftwareSerial mySerial(12, 13); //Uno Rx Tx (13 12) = mySerial byte Active_mode[9] = {0xFF, 0x01, 0x78, 0x40, 0x00, 0x00, 0x00, 0x00, 0x47}; void setup() { Serial.begin(9600); //시리얼 통신 초기화 delay(1000); while(!mySerial){} //시리얼 통신 포트가 연결되기 전까지 대기 mySerial.begin(9600); mySerial.write(Active_mode, 9); // mode set delay(100); } void loop() { unsigned char receive_data[9] = { 0x00, }; //모든 수를 양수로 값을 저장(0x00~0xFF) int packetIndex = 0; //packetIndex 0으로 초기화 while(mySerial.available()>0){ //수신받은 데이터가 0 초과, 즉 데이터가 존재한다면 코드수행 int ch = mySerial.read(); //시리얼 데이터를 정수형 ch에 저장 receive_data[packetIndex] = ch; Serial.print(ch, HEX); //시리얼 모니터에 입력받은 데이터 출력 Serial.print(' '); packetIndex += 1; } // 패킷을 모두 수신 후 체크섬을 이용하여 데이터의 유효성을 체크 // 응답 ex) FF 86 2C 88 3 E8 27 10 A4, 0x2710 = 10000 /* - 예제에 사용된 센서 TB600C-CO-1000 */ if( (packetIndex == 9) &&(1 + (0xFF ^ (byte)(receive_data[1] + re-ceive_data[2] + receive_data[3] + receive_data[4] + receive_data[5] + receive_data[6] + receive_data[7]))) == receive_data[8]) //체크섬=1~7자리 데이터를 더하여 8비트 데이터를 생성하고 각 비트를 반전시키고 끝에 1을 더함 { Serial.println(" "); Serial.print(receive_data[6],HEX); Serial.println(" <--- CO High byte "); Serial.print(receive_data[7],HEX); Serial.println(" <--- CO Low byte "); float CO_value = ((receive_data[6] * 256) + receive_data[7]); CO_value = CO_value/10; // /10은 센서의 종류나 측정범위에 따라 달라질 수 있으니 모듈 정보 읽기에서 자리수 확인 하는 것을 권장 Serial.print("CO : "); Serial.print(CO_value); Serial.println("ppm"); // 단위는 모듈 정보 읽기 (0xD7) 커맨드로 확인 할 수 있음 Serial.println("------------------------------------------------"); delay(500); } delay(500); }
Share article