이번 포스트에서는 Node.js 환경에서 MQTT를 사용해 센싱 데이터를 주고받는 방법에 대해 제가 실습해본 내용을 바탕으로 소개할 예정입니다.
두개의 visual studio code 프로젝트 MQTT_T1, MQTT_T2를 실행한 뒤,
두 프로젝트에 각각 main.js 파일을 생성합니다.
nodemon은 파일 변경을 감지하면, 자동으로 서버를 재시동하여 수정 사항을 서버에 적용시켜주는 편리한 도구입니다.
npm install nodemon
두 프로젝트 모두 터미널에 위 명령어를 입력하여 nodemon 패키지를 설치해줍니다.
npm install -g nodemon
위 코드로 설치하는게 국룰같은데, 전 새로운 프로젝트들에 대해선 해당 명령어가 먹지 않아서 -g는 제외하였습니다.
nodemon 설치가 완료되었다면 터미널에 다음 명령어를 입력합니다.
npm init -y
그러면 package.json 파일이 프로젝트 폴더 내에 생성되는데,
package.json 파일에 들어가 "scripts"에 다음 코드를 작성합니다.
"server": "nodemon main.js"
npm run server
이처럼 세팅을 해주면, 터미널에 간편하게 위 명령어를 입력하는 것으로 서버를 구동시킬 수 있습니다.
서버 종료를 원할땐 터미널을 선택한 뒤 ctrl + c를 통해 종료할 수 있습니다.
두 프로젝트 모두 기본적으로 서버 세팅이 완료되면, 코드를 작성합니다.
MQTT_T1의 main.js는 센싱 데이터를 수집하여 메시지를 발행하는 역할을 수행합니다.
위 예제에서는 express, http, mqtt, serialport 패키지를 사용하였습니다.
npm install express
npm install http
npm install mqtt
npm install serialport
이후 패키지들을 다음처럼 불러와 사용합니다.
const express = require('express');
const app = express();
const http = require('http');
const server = http.createServer(app);
const mqtt = require('mqtt');
const { SerialPort, ReadlineParser } = require('serialport');
필요에 따라 MQTT 사용을 위해 mosquitto 브로커 설치가 필요할 수 있습니다.
https://pros2.tistory.com/137
위 블로그를 참고하시면 될 것 같습니다.
다음으로, Uno보드와 연결 설정을 위해 SerialPort 객체 생성 및 parser를 연결해줍니다.
var port = new SerialPort({
path : '연결된 우노보드 경로',
baudRate : 9600,
autoOpen : false
});
const parser = port.pipe(new ReadlineParser());
연결된 우노 보드 경로는 아두이노 IDE 에서 포트 경로로 찾을 수 있습니다.
이번 실습은 우노 보드 하나에 sound 센서 2개를 연결하는 방식으로 진행하였습니다.
보드에 센서는 사진과 같이 연결하였습니다.
보드에 업로드한 코드는 아래와 같습니다.
int Sensor1value = 0;
int Sensor2value = 0;
void setup() {
Serial.begin(9600);
}
void loop() {
Sensorread();
delay(1000);
}
void Sensorread(){
Sensor1value = analogRead(0);
Sensor2value = analogRead(1);
Serial.print(Sensor1value);
Serial.print(",");
Serial.print(Sensor2value);
Serial.print(",");
Serial.print(Sensor1value);
Serial.print(",");
Serial.print(Sensor2value);
Serial.print(",");
Serial.print(Sensor1value);
Serial.print(",");
Serial.println(Sensor2value);
}
보드에 위 코드를 업로드시킨 후에 진행하면 됩니다.
아래 코드를 이어서 작성하면 우노 보드를 통해 전달된 센싱 데이터들이 메시지에 담겨 발행되게 됩니다.
port.open(function(error) {
if (error) {
console.log("연결된 포트 없음");
} else {
console.log("시리얼 포트 연결됨");
// MQTT 브로커에 연결합니다.
const client = mqtt.connect('mqtt://test.mosquitto.org');
client.on('connect', function () {
console.log('MQTT 클라이언트 연결됨');
// 센싱 데이터를 MQTT 브로커로 전송
parser.on('data', function (data) {
var datetime = new Date()
var year = datetime.getFullYear();
var month = datetime.getMonth() + 1;
var day = datetime.getDate();
var hours = datetime.getHours();
var minutes = datetime.getMinutes();
var seconds = datetime.getSeconds();
var timestamp = year + '-' + num_2(month) + '-' + num_2(day) + ' ' + num_2(hours) + ':' + num_2(minutes) + ':' + num_2(seconds);
// timestamp를 xxxx년 xx월 xx일 xx시 xx분 xx초 형식으로 변환
function num_2(num) {
return (num < 10 ? '0' : '') + num;
}
var values = data.trim().split(',');
var senddata = {
timestamp: timestamp,
value1: values[0],
value2: values[1],
value3: values[2],
value4: values[3],
value5: values[4],
value6: values[5]
};
// 데이터를 JSON으로 변환하여 'data'로 전송
client.publish('data', JSON.stringify(senddata));
console.log("전송된 데이터:", senddata);
});
});
}
})
작성자가 많이 부족하여 실습에 사용한 코드가 다소 주먹구구식인 점 양해 부탁드립니다.
코드를 작성 완료한 뒤에 MQTT_T1 프로젝트에서 npm run server 명령어를 통해 서버를 작동시키면, 모든 연결이 정상적으로 수행되었다는 전제 하에 센싱 데이터가 메시지로 발행되게 됩니다.
MQTT_T2의 main.js는 MQTT_T1의 main.js에서 발행된 메시지를 구독하고, 이를 출력해주는 단순한 기능을 수행합니다.
구독 기능만 수행하면 되므로, 단순히 mqtt 패키지만 설치합니다.
npm install mqtt
이후 패키지를 다음처럼 불러와 사용합니다.
const mqtt = require("mqtt");
const client = mqtt.connect('mqtt://test.mosquitto.org');
메시지를 구독하여 출력만 하면 되므로, 코드가 매우 간단해집니다.
client.on('connect', function() {
console.log('MQTT 클라이언트 연결됨');
})
client.subscribe('data');
client.on('message', function(topic, message) {
message = JSON.parse(message);
var timestamp = message.timestamp;
var value1 = message.value1;
var value2 = message.value2;
var value3 = message.value3;
var value4 = message.value4;
var value5 = message.value5;
var value6 = message.value6;
console.log("Received : [" + timestamp + ", " + value1 + ", " + value2 + ", " + value3 + ", " + value4 + ", " + value5 + ", " + value6 + "]");
})
마찬가지로 작성자가 많이 부족하여 실습에 사용한 코드가 다소 주먹구구식인 점 양해 부탁드립니다.
코드를 작성 완료한 뒤에 MQTT_T2 프로젝트에서 npm run server 명령어를 통해 서버를 작동시키면, MQTT_T1 프로젝트에서 발행되는 메시지를 받아와 출력하는 기능을 수행하게 됩니다.
영상에서처럼 실시간 센싱 데이터들이 메시지로 발행되고, 이를 구독받아 획득하는 과정이 잘 진행됩니다.
비록 많이 허술한 코드들이지만.. 그냥 이런 방법이 있다는 정도로 참고해주시면 감사하겠습니다.
node.js로 센싱 데이터를 MQTT를 통해 주고 받으실 때 유용하게 사용하셨으면 좋겠습니다.
둥글둥글한 훈수는 언제나 대환영입니다.