top of page

ESP32 보드와 Machbase Neo를 이용한 IoT 구현

최종 수정일: 7월 19일

개요


센서를 이용하여 IoT 데이터를 수집하는 방법은 다양합니다.

기존에는 Raspberry PI 등의 SBC를 이용하여, SBC에 센서를 부탁하고 센서에서 수집된 데이터를 바로 SBC에 설치한 데이터베이스나 저장공간에 저장하는 방법을 이용했는데, 이 방법은 SBC의 IO 핀의 수가 제한되어 있고 센서와 SBC간에 유선 연결이 필요하여 다양한 장소에 센서를 설치하려면 배선이나 연결에 많은 고려가 필요합니다.


라즈베리파이가 물가상승과 고성능화로 인해서 점점 더 가격이 올라가고 있는 점도 무시할 수 없는 문제입니다.

이러한 환경에서 간단히 마이크로 컨트롤러와 센서를 결합하고 WIFI망에서 MQTT프로토콜을 이용하여 데이터를 전송하는 스마트 센서를 만들고, 이 센서를 원하는 곳에 설치하면 다양한 장소에 많은 센서를 설치하는데 비용을 절약할 수 있습니다. 이 문서에서 다룬 ESP32 마이크로컨트롤러 보드와 센서 가격은 라즈베리 파이 최신 버전의 1/10 이하의 가격입니다.


ESP32 및 센서

ESP32는 아두이노와 유사한 SBC로 WiFi + Bluetooth 연결을 지원하고 dual core risc cpu와 내장된 메모리, ROM을 가진 보드입니다. 펌웨어를 Arduino IDE를 통해서 개발하여 USB를 통해서 전송하면 그 펌웨어를 이용하여 동작하도록 만들 수 있습니다.


이번 예제에서는 ESP-WROOM32 보드를 이용했습니다. 저렴한 가격으로 쓸만한 스마트 센서를 만들 수 있습니다. 예제에서 이용할 센서는온습도 데이터를 수집하는 DHT-11을 이용했습니다.

이번 예제에서는 ESP-WROOM32 보드를 이용했습니다. 저렴한 가격으로 쓸만한 스마트 센서를 만들 수 있습니다. 예제에서 이용할 센서는온습도 데이터를 수집하는 DHT-11을 이용했습니다.

저전력으로도 작동하기 때문에 휴대폰 외장베터리 등을 이용하여 연결해 두어도 상당히 오랫동안 동작하므로 전원을 연결할 수 없는곳에도 편리하게 설치할 수 있습니다.


결선 및 설정


DHT-11의 케이블을 각기 전원 및 GPIO 핀에 결선해 주었습니다. 이 정도만 설정하면 이제 센서값을 읽어 들일 수 있습니다.

데이터 선을 연결한 GPIO 핀번호는 펌웨어 개발시 상수값으로 지정하여야 합니다. 아래 그림대로 결선하면 데이터선은 D15에 연결됩니다.


Machbase neo의 설치

Mqtt를 통해 데이터를 수신하여 이를 기록 저장하기 위해서 machbase neo의 설치가 필요합니다. doc.machbase.com에서 최신 버전의 machbase neo를 설치하여 수행합니다.


