본문 바로가기
Unity

[Unity] NodeMCU와 유니티를 와이파이로 연결하기 (UDP)

by ifhead 2022. 8. 11.
반응형

 

NodeMCU란?

NodeMCU

NodeMCU는 오픈소스 사물인터넷 플랫폼입니다.

와이파이 기능이 구현된 MCU 개발보드로 네트워크 기능을 사용할 수 있습니다.

 

아두이노와는 다르게 와이파이를 이용할 수 있으며

Micro5핀 케이블로 전원 및 데이터를 연결할 수 있어 편리합니다.

USB to Micro 5핀
NodeMCU의 사양

NodeMCU의 핀을 아두이노 IDE에서 사용하기 위해서는 GPIO 번호를 참고해야 합니다.

보드에 있는 디지털 0번(D0)을 사용하고 싶다면 숫자 16을 사용하는 식입니다.

 

 

개발환경 준비

아두이노 IDE 환경설정

  • 환경설정 하단의 Additional Boards Manager URLs: 에 다음의 텍스트를 붙여넣고 저장합니다.
http://arduino.esp8266.com/stable/package_esp8266com_index.json
  • 이제 보드 매니저를 통해 패키지를 설치할 수 있게 되었습니다.

보드 매니저 열기

  • IDE가 NodeMCU라는 새로운 보드를 인식할 수 있도록 패키지를 설치해 줍니다.

보드 매니저를 통해 esp8266 패키지 설치

  • esp8266을 검색하여 패키지를 설치해 줍니다.
  • 이 패키지는 비단 NodeMCU뿐만이 아니라, esp 모듈이 탑재된 대부분의 보드를 사용할 수 있게 해줍니다.

준비가 끝났습니다.

이제 아두이노 IDE가 코드를 업로드할 수 있는 상태가 되었습니다.

Micro5핀으로 PC와 보드를 연결하면 인식하는 모습을 보실 수 있습니다.

 

 

와이파이 연결 테스트 코드를 업로드

업로드하기 전 4, 5번 라인에 와이파이 이름과 비밀번호를 입력해주세요.

#include <ESP8266WiFi.h>

const char* ssid = "여기에 와이파이 이름을 입력";
const char* password = "여기에 와이파이 비밀번호를 입력";

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

void loop() {
  if(WiFi.status() != WL_CONNECTED){ //연결이 끊어졌다면
    Serial.println("try reconnect"); 
    Wifi_connect(); // 다시 연결을 시도
  }
  delay(5000);
}

void Wifi_connect() {
  Serial.println("---------------------------------------");
  Serial.println(ssid);
  WiFi.begin(ssid, password); // WIFI연결 시작
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }

  Serial.println();
  Serial.println("Wifi connected!");
  Serial.println("\nConnected to network");
  Serial.print("My IP address is: ");
  Serial.println(WiFi.localIP());
}
  • COM포트를 확인하고 코드를 업로드해봅니다.

정상 업로드를 알리는 콘솔 화면

 

네트워크에 잘 연결되었습니다.

  • 위와 같이 시리얼 모니터를 설정해 주어야 정상적으로 메시지가 출력됩니다.
  • 참고 : WiFi.status는 8개의 리턴값을 가집니다.

 

더보기

WiFi.status 리턴값의 종류

WL_CONNECTED: WiFi 네트워크에 연결될 때 할당됩니다.
WL_NO_SHIELD: WiFi 실드가 없을 때 할당됩니다.
WL_IDLE_STATUS: WiFi.begin()이 호출될 때 할당된 임시 상태이며 시도 횟수가 만료되거나(결과적으로 WL_CONNECT_FAILED가 됨) 연결이 설정될 때까지(결과적으로 WL_CONNECTED가 됨) 활성 상태를 유지합니다.
WL_NO_SSID_AVAIL: 사용 가능한 SSID가 없을 때 할당됩니다.
WL_SCAN_COMPLETED: 스캔 네트워크가 완료되면 할당됩니다.
WL_CONNECT_FAILED: 모든 시도에 대해 연결이 실패할 때 할당됩니다.
WL_CONNECTION_LOST: 연결이 끊어지면 할당됩니다.
WL_DISCONNECTED: 네트워크 연결이 끊겼을 때 할당됨.

 

 

유니티 측 UDP 세팅

UDP(User Datagram Protocol)는 IP에 기반한 전송 프로토콜로써,

