스마트팜 시스템의 설계부터 구현까지 바로 적용할 수 있도록 구성한 예제입니다. 이 예제는 Arduino(ESP8266)에서 온도/습도 센서(DHT22)와 기타 센서 데이터를 읽어 .NET 백엔드로 전송하고, 백엔드에서는 SignalR Hub를 통해 .NET MAUI 클라이언트에 실시간 데이터를 전달하는 전체 흐름을 포함합니다.
1. 시스템 아키텍처 개요
- Arduino (ESP8266)
- 센서 연결: DHT22(온도, 습도) 및 필요에 따라 다른 센서를 연결
- 데이터 전송: WiFi를 통해 HTTP POST로 센서 데이터를 .NET 백엔드 서버에 전송
- .NET 백엔드 (ASP.NET Core + SignalR)
- SignalR Hub: /farmHub 엔드포인트에서 클라이언트와 실시간 통신
- API 엔드포인트: /api/sensor에서 Arduino가 전송한 센서 데이터를 수신 후, 연결된 모든 클라이언트에 브로드캐스트
- .NET MAUI 클라이언트
- UI 구성: 센서 데이터를 실시간으로 표시하는 간단한 UI
- SignalR 클라이언트: 백엔드 SignalR Hub에 연결하여 데이터 수신
2. 구현 단계
2.1. .NET 백엔드 (ASP.NET Core + SignalR)
프로젝트 생성 및 코드 구성
- Visual Studio에서 ASP.NET Core Web API 프로젝트를 생성합니다.
- NuGet 패키지 추가:
- Microsoft.AspNetCore.SignalR
- (필요 시) Microsoft.AspNetCore.SignalR.Core
Startup.cs (또는 Program.cs – .NET 6 이상)
아래 예제는 Startup.cs를 사용하는 형태이며, .NET 6 이상은 Program.cs로 통합할 수 있습니다.
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.SignalR;
using Microsoft.Extensions.DependencyInjection;
using System.IO;
using System.Threading.Tasks;
namespace SmartFarmBackend
{
// SignalR Hub 정의
public class FarmHub : Hub
{
// 추가적인 Hub 메서드 구현 가능
}
public class Startup
{
public void ConfigureServices(IServiceCollection services)
{
services.AddSignalR();
services.AddControllers();
}
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
app.UseRouting();
app.UseEndpoints(endpoints =>
{
// SignalR Hub 엔드포인트
endpoints.MapHub<FarmHub>("/farmHub");
// Arduino 센서 데이터 수신 API
endpoints.MapPost("/api/sensor", async context =>
{
using var reader = new StreamReader(context.Request.Body);
var sensorData = await reader.ReadToEndAsync();
// 연결된 모든 클라이언트에 센서 데이터 브로드캐스트
var hubContext = context.RequestServices.GetService<IHubContext<FarmHub>>();
await hubContext.Clients.All.SendAsync("ReceiveSensorData", sensorData);
context.Response.StatusCode = 200;
await context.Response.WriteAsync("Data received");
});
});
}
}
}
실행:
이 프로젝트를 실행한 후, SignalR Hub는 https://[서버주소]/farmHub로, 센서 데이터 API는 https://[서버주소]/api/sensor로 접근할 수 있습니다.
2.2. .NET MAUI 클라이언트
프로젝트 생성 및 SignalR 클라이언트 구현
- Visual Studio에서 .NET MAUI 프로젝트를 생성합니다.
- NuGet 패키지 추가:
- Microsoft.AspNetCore.SignalR.Client
MainPage.xaml
MainPage.xaml.cs
using Microsoft.AspNetCore.SignalR.Client;
using Microsoft.Maui.Controls;
using System;
using System.Threading.Tasks;
namespace SmartFarmMauiApp
{
public partial class MainPage : ContentPage
{
HubConnection hubConnection;
public MainPage()
{
InitializeComponent();
InitializeSignalR();
}
async void InitializeSignalR()
{
// 백엔드 서버 주소를 실제 서버 주소로 변경하세요.
hubConnection = new HubConnectionBuilder()
.WithUrl("https://yourserveraddress/farmHub")
.Build();
// SignalR Hub에서 데이터 수신 시 처리
hubConnection.On<string>("ReceiveSensorData", (data) =>
{
MainThread.BeginInvokeOnMainThread(() =>
{
SensorDataLabel.Text = data;
});
});
await ConnectToHub();
}
async Task ConnectToHub()
{
try
{
await hubConnection.StartAsync();
}
catch (Exception ex)
{
// 연결 실패 시 로깅 또는 재시도 로직 추가 가능
Console.WriteLine($"SignalR 연결 실패: {ex.Message}");
}
}
}
}
실행:
MAUI 앱을 실행하면 백엔드 SignalR Hub에 연결되어 Arduino에서 전송하는 센서 데이터를 실시간으로 표시합니다.
2.3. Arduino (ESP8266 + DHT22)
Arduino IDE 설정 및 라이브러리 설치
- 라이브러리 설치:
- 하드웨어 연결:
- DHT22 센서를 ESP8266의 디지털 핀(예: D4)에 연결합니다.
- 필요에 따라 추가 센서를 연결합니다.
Arduino 코드 예제
아래 코드는 DHT22 센서를 사용하여 온도/습도 데이터를 읽고, 주기적으로 .NET 백엔드의 /api/sensor 엔드포인트로 전송합니다.
#include <ESP8266WiFi.h>
#include <ESP8266HTTPClient.h>
#include <DHT.h>
// DHT 센서 설정 (DHT22 사용)
#define DHTPIN D4 // 연결 핀 (필요에 따라 변경)
#define DHTTYPE DHT22
DHT dht(DHTPIN, DHTTYPE);
// WiFi 설정
const char* ssid = "YOUR_WIFI_SSID";
const char* password = "YOUR_WIFI_PASSWORD";
// 백엔드 서버 URL (IP 또는 도메인, 포트 포함)
const char* serverUrl = "http://yourserveraddress/api/sensor";
void setup() {
Serial.begin(115200);
delay(10);
// DHT 센서 초기화
dht.begin();
// WiFi 연결
WiFi.begin(ssid, password);
Serial.print("Connecting to WiFi");
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("\nWiFi connected");
}
void loop() {
if (WiFi.status() == WL_CONNECTED) {
HTTPClient http;
http.begin(serverUrl);
http.addHeader("Content-Type", "text/plain");
// 온도와 습도 읽기
float temperature = dht.readTemperature();
float humidity = dht.readHumidity();
// 센서 읽기 실패 시 처리
if (isnan(temperature) || isnan(humidity)) {
Serial.println("DHT 센서 읽기 실패!");
delay(2000);
return;
}
// 추가 센서 데이터가 있을 경우 문자열에 포함 가능
String sensorData = "Temperature:" + String(temperature) + ";Humidity:" + String(humidity);
// 예시로 추가 센서: 토양 수분 값 (가상 값 사용)
// int soilMoisture = analogRead(A0);
// sensorData += ";Soil:" + String(soilMoisture);
int httpResponseCode = http.POST(sensorData);
if (httpResponseCode > 0) {
Serial.printf("HTTP Response code: %d\n", httpResponseCode);
} else {
Serial.printf("Error code: %d\n", httpResponseCode);
}
http.end();
} else {
Serial.println("WiFi Disconnected");
}
// 5초마다 데이터 전송 (필요 시 간격 조정)
delay(5000);
}
실행:
- Arduino 보드를 업로드하고, WiFi 연결 정보를 실제 네트워크에 맞게 수정합니다.
- 코드 실행 후, 센서 데이터가 주기적으로 백엔드 API로 전송됩니다.
3. 전체 데이터 흐름
- Arduino (ESP8266):
- DHT22 센서에서 온도와 습도를 읽어 문자열 형식으로 구성
- HTTP POST 요청을 통해 /api/sensor 엔드포인트로 전송
- .NET 백엔드:
- /api/sensor 엔드포인트에서 데이터를 수신
- SignalR Hub(/farmHub)를 통해 모든 연결된 클라이언트에 데이터 브로드캐스트
- .NET MAUI 클라이언트:
- SignalR 클라이언트가 백엔드에 연결되어 실시간 센서 데이터를 수신
- UI 라벨에 데이터를 업데이트하여 사용자에게 표시
4. 배포 및 적용 팁
- 보안:
- 운영 환경에서는 HTTPS 사용 및 인증/암호화 적용
- API 엔드포인트에 토큰 인증이나 IP 화이트리스트 적용 고려
- 에러 핸들링:
- 각 컴포넌트에서 예외 처리 및 로깅을 추가하여 문제 상황을 추적
- Arduino의 경우, WiFi 재연결 로직 추가 가능
- 확장성:
- 센서 종류가 늘어나면, API에서 JSON 형식으로 데이터를 전송하여 확장성을 고려
- 백엔드에서는 센서별 데이터를 분리하여 저장하거나 분석하는 기능 추가
- 테스트:
- 각 부분을 독립적으로 테스트한 후 전체 시스템 통합 테스트를 진행
- MAUI 앱의 경우, 실제 디바이스나 에뮬레이터에서 테스트
.png)
댓글
댓글 쓰기