2023. 1. 4. 15:00ㆍ개발/Arduino
https://www.mss.go.kr/site/smba/main.do
중소벤처기업부 에서 매년
'R&D 역량제고사업 맞춤형기술파트너' 를 실시한다.
현재 PTC 난방기 프로젝트가 작년 6월에 해당 정책에 선정되어서
국가의 지원을 받아 진행 중인 상태다.
매달 연구를 진행하면서
연구노트를 작성하고
그에 맞는 견적서, 명세표 및
각종 서류들을 심사 받는다.
그 중에서도 '성능지표' 항목에 대해
오늘 테스트를 해보았다.
실제 그 제품이 어떤 기술적 가치를 갖는지
그 기술적 가치에 합당하는
성능 테스트를 심사 받는 개념이다.
성능지표
5개의 항목을 작성했었다.
1,2 번은 3일간 평균값을 측정해야 하는데
공간의 제약이 있어 다음주 월요일에 진행하기로 했다.
3번은 준비를 마친 상태고
4번 및 5번을 테스트 하려고 한다.
검은색 제품은 '플라즈마 발생기'
간단하게 제작되어 있는 보드에는
'MQ131 오존 감지 센서' 및
'RCWL-0516 레이다 모션 센서' 가 있다.
뭉툭하게 튀어나온 센서가 MQ 131이다.
#include <ESP8266WiFi.h>
#include <WiFiClient.h>
#include <PubSubClient.h>
#include <ArduinoJson.h>
#include <MQ131.h>
#define RCWL D6 //레이다
#define mq131 A0 // 오존감지
// 아래의 6개설정은 사용자 환경에 맞게 수정하세요.
const char* ssid = " "; // 와이파이 AP, 또는 스마트폰의 핫스판 이름
const char* password = " "; // 와이파이 AP, 또는 스마트폰의 핫스판 이름
const char* mqtt_server = "broker.mqtt-dashboard.com"; //브로커 주소
const char* outTopic = "/khj/outTopic"; // 이름이 중복되지 않게 설정 기록
const char* inTopic = "/khj/inTopic"; // 이름이 중복되지 않게 설정 기록
const char* clientName = ""; // setup 함수에서 자동생성
WiFiClient espClient;
PubSubClient client(espClient);
long lastMsg = 0;
char msg[50];
//json을 위한 설정
StaticJsonDocument<200> doc;
DeserializationError error;
JsonObject root;
char mac[20];
String sMac="";
String inputString;
float o3value;
int tect;
unsigned long previousMillis = 0;
const long interval = 1000;
void setup_wifi() {
// We start by connecting to a WiFi network
Serial.println();
Serial.print("Connecting to ");
Serial.println(ssid);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("");
Serial.println("WiFi connected");
Serial.println("IP address: ");
Serial.println(WiFi.localIP());
}
// 통신에서 문자가 들어오면 이 함수의 payload 배열에 저장된다.
void callback(char* topic, byte* payload, unsigned int length) {
Serial.print("Message arrived [");
Serial.print(topic);
Serial.print("] ");
for (int i = 0; i < length; i++) {
Serial.print((char)payload[i]);
}
Serial.println();
deserializeJson(doc,payload);
root = doc.as<JsonObject>();
}
// mqtt 통신에 지속적으로 접속한다.
void reconnect() {
// Loop until we're reconnected
while (!client.connected()) {
Serial.print("Attempting MQTT connection...");
// Attempt to connect
if (client.connect(clientName)) {
Serial.println("connected");
// Once connected, publish an announcement...
client.publish(outTopic, "Reconnected");
// ... and resubscribe
client.subscribe(inTopic);
} else {
Serial.print("failed, rc=");
Serial.print(client.state());
Serial.println(" try again in 5 seconds");
// Wait 5 seconds before retrying
delay(5000);
}
}
}
void doTick() {
unsigned long currentMillis = millis();
if (currentMillis - previousMillis >= interval) {
previousMillis = currentMillis;
detect(); // 레이다 센서
DoResult(); // 오존 센서
}
}
void detect(){
tect = digitalRead(RCWL);
if(tect>0){
digitalWrite(D7,LOW);
}
else if(tect == 0){
digitalWrite(D7,HIGH);
}
}
void DoResult() {
Serial.println("Sampling...");
MQ131.sample();
float o3value = MQ131.getO3(PPM);
StaticJsonDocument<200> doc;
doc["o3"] = o3value;
doc["detact"] = tect;
char jsonBuffer[512];
serializeJson(doc, jsonBuffer); // print to client
Serial.println(jsonBuffer);
client.publish(outTopic, jsonBuffer);
}
void setup() {
Serial.begin(115200);
Serial.println("mac address");
uint8_t macH[6]="";
WiFi.macAddress(macH);
sprintf(mac,"%02x%02x%02x%02x%02x%02x%c",macH[0], macH[1], macH[2], macH[3], macH[4], macH[5],0);
sMac=mac;
clientName=mac;
Serial.println(clientName);
setup_wifi();
MQ131.begin(2,A0, LOW_CONCENTRATION, 1000000);
MQ131.calibrate();
pinMode(RCWL,INPUT);
pinMode(D7, OUTPUT);
client.setServer(mqtt_server, 1883);
client.setCallback(callback);
digitalWrite(D7,0);
}
void loop() {
doTick();
if (!client.connected()) {
reconnect();
}
client.loop();
}
위 소스코드를 사용해서 테스트해보았다.
void detect(){
tect = digitalRead(RCWL);
if(tect>0){
digitalWrite(D7,LOW);
}
else if(tect == 0){
digitalWrite(D7,HIGH);
}
}
void DoResult() {
Serial.println("Sampling...");
MQ131.sample();
float o3value = MQ131.getO3(PPM);
StaticJsonDocument<200> doc;
doc["o3"] = o3value;
doc["detact"] = tect;
char jsonBuffer[512];
serializeJson(doc, jsonBuffer); // print to client
Serial.println(jsonBuffer);
client.publish(outTopic, jsonBuffer);
}
void loop 문에서 위 두 함수가 반복 실행된다.
detect() 함수는 레이다 모션 센서
DoResult() 는 MQ131 센서 및 MQTT로 데이터를 출력한다.
문제가 하나 발생했는데
MQ131 센서는 Sampling 시간이 필요하다.
공기질을 측정하고 샘플링하는데 시간이 걸리는데
그 주기가 무려 18초다.
즉, detect()함수로 레이다 모션 센서를 먼저 측정해도
결국 18초 동안이나 딜레이가 걸린 상태로
MQ131센서 측정결과를 기다려야 한다.
RCWL-0516 레이다 모션 센서의
저조한 인식률도 문제다.
일단 레이다 모션 센서만 따로
동작 테스트를 해보기로 했다.
RCWL-0516 레이다 모션 센서
소스 코드에서 레이다 관련 소스만 추출했다.
#include <ESP8266WiFi.h>
#include <WiFiClient.h>
#include <PubSubClient.h>
#include <ArduinoJson.h>
#define RCWL D6 //레이다
// 아래의 6개설정은 사용자 환경에 맞게 수정하세요.
const char* ssid = " "; // 와이파이 AP, 또는 스마트폰의 핫스판 이름
const char* password = " "; // 와이파이 AP, 또는 스마트폰의 핫스판 이름
const char* mqtt_server = "broker.mqtt-dashboard.com"; //브로커 주소
const char* outTopic = "/khj/outTopic"; // 이름이 중복되지 않게 설정 기록
const char* inTopic = "/khj/inTopic"; // 이름이 중복되지 않게 설정 기록
const char* clientName = ""; // setup 함수에서 자동생성
WiFiClient espClient;
PubSubClient client(espClient);
long lastMsg = 0;
char msg[50];
//json을 위한 설정
StaticJsonDocument<200> doc;
DeserializationError error;
JsonObject root;
char mac[20];
String sMac="";
String inputString;
int tect;
unsigned long previousMillis = 0;
const long interval = 1000;
void setup_wifi() {
// We start by connecting to a WiFi network
Serial.println();
Serial.print("Connecting to ");
Serial.println(ssid);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("");
Serial.println("WiFi connected");
Serial.println("IP address: ");
Serial.println(WiFi.localIP());
}
// 통신에서 문자가 들어오면 이 함수의 payload 배열에 저장된다.
void callback(char* topic, byte* payload, unsigned int length) {
Serial.print("Message arrived [");
Serial.print(topic);
Serial.print("] ");
for (int i = 0; i < length; i++) {
Serial.print((char)payload[i]);
}
Serial.println();
deserializeJson(doc,payload);
root = doc.as<JsonObject>();
}
// mqtt 통신에 지속적으로 접속한다.
void reconnect() {
// Loop until we're reconnected
while (!client.connected()) {
Serial.print("Attempting MQTT connection...");
// Attempt to connect
if (client.connect(clientName)) {
Serial.println("connected");
// Once connected, publish an announcement...
client.publish(outTopic, "Reconnected");
// ... and resubscribe
client.subscribe(inTopic);
} else {
Serial.print("failed, rc=");
Serial.print(client.state());
Serial.println(" try again in 5 seconds");
// Wait 5 seconds before retrying
delay(5000);
}
}
}
void doTick() {
unsigned long currentMillis = millis();
if (currentMillis - previousMillis >= interval) {
previousMillis = currentMillis;
detect(); // 레이다 센서
}
}
void detect(){
tect = digitalRead(RCWL);
if(tect>0){
digitalWrite(D7,LOW);
}
else if(tect == 0){
digitalWrite(D7,HIGH);
}
StaticJsonDocument<200> doc;
doc["detact"] = tect;
char jsonBuffer[512];
serializeJson(doc, jsonBuffer); // print to client
Serial.println(jsonBuffer);
client.publish(outTopic, jsonBuffer);
}
void setup() {
Serial.begin(115200);
pinMode(RCWL,INPUT);
pinMode(D7, OUTPUT);
digitalWrite(D7,0);
Serial.println("mac address");
uint8_t macH[6]="";
WiFi.macAddress(macH);
sprintf(mac,"%02x%02x%02x%02x%02x%02x%c",macH[0], macH[1], macH[2], macH[3], macH[4], macH[5],0);
sMac=mac;
clientName=mac;
Serial.println(clientName);
setup_wifi();
client.setServer(mqtt_server, 1883);
client.setCallback(callback);
}
void loop() {
doTick();
if (!client.connected()) {
reconnect();
}
client.loop();
}
센서 앞에서 움직임이 있으면 1
평상시에 0 이 출력된다.
모션센서여서 그런지
근섭센서와는 다르게
인식률이 낮은 느낌이다. 바로바로 변하지 않는 느낌
그리고 예를 들어서
위와 같이 레이다 모션 센서 앞을
특정한 물체로 가로막으면
감지가 되며 1이 출력된다.
근데
이 상태로 가만히 두면
몇 초 뒤에 원상태로 돌아간다( 0 출력 ).
그러고 나서
다시 1이 출력된다.
혹시나 하고 물체를 치우고
기본 측정거리가 7m라서
센서가 벽을 바라보도록 했는데
1 0이 왔다갔다 출력된다.
센서가 예민한가..
이 오류는 앞으로 계속 생각해봐야겠다.
성능지표 4번째 항목을 보면
사람이 왔다가 떠나는 경우로 처리했다.
즉
처음 감지됐을 때 1회( 사람이 화장실 사용 ),
한 번 더 감지됐을 때 1회( 사람이 떠남 )
만 전기적 신호를 내보내도록 수정한다.
void detect(){
tect = digitalRead(RCWL);
if(tect>0){
digitalWrite(D7,LOW);
}
else if(tect == 0){
digitalWrite(D7,HIGH);
}
}
기존에는 위와 같이
tect가 0인경우 1인경우
매번 D7핀에 전기신호를 줬는데
이 부분을 조금 수정하려 한다.
소스 수정
void detect(){
sensor = digitalRead(RCWL);
if(preSensor==0 && sensor==1){ // 새로운 감지 발생 시
if(counter==0){
digitalWrite(D7,HIGH); // 릴레이 on
Serial.println("detected! relay On ");
counter++;
}
else if(counter==1){
digitalWrite(D7,LOW); // 릴레이 off
Serial.println("detected! relay Off ");
counter=0;
}
StaticJsonDocument<200> doc;
doc["detect"] = sensor;
char jsonBuffer[512];
serializeJson(doc, jsonBuffer); // print to client
Serial.println(jsonBuffer);
client.publish(outTopic, jsonBuffer);
}
else{
Serial.println("waiting...");
}
preSensor=sensor;
}
레이다 센서 값이 0->1 로 변할 때 만 동작하도록 수정했다.
preSensor 변수를 생성해
이전에 측정된 sensor 값을 저장하고,
그 preSensor 값이 0 이고, 현재 sensor 값이 1일 때
즉, 0->1로 변했을 때만 처리를 하도록 했다.
0에서 1로 변했을 때
함수 안에 if문을 또 추가해서
counter 변수에 따라 동작을 구분했다.
초기에는 counter값이 디폴트 값 0이므로
digitalWrite HIGH 가 실행되고
counter 를 1 증가시킨다. ( counter++ )
다음번에 함수가 실행됐을때는
counter값이 0이 아니라 1이므로
else 문이 실행돼서 digitalWrite LOW가 실행된다.
그리고 counter를 0으로 초기화한다.
코드가 훨씬 깔끔하고 활용도가 높게 수정했다.
'개발 > Arduino' 카테고리의 다른 글
Xiaomi Flower care + ESP32 / BLE통신 (0) | 2023.03.13 |
---|---|
Lora 및 485 통신 (0) | 2023.03.08 |
ESP32 BLE & RS-232 RS-485통신 (0) | 2023.03.02 |
ESP32 web server (0) | 2023.02.28 |
성능지표 테스트 (0) | 2023.01.10 |