강좌 전체보기

.

이번 장에서는 WiFi 모듈을 이용한 통신 방법들을 다뤄보겠습니다.

WiFi 통신은 블루투스 통신과는 전혀 다른 방식으로 동작합니다. 따라서 센서장치가 WiFi 통신을 사용한다면 블루투스와는 전혀 다른 사용자 UI / 동작 시나리오를 가지게 됩니다. WiFi/블루투스 모두 각자의 장단점이 있지만, 센서장치가 홈 서버나 모바일 장치의 도움 없이 인터넷에 직접 연결된다는 것은 블루투스에 비해 대단히 매력적인 장점입니다.

센서장치에 WiFi 모듈을 이용한다면 대부분은 특정 서버에 접속해서 데이터를 주고 받기 위함일 것입니다. 하지만 데이터를 주고 받는 방법도 다양하게 변화시킬 수 있고, 센서장치 자체가 마이크로 서버처럼 동작하게 만들 수도 있습니다. 이런 세세한 통신 기술들을 익혀두면, 자신의 사물 인터넷 시나리오를 구현함에 있어 최적의 솔루션을 기획할 수 있을겁니다.

공유기 스캔과 연결

WiFi 통신을 위해 가장 먼저 해야할 것은 센서장치 주변의 무선 공유기를 찾는 것입니다. 블루투스에서 주변 장치 스캔을 하듯, WiFi 도 일단 공유기를 스캔하고, 내가 원하는 공유기에 비밀번호를 이용해 접속해야 합니다.

첫 실습은 ESP32 모듈을 이용해 주변에 있는 공유기를 스캔하고 시리얼로 출력하도록 만들어 보겠습니다. 아래 스케치를 ESP32 모듈에 업로드 해주세요.

업로드가 완료되면 [시리얼 모니터] 창을 열어보세요. 일정 시간 간격으로 주변의 무선 공유기(2.4GHz)를 스캔하고 이름을 표시해 줄 것입니다.

스캔 결과를 보면 [공유기 이름] [신호세기] [보안 여부] 정보가 표시되어 있습니다.

여기서 [공유기 이름]은 다른말로 SSID(Service Set Identifier) 라고도 합니다. 소스코드에서는 SSID 라는 변수명을 자주 보게 될 것입니다. [보안 여부]는 비밀번호 없이 접속 가능한 공유기인지 표시합니다. 만약 * 마크가 표시되어 있다면 비밀번호 입력이 필요하다는 의미입니다.

그럼 WiFi 스캔에 사용된 소스코드를 확인해 보겠습니다. 실습 만큼이나 코드도 매우 간단합니다.

#include "WiFi.h"

void setup()
{
    Serial.begin(115200);

    // Set WiFi to station mode and disconnect from an AP if it was previously connected
    WiFi.mode(WIFI_STA);
    WiFi.disconnect();
    delay(100);

    Serial.println("Setup done");
}

void loop()
{
    Serial.println("scan start");

    // WiFi.scanNetworks will return the number of networks found
    int n = WiFi.scanNetworks();
    Serial.println("scan done");
    if (n == 0) {
        Serial.println("no networks found");
    } else {
        Serial.print(n);
        Serial.println(" networks found");
        for (int i = 0; i < n; ++i) {
            // Print SSID and RSSI for each network found
            Serial.print(i + 1);
            Serial.print(": ");
            Serial.print(WiFi.SSID(i));
            Serial.print(" (");
            Serial.print(WiFi.RSSI(i));
            Serial.print(")");
            Serial.println((WiFi.encryptionType(i) == WIFI_AUTH_OPEN)?" ":"*");
            delay(10);
        }
    }
    Serial.println("");

    // Wait a bit before scanning again
    delay(5000);
}

WiFi.scanNetworks() 호출하고 스캔이 끝나면 결과를 출력할 뿐입니다.

눈여결 볼만한 코드는 setup() 함수 안에 있는 WiFi.mode(WIFI_STA) 입니다. 이 코드는 ESP32 모듈을 WIFI_STA 모드로 동작시키겠다는 의미입니다. 보통의 WiFi 모듈들은 아래와 같은 3가지 모드를 제공합니다.

  • WIFI_STA (Station mode, Stand-alone mode)
    • 다른 공유기에 접속해서 IP를 할당받고, HTTP 통신을 사용하는 모드입니다. 이 모드가 가장 많이 사용됩니다.
  • WIFI_AP
    • 공유기처럼 여러개의 WiFi 모듈들이 접속할 수 있도록 해주는, 일종의 WiFi Hub 모드입니다. 근거리에 WiFi 모듈들이 산재한 경우 이들을 WiFi 네트웍으로 묶을 수 있습니다.
  • WIFI_STA + WIFI_AP
    • 앞선 두 가지 모드를 동시에 수행하는 모드입니다. WiFi 모듈에 따라서 사용할 수 있는 기능에 제약이 있기도 합니다.

이 강좌에서는 WIFI_STA 모드만 사용할 것입니다.

Scan은 했으니 이제 연결을 해야겠죠. (연결을 위해 굳이 Scan 을 할 필요는 없지만…) 아래는 연결을 위한 가장 간단한 방법을 구현한 코드입니다.

#include <WiFi.h>

const char* ssid     = "USER_SSID";    // 연결할 SSID
const char* password = "PASSWORD";     // 연결할 SSID의 비밀번호

