2023. 1. 10. 15:06ㆍ개발/Arduino
그동안 성능지표 테스트를 준비했다.
중소벤처기업부 에서 진행하는 과제에 선정돼서
연구비를 받아 진행하는데
그 과정에서 어떤 식으로 기술을 연구/개발 하는지
지표에 맞게 테스트를 진행한다.
위와 같이 5가지 항목이 있다.
각 항목별로 어떤 식으로 진행할지 검토하고
서류를 작성한다.
이런 식으로 서류를 작성했다.
아무튼 전반적인 준비 과정을 기록한다.
모든 센서 데이터는 local Node-red 에서
MQTT 통신으로 수신받는다.
2023.01.04 - [기록/개발 노트] - 성능지표 및 Arduino 함수 트리거 처리
성능지표 및 Arduino 함수 트리거 처리
https://www.mss.go.kr/site/smba/main.do 중소벤처기업부 중소기업중앙회 등 기관 중소기업 조사, 통계 DB화 검색, 내려받기 등 제공. www.mss.go.kr 중소벤처기업부 에서 매년 'R&D 역량제고사업 맞춤형기술파
iruk.tistory.com
이전에 레이다 센서에 관한 내용을 기록했었다.
레이다 센서 말고도 3가지 센서를 추가했다.
1. 암모니아 센서
#include <ESP8266WiFi.h>
#include <WiFiClient.h>
#include <PubSubClient.h>
#include <ArduinoJson.h>
const char* ssid = ""; // 와이파이 AP, 또는 스마트폰의 핫스판 이름
const char* password = ""; // 와이파이 AP, 또는 스마트폰의 핫스판 이름
const char* mqtt_server = ""; //브로커 주소
const char* outTopic = ""; // 이름이 중복되지 않게 설정 기록
const char* inTopic = ""; // 이름이 중복되지 않게 설정 기록
const char* clientName = ""; // setup 함수에서 자동생성
WiFiClient espClient;
PubSubClient client(espClient);
long lastMsg = 0;
char msg[50];
//json을 위한 설정
StaticJsonDocument<200> doc;
DeserializationError error;
JsonObject root;
int Vpin = A0;
int Vvalue = 0;
String sMac="";
char mac[20];
unsigned long previousMillis = 0;
const long interval = 1800000;
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 setup() {
Serial.begin(9600);
setup_wifi();
//이름 자동으로 생성
Serial.print("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(mac);
client.setServer(mqtt_server, 1883);
client.setCallback(callback);
}
void loop() {
doTick();
if (!client.connected()) {
reconnect();
}
client.loop();
}
void doTick() {
unsigned long currentMillis = millis();
if (currentMillis - previousMillis >= interval) {
previousMillis = currentMillis;
sensor();
}
}
void sensor() {
Vvalue = analogRead(Vpin);
Serial.println(Vvalue);
doc["mac"] = sMac;
doc["amonia"] = Vvalue;
char jsonBuffer[512];
serializeJson(doc, jsonBuffer);
client.publish(outTopic, jsonBuffer);
}
2. 미세먼지 센서
//1-16-3 https://youtu.be/6rfDrpsOGMY 를 기초로 작업
#include <WiFi.h>
#include <PubSubClient.h>
#include <ArduinoJson.h>
#include "PMS.h"
// 아래의 6개설정은 사용자 환경에 맞게 수정하세요.
const char* ssid = ""; // 와이파이 AP, 또는 스마트폰의 핫스판 이름
const char* password = ""; // 와이파이 AP, 또는 스마트폰의 핫스판 이름
const char* mqtt_server = ""; //브로커 주소
const char* outTopic = ""; // 이름이 중복되지 않게 설정 기록
const char* inTopic = ""; // 이름이 중복되지 않게 설정 기록
const char* clientName = ""; // setup 함수에서 자동생성
WiFiClient espClient;
PubSubClient client(espClient);
long lastMsg = 0;
char msg[50];
//json을 위한 설정
StaticJsonDocument<200> doc;
DeserializationError error;
JsonObject root;
//PMS5003 센서를 위한 변수
PMS pms(Serial2);
PMS::DATA data;
int dustValue;
String sMac="";
char mac[20];
unsigned long previousMillis = 0;
const long interval = 1800000;
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>();
//red = root["r"];
}
// 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 setup() {
Serial.begin(9600);
Serial2.begin(9600);
setup_wifi();
//이름 자동으로 생성
Serial.print("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(mac);
client.setServer(mqtt_server, 1883);
client.setCallback(callback);
}
void loop() {
if (pms.read(data)){
doTick();
}
if (!client.connected()) {
reconnect();
}
client.loop();
}
void doTick() {
unsigned long currentMillis = millis();
if (currentMillis - previousMillis >= interval) {
previousMillis = currentMillis;
sensor(); // 오존 센서
}
}
void sensor() {
dustValue=data.PM_AE_UG_2_5;
Serial.print("PM 2.5 (ug/m3): ");
Serial.println(dustValue);
doc["mac"] = sMac;
doc["dust"] = dustValue;
char jsonBuffer[512];
serializeJson(doc, jsonBuffer);
client.publish(outTopic, jsonBuffer);
}
3. 레이다 센서
#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 = ""; //브로커 주소
const char* outTopic = ""; // 이름이 중복되지 않게 설정 기록
const char* 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 sensor,preSensor,counter;
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(){
sensor = digitalRead(RCWL);
if(preSensor==0 && sensor==1){ // 새로운 감지 발생 시
if(counter==0){
digitalWrite(D7,HIGH); // 릴레이 on
Serial.println("detected! relay On ");
counter++;
StaticJsonDocument<200> doc;
doc["mac"] = sMac;
doc["detect"] = "on";
char jsonBuffer[512];
serializeJson(doc, jsonBuffer); // print to client
Serial.println(jsonBuffer);
client.publish(outTopic, jsonBuffer);
}
else if(counter==1){
digitalWrite(D7,LOW); // 릴레이 off
Serial.println("detected! relay Off ");
counter=0;
StaticJsonDocument<200> doc;
doc["mac"] = sMac;
doc["detect"] = "off";
char jsonBuffer[512];
serializeJson(doc, jsonBuffer); // print to client
Serial.println(jsonBuffer);
client.publish(outTopic, jsonBuffer);
}
}
else{
Serial.println("waiting...");
}
preSensor=sensor;
}
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();
}
4. 오존 센서
#include <ESP8266WiFi.h>
#include <WiFiClient.h>
#include <PubSubClient.h>
#include <ArduinoJson.h>
#include <MQ131.h>
#define mq131 A0 // 오존감지
// 아래의 6개설정은 사용자 환경에 맞게 수정하세요.
const char* ssid = ""; // 와이파이 AP, 또는 스마트폰의 핫스판 이름
const char* password = ""; // 와이파이 AP, 또는 스마트폰의 핫스판 이름
const char* mqtt_server = ""; //브로커 주소
const char* outTopic = ""; // 이름이 중복되지 않게 설정 기록
const char* 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="";
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;
sensor(); // 오존 센서
}
}
void sensor() {
Serial.println("Sampling...");
MQ131.sample();
float o3value = MQ131.getO3(PPM);
reconnect(); // sampling 하는동안 MQTT 종료됨
StaticJsonDocument<200> doc;
doc["mac"] = sMac;
doc["o3"] = o3value;
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();
Serial.println("Wait for calibration...");
MQ131.begin(2,A0, LOW_CONCENTRATION, 1000000);
MQ131.calibrate();
Serial.println("calibration done");
client.setServer(mqtt_server, 1883);
client.setCallback(callback);
}
void loop() {
doTick();
if (!client.connected()) {
reconnect();
}
client.loop();
}
소스는 위와 같다.
전부 다 같은 MQTT 서버, 같은 MQTT 토픽에 데이터를 전송한다.
var time = new Date().toLocaleString('ko-KR',
{ timeZone: 'Asia/Seoul' });
var ammonia = msg.payload.amonia;
var newMsg = {};
newMsg.collection = '1_ammoniaSensor';
newMsg.operation = 'insert';
newMsg.payload = { 'mac':msg.payload.mac, 'ammonia': ammonia, 'time': time };
newMsg.projection = { 'start': 1, '_id': 0 };
return newMsg;
그 뒤 Node-red 에서
데이터를 mongoDB 에 저장한다.
센서별로 1, 2, 3, 4 숫자를 collection에서 구분해
보기에 편하도록 했다.
위와 같이 mongoDB 에서
편하게 볼 수 있도록 설정했다.
근데 문제는
성능지표를 보면
암모니아, 미세먼지 센서는
3일간 측정해야한다.
현재는 CPU와 센서를
노트북에 USB로 연결해서 전원을 해결했는데
3일간 하루종일 구동하려면
외부 전원이 필요하다
그래서 위 사진처럼
콘센트에 전원을 연결해서
연구실에 3일동안 켜 놓을 생각이다.
그리고 현재 1초마다 센서값을 받아오도록 했는데
30분마다 한 번씩 받아오도록 소스를 수정했다.
//const long interval = 1000;
const long interval = 1800000;
위와 같이 interval 변수를 수정했다.
또한, Node-red 도 local환경이기 때문에
노트북이 꺼지면 돌아가지 않는다.
따라서 AWS Instance 가상서버를 사용해
24시간 서버를 돌리고
그 안에 설치된 Node-red와 mongoDB에서
프로그램이 돌아가도록 했다.
그리고 성능지표 항목 중에서
세번째, IoT 제어 통신응답 정확성은
위와 같이 Node-red에서 웹사이트를 구성해 테스트했다.
위 보드에 전원이 입력되면
자동으로 AWS 서버와 연결돼
MQTT로 정보를 송신하고
웹에 버튼이 자동생성되며
실시간으로 웹과 연동된다.
성능지표 테스트 준비 끝
'개발 > 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 |
성능지표 및 Arduino 함수 트리거 처리 (2) | 2023.01.04 |