한 네트워크(WiFi)안에 있는 컴퓨터들 간의 메시지를 교환합니다.

유니티에서 UDP 통신은 두 가지 클래스를 중 하나를 사용합니다.

 

1. System.Net.Sockets -> UdpClient Class

2. System.Net.Sockets -> Socket Class

 

2번 Socket을 사용해보도록 하겠습니다.

 

UDPClient.cs

코드에 아이피를 기입해주세요.

using UnityEngine;
using System.Collections;
using System;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;

public class UDPClient : MonoBehaviour
{
    public string recvStr;
    private string UDPClientIP;
    string str = "From Unity!";
    Socket socket;
    EndPoint serverEnd;
    IPEndPoint ipEnd;

    byte[] recvData = new byte[1024];
    byte[] sendData = new byte[1024];
    int recvLen = 0;
    Thread connectThread;

    void Start()
    {
        UDPClientIP = "----아이피를 기입하세요----";
        UDPClientIP = UDPClientIP.Trim();       
        InitSocket(); 
    }

    void InitSocket()
    {
        ipEnd = new IPEndPoint(IPAddress.Parse(UDPClientIP), 25666);
        socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
        IPEndPoint sender = new IPEndPoint(IPAddress.Any, 0);
        serverEnd = (EndPoint)sender;
        print("    ");
        SocketSend(str);
        print("  ");

        connectThread = new Thread(new ThreadStart(SocketReceive));
        connectThread.Start();
    }
    
    void SocketSend(string sendStr)
    {
        sendData = new byte[1024];
        sendData = Encoding.UTF8.GetBytes(sendStr);
        socket.SendTo(sendData, sendData.Length, SocketFlags.None, ipEnd);
    }

    void SocketReceive()
    {
        while (true)
        {
            recvData = new byte[1024];
            try
            {
                recvLen = socket.ReceiveFrom(recvData, ref serverEnd);
            }
            catch (Exception e)
            {
            }

            print("    : " + serverEnd.ToString());
            if (recvLen > 0)
            {
                recvStr = Encoding.UTF8.GetString(recvData, 0, recvLen);
            }

            print(recvStr);
        }
    }
  
    void SocketQuit()
    {
        if (connectThread != null)
        {
            connectThread.Interrupt();
            connectThread.Abort();
        }
        if (socket != null)
            socket.Close();
    }
    void OnApplicationQuit()
    {
        SocketQuit();
    }

    void Update()
    {

    }
}

 

 

NodeMCU 측 UDP 세팅

 

WiFiUDP.ino

코드에 와이파이 이름과 비밀번호를 기입해주세요.

#include <ESP8266WiFi.h>
#include <WiFiUdp.h>

const char* ssid = "---와이파이 이름---";
const char* password = "---와이파이 비밀번호---";

WiFiUDP Udp;
unsigned int port = 25666;
char packet[255];

IPAddress ip(192, 168, 43, 20);
IPAddress gateway(192, 168, 1, 1);
IPAddress subnet(255, 255, 255, 0);

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

  WiFi.hostname("YVRB-01");
  WiFi.config(ip, gateway, subnet);

  Serial.printf("Connecting to %s ", ssid);
  WiFi.begin(ssid, password);

  while (WiFi.status() != WL_CONNECTED)
  {
    delay(500);
    Serial.print(".");
  }

  Serial.println("Connection Successful");
  Udp.begin(port);
  Serial.printf("Listener started at IP %s, at port %d", WiFi.localIP().toString().c_str(), port);
  Serial.println();
}

void loop()
{
  int packetSize = Udp.parsePacket();
  if (packetSize)
  {
    Serial.printf("Received %d bytes from %s, port %d", packetSize, Udp.remoteIP().toString().c_str(), Udp.remotePort());
    int len = Udp.read(packet, 255);
    if (len > 0)
    {
      packet[len] = 0;
    }
    Serial.printf("UDP packet contents: %s", packet);
    Serial.println();
  }

  Udp.beginPacket (Udp.remoteIP(), Udp.remotePort());
  Udp.write("Important data");
  Udp.endPacket();

  delay(300);
}

 

Unity - NodeMCU 연결 확인

시리얼 모니터와 유니티 콘솔에서 연결을 확인합니다.

"From Unity!" 메시지가 확인되시나요?

이렇게 유니티와 NodeMCU를 WiFi 망에서 UDP 통신방식으로 연결해보았습니다.

반응형

댓글