기본 설정으로 machbase neo 서버를 실행한 경우, 접속 IP는 설치한 장비의 ip, mqtt 포트는 5653입니다. 해당 내용을 아래의 펌웨어 개발에서 설정해 주어야 합니다.


 __  __                  _       _
 |  \/  |   __ _    ___  | |__   | |__     __ _   ___    ___
 | |\/| |  / _` |  / __| | '_ \  | '_ \   / _` | / __|  / _ \
 | |  | | | (_| | | (__  | | | | | |_) | | (_| | \__ \ |  __/
 |_|  |_|  \__,_|  \___| |_| |_| |_.__/   \__,_| |___/  \___|

  _ __     ___    ___
 | '_ \   / _ \  / _ \   v8.0.17 (fedc1d8f 2024-04-19T11:42:46)
 | | | | |  __/ | (_) |  engine v8.0.18 (df3cccd1e)
 |_| |_|  \___|  \___/   static_standard_windows_amd64 Windows 10.0 19045

2024/05/10 10:10:39.043 INFO  scheduler        started.
2024/05/10 10:10:39.044 INFO  neosvr           MACH Listen tcp://0.0.0.0:5656
2024/05/10 10:10:39.068 INFO  grpcd            gRPC TLS enabled
2024/05/10 10:10:39.069 INFO  grpcd            gRPC Listen tcp://0.0.0.0:5655
2024/05/10 10:10:39.069 INFO  httpd            HTTP token authentication disabled
2024/05/10 10:10:39.070 INFO  httpd            HTTP path /db for machbase api
2024/05/10 10:10:39.070 INFO  httpd            HTTP path /lakes for lake api
2024/05/10 10:10:39.071 INFO  httpd            HTTP path /metrics for the line protocol
2024/05/10 10:10:39.071 INFO  httpd            HTTP path /web for the web ui
2024/05/10 10:10:39.072 INFO  httpd            HTTP Listen tcp://0.0.0.0:5654
2024/05/10 10:10:39.073 INFO  mqttd            MQTT token authentication disabled
2024/05/10 10:10:39.073 INFO  mqtt-tcp         MQTT Listen tcp://[::]:5653

Machbase neo를 Windows환경에서 설치했다면 방화벽 설정을 해주어야 합니다. Windows 방화벽에서 앱 허용을 수행하여 machbase-neo가 연결을 수행할 수 있도록 허용해 줍니다.


데이터를 입력받을 table을 생성하기 위해 http://(서버 IP):5656 으로 웹브라우저를 이용하여 접속합니다. 이후 데이터를 입력 받을 테이블을 생성합니다.

CREATE TAG TABLE tag (name VARCHAR(20) PRIMARY KEY, time DATETIME BASETIME, value DOUBLE SUMMARIZED) WITH ROLLUP (hour)

이제 데이터를 입력받을 mqtt 브로커 역할을 하는 machbase-neo 서버와 테이블 준비가 끝났습니다. 다음 사항을 준비해 두고 펌웨어 개발을 진행합니다.

  • Machbase neo의 IP 주소 (예제에서는 "192.168.1.131"입니다.)

  • Machbase neo의 mqtt 포트 (기본 설치시 5653입니다.)

  • 데이터를 수집할 센서 tag table명 (예제에서는 TAG)


펌웨어 개발


펌웨어의 동작 방식

센서값을 읽어서 machbase neo 서버에 전송하기 위해, 다음과 같은 순서로 동작합니다.

본 예제의 펌웨어는 github(https://github.com/machbase/esp32-mqtt) 에 공개되어 있습니다.


  1. 네트워크 연결 및 사전 준비

    1. Wifi 네트워크를 연결합니다. (wifi의 ssid 및 접속암호 필요)

    2. Ntp(Network Time protocol) 프로토콜을 이용하여 내장 시계를 동기화합니다.

    3. Machbase neo의 mqtt 브로커에 접속합니다.

    4. DHT-11 센서를 초기화합니다.

  2. Mqtt 브로커(machbase neo 서버)의 연결상태를 확인합니다. 연결이 끊겼으면 재연결을 시도합니다.

  3. 센서에서 데이터 값을 읽어들입니다. 읽어들인 데이터는 machbase neo의 mqtt 데이터 포멧인 json으로 인코딩합니다.

  4. Mqtt topic에 인코딩한 json 데이터를 publish 합니다.

  5. 일정 시간 대기한 다음 2번으로 돌아갑니다.

위 과정을 코드를 통해서 살펴봅시다.


개발 도구 및 모듈 설치

ESP32를 이용하면 일반적으로 펌웨어를 개발하는 것과 다르게 Aruduino IDE를 이용하여 쉽고 빠르게 개발할 수 있습니다. 먼저 Aruduino IDE를 설치한 다음, Tools->Board->Board Manager에서 esp32 by Espressif 모듈을 추가합니다.


모듈 설치시 다운로드와 컴파일 과정을 거치므로 약간의 시간이 걸립니다.


그런 다음, 개발 보드의 usb 드라이버를 설치해 줍니다. 시험에 사용된 보드는 CP2102였으며 해당 드라이버는 silicon labs에서 다운로드 할 수 있었습니다.


모듈과 드라이버를 설치한 이후, ESP32 보드를 usb로 연결하고, 연결된 usb to serial 포트를 설정하면 Arduino IDE에서 인식됩니다. 간단한 샘플 프로그램을 빌드 후 실행해 보면 실행 결과를 IDE의 serial console emuator 창에서 확인할 수 있습니다.


센서 드라이버 및 MQTT 라이브러리 설치

DHT-11 드라이버와 MQTT를 위한 라이브러리를 Tools->Library Manager 메뉴를 통해 설치합니다. DHT sensor library by Adafruit를 검색해서 설치합니다.

PublSubClient 라이브러리를 검색하여 설치해 줍니다.

모든 라이브러리를 설치하면 개발 준비가 완료된 것입니다.


센서 설정


센서와 ESP32 보드를 연결된 GPIO핀의 번호와 센서 모델을 설정하여 센서 정보를 설정합니다.

#define DHTPIN 15
#define DHTTYPE DHT11
//DHTTYPE = DHT11, but there are also DHT22 and 21
DHT dht(DHTPIN, DHTTYPE); // constructor to declare our sensor

이후 setup()함수에서 센서를 초기화합니다.

  dht.begin();

WiFi 접속 및 시간 동기화

먼저 Wifi에 접속하고 network time protocol을 이용한 시간 동기화를 수행합니다. ESP32 개발 보드는 wifi 접속 기능이 있으므로 하드웨어를 추가로 설치할 필요가 없습니다.


// WiFi
const char *ssid = "MACHBASE_AP"; // Enter your Wi-Fi name
const char *password = "xxxxxxxxxx";  // Enter Wi-Fi password
WiFiClient wifi_connection;

접속할 Access point의 SSID와 패스워드를 설정해 줍니다.

wifi 접속은 다음의 코드를 통하여 수행합니다.

  WiFi.mode(WIFI_STA);
  WiFi.begin(ssid, password);

Esp 32보드에는 시간값을 저장하는 배터리가 없습니다. 시계열 데이터의 수집을 위해서는 정확한 현재 시간을 측정할 수 있어야 합니다. 네트워크 연결이 되었으니 ntp(network time protocol)을 이용하여 현재시간을 설정합니다.


//Time
const char* ntpServer = "pool.ntp.org";
const long gmtOffset_sec = 3600*9;
const int daylightOffset_sec = 0;

Ntp 동기화시에 GMT(그리니치 표준시)기준이므로 한국시간에 맞게 설정하려면 9시간을 더해 주어야 합니다. 일광절약시간제는 한국은 적용하지 않으므로 0으로 설정합니다.NTP서버는 공개된 pool.ntp.org를 설정합니다.이후 코드에서 다음 함수를 호출하면 시간 동기화가 수행됩니다.


  configTime(gmtOffset_sec, daylightOffset_sec, ntpServer);

Mqtt 브로커 설정 및 접속

Machbase neo 설치시에 서버의 ip와 mqtt 브로커 포트번호를 확인했습니다. 이 값을 아래와 같이 설정해 줍니다.


// MQTT
const char *mqtt_server = "192.168.1.131";
const char *topic = "db/append/TAG";
const int   mqtt_port = 5653;
PubSubClient mqtt_client(wifi_connection);

wifi 접속을 수행한 다음, 아래의 코드로 mqtt 접속을 진행합니다. 접속 실패시에 재접속 시도를 반복하도록 구현하였습니다.

펌웨어의 메인 루프에서 mqtt 접속을 확인하고 연결이 끊겼으면 재접속을 시도합니다. 


// initialize mqtt client void setup() { mqtt_client.setServer(mqtt_server, mqtt_port); mqtt_client.setCallback(callback); // other code omitted. } void reconnect() { // Loop until we're reconnected while (!mqtt_client.connected()) { Serial.print("Attempting MQTT connection..."); String clientId = "ESP32-"; clientId += WiFi.localIP(); // Attempt to connect if (mqtt_client.connect(clientId.c_str())) { Serial.println("connected"); } else { Serial.print("failed, rc="); Serial.print(mqtt_client.state()); Serial.println(" try again in 5 seconds"); // Wait 5 seconds before retrying delay(5000); } } }

Mqtt 데이터 전송


Mqtt topic


Mqtt는 pub/sub를 이용하여 데이터를 주고 받습니다. Machbase neo에 생성한 tag table에 대한 데이터 입력시에는 "db/API종류/테이블명"의 topic에 대해 publish를 수행해야 합니다. 이번 예제에서는 append api를 이용하여 데이터를 입력할 것이므로 "db/append/TAG"가 입력에 사용할 topic이 됩니다.

Machbase Neo의 데이터 입력시 입력포멧은 json이나 csv가 가능합니다. 이번 예제에서는 Json을 이용하여 입력합니다.


입력 시간값

Machbase neo의 기본 시간값은 나노초단위의 정수형 값입니다. 이번 테스트에는 초 단위의 정밀도만 있으면 되기 때문에 다음과 같이 설정하였습니다.


int64_t get_timestamp_milis() {
    struct timeval tv;
    gettimeofday(&tv, NULL);
  return tv.tv_sec * 1000LL;
// return (tv.tv_sec * 1000LL + (tv.tv_usec / 1000LL));
}

...   //miliseconds to nanoseconds
        current_time = get_timestamp_milis() * 1000000LL;
...


데이터 전송

Mqtt를 이용하여 데이터를 입력할 때, 데이터는 json 혹은 csv 파일형태로 구성되어야 합니다. 아래의 코드에서 센서로부터 읽어들인 데이터를 json형태로 변환하고 이를 Machbase 서버로 보내는 내용을 보여 줍니다.

    // The DHT11 returns at most one measurement every 1s
    float h = dht.readHumidity();
    //Read the moisture content in %.
    float t = dht.readTemperature();
    //Read the temperature in degrees Celsius
    
      snprintf (msg, MSG_BUFFER_SIZE, "[ [\"ESP32.hum\",%lld,%f],
        [\"ESP32.tem\",%lld,%f] ]", 
        current_time, h, current_time, t);
    Serial.print("Publish message: ");
    Serial.println(msg);
    mqtt_client.publish(topic, msg);

구현한 펌웨어를 Arduino IDE를 통해 ESP32 보드로 전송하면 자동으로 수행이 시작됩니다. IDE의 serial console을 이용하여 수행 상태를 확인할 수 있습니다. Machbase neo의 웹 인터페이스에서 질의를 수행하여 입력 상태를 확인할 수 있습니다.


Machbase neo를 이용한 데이터 활용

Machbase Neo에 저장한 데이터는 다른 추가 도구를 설치하지 않아도 쉽게 시각화 하여 분석할 수 있습니다. Machbase neo의 TAG Analyzer를 이용하여 수집한 온/습도 데이터를 간단히 시각화할 수 있습니다.

마크베이스 TSDB는 데이터를 압축하여 저장하므로 장기간의 데이터 수집시에도 저장공간을 적게 차지하고 고속의 인덱스를 기반한 검색기능을 이용하여 많은 데이터도 빠르게 검색할 수 있습니다.


이번 포스트에서는 ESP32 보드를 이용한 네트워크 연결가능한 스마트 센서를 개발해 보았습니다. 아두이노 생태계의 다양한 센서 지원기능을 활용하고 wifi 및 mqtt를 이용한 데이터 전송기능을 이용하여 매우 간단하게 IoT 구현이 가능함을 확인했습니다. Machbase neo에 수집한 데이터는 편리하게 시각화등의 활용이 가능한 것도 알 수 있었습니다.

조회수 120회

최근 게시물

전체 보기
bottom of page