1. 개념
https://powerdeng.tistory.com/227
2. 개요
Wi-Fi 공유기에 IoT 보드와 PC( C#으로 UDP 서버 역할)가 연결되면 같은 공유기에 연결된 것들끼리는 UDP 통신이 가능하다. 따라서 이를 이용하여 보드에서 PC로 "나는 ESP8266보드이다!!"라고 메시지를 보내고, PC에서 보드로는 "나는 C# UDP 클라이언트이다!"라고 메시지를 보내는 프로젝트를 진행하려고 한다.
<참고 자료>
보드 정보: WeMos D1 R1
https://www.devicemart.co.kr/goods/view?no=1312096
3. 진행 과정
1번. IoT보드가 UDP 통신이 가능한 클라이언트로 만든다.
2번. C#으로 서버 역할을 할 UDP 클라이언트를 만든다.
3번. 1번과 2번이 서로 연결되는지 확인한다.
4. IoT보드가 UDP 통신이 가능한 클라이언트 만들기
1) 개발 환경 설정
① Arduino IDE 다운로드
아래의 링크에서 Arduino IDE를 다운로드한다(여기서는 2.3.2 버전을 사용하였다.)
https://www.arduino.cc/en/software
② 보드매니저 URL 추가
Arduino IDE 상단 File 탭에서 Preferences을 선택하면 아래의 그림1이 나온다.
그림1에 표시된 것처럼 추가적인 보드매니저 URL에 아래의 링크를 추가한다.
https://arduino.esp8266.com/stable/package_esp8266com_index.json
③ 보드 설치
아래 그림2에 표시된 부분을 눌러서 보드 매니저에 들어간 뒤, ESP8266을 검색하여 해당 보드를 설치한다.
여기서는 3.1.2 버전을 사용하였다.
④ 보드 및 포트 설정
WeMos 보드를 컴퓨터에 연결한 뒤 아래 그림3에 표시된 부분을 눌러서 Select other board and port를 누른다.
아래 그림4처럼 WeMos 보드를 검색하여 LOLIN(WeMos) D1 R1와 연결된 포트를 선택하고 OK를 누른다.
⑤ 보드 정상 작동 확인
아래 그림5처럼 상단 File 탭에서 Examples -> ESP8266 -> Blink를 선택한다.
아래 그림6에 표시된 부분을 눌러서 Blink 예제를 보드에 Upload한다.
정상적으로 Upload가 되면 아래 동영상처럼 Wi-Fi 칩부분의 LED가 깜빡거린다.
2) 코드 작성
여기서 작성한 코드는 아래 경로의 UDP 코드를 기본으로 작성했다.
File -> Examples -> ESP8266WiFi -> Udp
#include <ESP8266WiFi.h>
#include <WiFiUdp.h>
// 사물인터넷보드가 와이파이 공유기와 연결하기 위한 ID, PW를 입력해야 한다.
#ifndef STASSID
#define STASSID "미래기술"
#define STAPSK "hynux17830"
#endif
// IoT보드에서 사용할 포트번호
unsigned int localPort = 60000; // local port to listen on
// 송수신 데이터의 버퍼를 생성한다.
char packetBuffer[UDP_TX_PACKET_MAX_SIZE + 1]; // buffer to hold incoming packet,
char ReplyBuffer[] = "나는 ESP8266보드이다!!\r\n"; // a string to send back
// UDP 통신을 위한 클래스
WiFiUDP Udp;
unsigned long t = 0;
void setup() {
// 와이파이 공유기와 접속하기 위한 절차가 진행된다.
Serial.begin(9600);
WiFi.mode(WIFI_STA);
WiFi.begin(STASSID, STAPSK);
while (WiFi.status() != WL_CONNECTED) {
Serial.print('.');
delay(500);
}
Serial.print("Connected! IP address: ");
Serial.println(WiFi.localIP());
Serial.printf("UDP server on port %d\n", localPort);
// 상단에 지정된 포트를 UDP 통신에 개구멍으로 쓴다.
Udp.begin(localPort);
}
void loop() {
// 수신된 데이터의 길이를 받는다.
int packetSize = Udp.parsePacket();
if (packetSize) {
//Serial.printf("Received packet of size %d from %s:%d\n (to %s:%d, free heap = %d B)\n", packetSize, Udp.remoteIP().toString().c_str(), Udp.remotePort(), Udp.destinationIP().toString().c_str(), Udp.localPort(), ESP.getFreeHeap());
// UDP 통신으로 데이터를 수신한다.
int n = Udp.read(packetBuffer, UDP_TX_PACKET_MAX_SIZE);
packetBuffer[n] = 0;
// 받아온 데이터를 출력한다.
Serial.println(packetBuffer);
}
// 1초에 한 번마다 UDP 통신으로 C# UDP 클라이언트에 메시지를 전송한다.
if (millis() - t > 1000) {
t = millis();
// UDP 전송데이터의 시작(목적지의 주소가 필요하다)
Udp.beginPacket("192.168.2.197", 60001);
Udp.write(ReplyBuffer);
// UDP 전송데이터의 끝
Udp.endPacket();
}
}
/*
test (shell/netcat):
--------------------
nc -u 192.168.esp.address 8888
*/
5. C#으로 서버 역할을 할 UDP 클라이언트 만들기
1) 개발 환경 설정
① Visual Studio Community 설치
여기서는 2022 버전을 사용하였다.
② .NET 데스크톱 개발 설치
아래 그림7에 표시된 것 같이 .NET 데스크톱 개발을 체크한 뒤 설치한다.
③ 프로젝트 생성
새 프로젝트 만들기를 누르면 아래 그림8의 화면이 나온다.
이때 그림8에 표시된 것 처럼 Windows Forms 앱(.NET Framework)를 선택하여 프로젝트를 생성한다.
2) 코드 작성
여기서 작성한 코드는 아래 경로의 예시를 기본으로 작성했다.
https://learn.microsoft.com/ko-kr/dotnet/api/system.net.sockets.udpclient?view=net-5.0
<UI>
<코드>
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace UDP_IoT_WinForm
{
public partial class Form1 : Form
{
UdpClient udpClient = new UdpClient(60001);
Thread t;
bool is_udp_run = false;
public Form1()
{
InitializeComponent();
}
void powerdeng_udp()
{
try
{
Byte[] sendBytes = Encoding.UTF8.GetBytes("나는 C# UDP 클라이언트이다!");
//udp로 연결될 대상이 있는데 그 대상이 누구든지 그냥 받아 들이겠다.
IPEndPoint RemoteIpEndPoint = new IPEndPoint(IPAddress.Any, 0);
DateTime dt = DateTime.Now;
while(is_udp_run)
{
if((DateTime.Now - dt).TotalSeconds > 1)
{
dt = DateTime.Now;
// 1초마다 한번씩 전송한다.
udpClient.Connect("192.168.2.195", 60000);
udpClient.Send(sendBytes, sendBytes.Length);
}
// Blocks until a message returns on this socket from a remote host.
Byte[] receiveBytes = udpClient.Receive(ref RemoteIpEndPoint);
string returnData = Encoding.UTF8.GetString(receiveBytes);
/*
// Uses the IPEndPoint object to determine which of these two hosts responded.
Console.WriteLine("This is the message you received " +
returnData.ToString());
Console.WriteLine("This message was sent from " +
RemoteIpEndPoint.Address.ToString() +
" on their port number " +
RemoteIpEndPoint.Port.ToString());
*/
richTextBox1.Text += returnData + "@" + RemoteIpEndPoint.Address.ToString() + ":" + RemoteIpEndPoint.Port.ToString() +"\n";
}
//udpClient.Close();
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
}
}
private void button1_Click(object sender, EventArgs e)
{
is_udp_run = true;
t = new Thread(new ThreadStart(powerdeng_udp));
t.Start();
}
private void button2_Click(object sender, EventArgs e)
{
is_udp_run = false;
if(t != null && t.IsAlive) t.Abort();
}
}
}
6. IoT 보드와 PC연결 확인 및 최종 테스트
PC에서는 IoT보드의 메시지가, IoT보드에서는 PC의 메시지가 출력되는 것을 확인할 수 있다.
<참고 자료>
아두이노 IDE 환경설정
https://rockjjy.tistory.com/2453
프로젝트 전체적인 과정
https://www.youtube.com/watch?v=mHTFR4CnHxA
'토이 프로젝트' 카테고리의 다른 글
Arduino 보드에서 생성된 값을 Serial 통신을 사용하여 서버로 보내기 (0) | 2024.03.19 |
---|---|
Arduino 보드와 PC(C# 사용)간에 UDP 통신을 사용하여 LED 제어하기 (0) | 2024.03.15 |