void setup()
{
    Serial.begin(115200);
    delay(10);
    
    WiFi.begin(ssid, password);

    // 와이파이망에 연결
    while (WiFi.status() != WL_CONNECTED) {
        delay(500);
        Serial.print(".");
    }
}

// 연결 여부 로그 출력
void loop()
{
    if(WiFi.status() == WL_CONNECTED)
        Serial.println("WiFi connected");
    else 
        Serial.println("WiFi not connected");
    delay(1000);
}

긴 설명이 필요없을 정도로 간단한 코드입니다. 소스코드에서 ssid, password 값만 자신의 공유기 설정에 맞게 넣어주면 됩니다. 그리고 ESP32 모듈에 업로드하면 해당 공유기에 연결을 시도합니다.

코드를 살펴보면, setup() 안에서 WiFi.begin() 함수를 이용해서 연결을 시도합니다. 그리고 WiFi.status() 함수로 연결 여부를 체크하면 됩니다.

다중 공유기 설정 등록

센서장치가 항상 특정 공유기 근처에서 동작하는 경우라면, 하나의 공유기만 등록한 뒤 그 공유기에만 연결을 시도하면 됩니다. 하지만 센서장치가 계속 움직이는 경우라면?

이런 경우 센서장치가 사용할 수 있는 공유기들을 여러개 등록해 두고, 그 중 하나가 검색되면 연결하는 방식이 효율적일겁니다. WiFiMulti 가 바로 이런 역할을 자동으로 해주는 기능입니다. 아래 스케치에 담긴 코드를 확인해보세요.

#include <WiFi.h>
#include <WiFiMulti.h>

WiFiMulti wifiMulti;

void setup()
{
    Serial.begin(115200);
    delay(10);

    wifiMulti.addAP("ssid_from_AP_1", "your_password_for_AP_1");
    wifiMulti.addAP("ssid_from_AP_2", "your_password_for_AP_2");
    wifiMulti.addAP("ssid_from_AP_3", "your_password_for_AP_3");

    Serial.println("Connecting Wifi...");
    if(wifiMulti.run() == WL_CONNECTED) {
        Serial.println("");
        Serial.println("WiFi connected");
        Serial.println("IP address: ");
        Serial.println(WiFi.localIP());
    }
}

void loop()
{
    if(wifiMulti.run() != WL_CONNECTED) {
        Serial.println("WiFi not connected!");
        delay(1000);
    }
}

setup() 함수 안에서 wifiMulti.addAP() 를 이용해 공유기를 3개 등록하죠? 공유기를 등록할 때 SSID(이름), Password(비번)을 넣어주도록 되어 있습니다. wifiMulti.addAP() 를 이용해서 사용하길 원하는 공유기를 원하는 수만큼 등록해보세요.

그리고 소스코드를 업로드해서 동작시켜 보세요. ESP32 모듈이 자동으로 연결 가능한 AP 들을 찾아 연결할 것입니다.

SmartConfig 을 이용한 연결

이번엔 좀 더 우아한 방법으로 공유기에 연결하도록 해보겠습니다. SmartConfig을 이용한 방법입니다.

SmartConfig 은 앞선 방법들과는 달리 소스코드에 공유기의 SSID, Password 를 일일이 적어서 업로드 할 필요가 없습니다. 대신 핸드폰에 SmartConfig 을 지원하는 앱을 깔아서, 핸드폰을 통해 ESP32 모듈이 접속할 공유기를 알려줄겁니다. 손 안대고 코 푸는 격입니다.

아래 스케치를 받아 ESP32 모듈에 업로드 하세요. 그리고 [시리얼 모니터]를 실행하세요. ESP32 모듈은 SmartConfig 정보가 들어오길 계속 기다릴겁니다.

이제 핸드폰에 SmartConfig 을 지원하는 앱을 설치하면 됩니다. App Store 에서 SmartConfig 으로 검색하면 여러 앱을 찾을 수 있습니다. 그 중 하나를 설치해보세요.

앱을 실행하기 전에 주변에 연결 가능한 공유기에 핸드폰을 연결하세요. 전 NETGEAR60 공유기에 연결했습니다. 반드시 2.4GHz 공유기를 사용하세요. 그리고 설치한 앱을 실행하세요.

현재 핸드폰이 연결된 공유기가 뜰겁니다. 비밀번호를 입력하고 Submit 을 누르세요.

그럼 공유기 연결을 위한 SSID, Password 정보가 무선을 통해 날라갑니다. ESP32 모듈은 이 SmartConfig 신호를 잡아서 해당 공유기에 연결을 시도합니다.

공유기에 성공적으로 연결되어 내부 IP (192.168.1.x)를 받았습니다!!

이처럼 SmartConfig 을 사용하면 굳이 소스코드에 연결할 공유기들을 지정하지 않아도 주변 공유기 상황에 맞춰 연결해줄 수 있습니다.

공유기와 연결하는 기본적인 연결법을 다루었으니 다음 파트부터는 WiFi 를 통해 HTTP 통신을 해보겠습니다.

주의!!! [사물 인터넷 네트워크와 서비스 구축 강좌] 시리즈 관련 문서들은 무단으로 내용의 일부 또는 전체를 게시하여서는 안됩니다. 계속 내용이 업데이트 되는 문서이며, 문서에 인용된 자료의 경우 원작자의 라이센스 문제가 있을 수 있습니다.

강좌 전체보기

.