아두이노 나노 ESP32 - 웹 서버 다중 페이지 | Arduino Nano ESP32 - Web Server Multiple Pages
이 튜토리얼에서는 Arduino Nano ESP32를 웹 서버로 변환하는 방법을 알아보겠습니다. 이 웹 서버는 index.html, temperature.html, led.html, error_404.html, error_405.html과 같이 동시에 여러 페이지를 처리할 수 있습니다...
이 튜토리얼을 따라하면 아두이노 나노 ESP32를 웹 서버로 바꾸고 몇 가지 멋진 기능을 추가할 수 있습니다:
여러 웹 페이지가 동시에 활성 상태입니다.
각 페이지의 HTML 컨텐츠(HTML, CSS, 및 Javascript 포함)는 Arduino IDE에서 각자의 파일로 별도로 저장됩니다.
HTML 컨텐츠는 센서의 실시간 값으로 동적으로 업데이트 될 수 있어, 웹 페이지를 동적이고 반응형으로 만듭니다.
웹 서버는 웹을 통해 Arduino Nano ESP32에 연결된 무언가를 제어할 수 있습니다.
웹 서버는 404 Not Found와 405 Method Not Allowed와 같은 HTTP 오류 코드를 처리합니다.
복잡하게 들릴 수도 있지만 걱정하지 마세요! 이 튜토리얼은 단계별 지침을 제공하고 코드는 초보자도 쉽게 이해하고 자신만의 Arduino Nano ESP32 웹 서버를 만들 수 있도록 초보자 친화적으로 설계되었습니다.
1 | × | Arduino Nano ESP32 | Amazon | |
1 | × | USB Cable Type-C | 쿠팡 | Amazon | |
1 | × | (Recommended) Screw Terminal Expansion Board for Arduino Nano | 쿠팡 | Amazon | |
공개: 이 섹션에서 제공된 링크 중 일부는 제휴 링크입니다. 이 링크를 통해 구매한 경우 추가 비용없이 수수료를 받을 수 있습니다. 지원해 주셔서 감사합니다.
Arduino Nano ESP32 및 Web Server(핀 아웃, 작동 방식 및 프로그래밍 포함)에 익숙하지 않다면, 다음 튜토리얼을 통해 배울 수 있습니다:
아두이노 나노 ESP32 - 웹 서버
아래는 여러 페이지를 가진 웹 서버를 생성하는 Arduino Nano ESP32 코드의 전체입니다. 간단하게 유지하기 위해 각 페이지의 HTML 내용은 매우 간단하며 Arduino Nano ESP32 코드에 직접 포함되어 있습니다. 다른 부분에서는 각 페이지의 HTML 내용을 별도의 파일로 분리하는 방법을 배우게 되어 코드를 더 정리되고 관리하기 쉽게 만듭니다.
#include <WiFi.h>
#include <ESPAsyncWebServer.h>
#define LED_PIN D5
const char *ssid = "YOUR_WIFI_SSID";
const char *password = "YOUR_WIFI_PASSWORD";
AsyncWebServer server(80);
int LED_state = LOW;
float getTemperature() {
float temp_x100 = random(0, 10000);
return temp_x100 / 100;
}
void setup() {
Serial.begin(9600);
pinMode(LED_PIN, OUTPUT);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(1000);
Serial.println("Connecting to WiFi...");
}
Serial.println("Connected to WiFi");
Serial.print("Arduino Nano ESP32 Web Server's IP address: ");
Serial.println(WiFi.localIP());
server.on("/", HTTP_GET, [](AsyncWebServerRequest *request) {
Serial.println("Web Server: home page");
request->send(200, "text/html", "This is the ESP32 home page");
});
server.on("/temperature.html", HTTP_GET, [](AsyncWebServerRequest *request) {
Serial.println("Web Server: temperature page");
float temperature = getTemperature();
request->send(200, "text/html", "Temperature: " + String(temperature));
});
server.on("/led.html", HTTP_GET, [](AsyncWebServerRequest *request) {
Serial.print("Web Server: LED page");
if (request->hasArg("state")) {
String state = request->arg("state");
if (state == "on") {
LED_state = HIGH;
} else if (state == "off") {
LED_state = LOW;
}
digitalWrite(LED_PIN, LED_state);
Serial.print(" => turning LED to ");
Serial.print(state);
}
Serial.println();
request->send(200, "text/html", "LED state: " + String(LED_state));
});
server.onNotFound([](AsyncWebServerRequest *request) {
if (request->method() == HTTP_GET) {
Serial.println("Web Server: Not Found");
request->send(404, "text/html", "Not Found");
} else {
Serial.println("Web Server: Method Not Allowed");
request->send(405, "text/html", "Method Not Allowed");
}
});
server.begin();
Serial.println("Arduino Nano ESP32 Web server started");
}
void loop() {
}
아두이노 나노 ESP32를 시작하려면 다음 단계를 따르세요:
Arduino Nano ESP32 보드를 USB 케이블을 사용하여 컴퓨터에 연결하세요.
컴퓨터에서 Arduino IDE를 실행하세요.
Arduino Nano ESP32 보드와 해당 COM 포트를 선택하세요.
Arduino IDE의 왼쪽 내비게이션 바에서 Library Manager 아이콘을 클릭하여 라이브러리 관리자를 열어주세요.
“ESPAsyncWebServer”을 검색하고, ESPAsyncWebServer를 찾으세요.
Lacamera가 제공하는 ESPAsyncWebServer 라이브러리를 설치하려면 Install 버튼을 클릭하세요.
의존성을 설치하라는 요청을 받게 됩니다. Install All 버튼을 클릭하세요.
위의 코드를 복사하고 Arduino IDE로 열기
코드 내의 와이파이 정보(SSID와 비밀번호)를 본인 것으로 변경하기
Arduino IDE의 Upload 버튼을 클릭해서 코드를 Arduino Nano ESP32에 업로드하기
시리얼 모니터 열기
시리얼 모니터에서 결과 확인하기
Connecting to WiFi...
Connected to WiFi
Arduino Nano ESP32 Web Server's IP address: 192.168.0.2
Arduino Nano ESP32 Web server started
192.168.0.2
192.168.0.2/index.html
192.168.0.2/led.html
192.168.0.2/temperature.html
192.168.0.2/blabla.html
시리얼 모니터에서 얻은 IP 주소로 192.168.0.2를 변경해야 한다는 점을 유의해 주세요.
다음과 같은 페이지를 볼 수 있습니다: 홈 페이지, LED 페이지, 온도 페이지, 찾을 수 없는 페이지
시리얼 모니터에서 출력도 확인할 수 있습니다.
Connecting to WiFi...
Connected to WiFi
Arduino Nano ESP32 Web Server's IP address: 192.168.0.2
Arduino Nano ESP32 Web server started
Web Server: home page
Web Server: LED page
Web Server: LED page => turning LED to on
Web Server: LED page => turning LED to off
Web Server: temperature page
Web Server: Not Found
이전 코드에는 각 페이지마다 매우 간단한 HTML 내용이 있습니다. 하지만 많은 HTML을 가진 화려한 인터페이스를 만들고 싶다면 코드가 클 수 있고 지저분해질 수 있습니다. 이를 더 단순하게 만들기 위해, 아두이노 나노 ESP32 코드에서 HTML을 분리하는 방법을 배울 것입니다. 이를 통해 HTML을 별도의 파일로 유지할 수 있게 되어, 관리하기가 쉬워지고 작업하기가 편해집니다.
#include <WiFi.h>
#include <ESPAsyncWebServer.h>
#include "index.h"
#include "temperature.h"
#include "led.h"
#include "error_404.h"
#include "error_405.h"
#define LED_PIN D5
const char *ssid = "YOUR_WIFI_SSID";
const char *password = "YOUR_WIFI_PASSWORD";
AsyncWebServer server(80);
int LED_state = LOW;
float getTemperature() {
float temp_x100 = random(0, 10000);
return temp_x100 / 100;
}
void setup() {
Serial.begin(9600);
pinMode(LED_PIN, OUTPUT);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(1000);
Serial.println("Wi-Fi에 연결 중...");
}
Serial.println("Wi-Fi에 연결됨");
Serial.print("Arduino Nano ESP32 웹 서버의 IP 주소: ");
Serial.println(WiFi.localIP());
server.on("/", HTTP_GET, [](AsyncWebServerRequest *request) {
Serial.println("웹 서버: 홈페이지");
String html = HTML_CONTENT_HOME;
request->send(200, "text/html", html);
});
server.on("/temperature.html", HTTP_GET, [](AsyncWebServerRequest *request) {
Serial.println("웹 서버: 온도 페이지");
String html = HTML_CONTENT_TEMPERATURE;
float temperature = getTemperature();
html.replace("%TEMPERATURE_VALUE%", String(temperature));
request->send(200, "text/html", html);
});
server.on("/led.html", HTTP_GET, [](AsyncWebServerRequest *request) {
Serial.print("웹 서버: LED 페이지");
if (request->hasArg("state")) {
String state = request->arg("state");
if (state == "on") {
LED_state = HIGH;
} else if (state == "off") {
LED_state = LOW;
}
digitalWrite(LED_PIN, LED_state);
Serial.print(" => turning LED to ");
Serial.print(state);
}
Serial.println();
String html = HTML_CONTENT_LED;
html.replace("%LED_STATE%", LED_state ? "ON" : "OFF");
request->send(200, "text/html", html);
});
server.onNotFound([](AsyncWebServerRequest *request) {
if (request->method() == HTTP_GET) {
Serial.println("웹 서버: 찾을 수 없음");
String html = HTML_CONTENT_404;
request->send(404, "text/html", html);
} else {
Serial.println("웹 서버: 허용되지 않는 방법");
String html = HTML_CONTENT_405;
request->send(405, "text/html", html);
}
});
server.begin();
Serial.println("Arduino Nano ESP32 웹 서버 시작됨");
}
void loop() {
}
코드에서 WiFi 정보(SSID 및 비밀번호)를 변경하세요
Arduino IDE에서 index.h 파일 생성하기:
파일 이름을 index.h로 지정하고 OK 버튼을 클릭하세요.
아래 코드를 복사하여 index.h 파일에 붙여넣으세요.
const char *HTML_CONTENT_HOME = R"=====(
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="icon" href="data:,">
<title>Home Page</title>
</head>
<body>
<h1>Welcome to the Home Page</h1>
<ul>
<li><a href="/led.html">LED Page</a></li>
<li><a href="/temperature.html">Temperature Page</a></li>
</ul>
</body>
</html>
)=====";
마찬가지로, 아래 내용을 포함하는 led.h 파일을 Arduino IDE에서 생성하세요.
const char *HTML_CONTENT_LED = R"=====(
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="icon" href="data:,">
<title>LED Page</title>
</head>
<body>
<h1>LED Page</h1>
<p>LED State: <span style="color: red;">%LED_STATE%</span></p>
<a href='/led.html?state=on'>Turn ON</a>
<br><br>
<a href='/led.html?state=off'>Turn OFF</a>
</body>
</html>
)=====";
const char *HTML_CONTENT_TEMPERATURE = R"=====(
<!DOCTYPE html>
<html>
<head>
<title>Arduino Nano ESP32 - Web Temperature</title>
<meta name="viewport" content="width=device-width, initial-scale=0.7, maximum-scale=0.7">
<meta charset="utf-8">
<link rel="icon" href="https://diyables.io/images/page/diyables.svg">
<style>
body { font-family: "Georgia"; text-align: center; font-size: width/2pt;}
h1 { font-weight: bold; font-size: width/2pt;}
h2 { font-weight: bold; font-size: width/2pt;}
button { font-weight: bold; font-size: width/2pt;}
</style>
<script>
var cvs_width = 200, cvs_height = 450;
function init() {
var canvas = document.getElementById("cvs");
canvas.width = cvs_width;
canvas.height = cvs_height + 50;
var ctx = canvas.getContext("2d");
ctx.translate(cvs_width/2, cvs_height - 80);
update_view(%TEMPERATURE_VALUE%);
}
function update_view(temp) {
var canvas = document.getElementById("cvs");
var ctx = canvas.getContext("2d");
var radius = 70;
var offset = 5;
var width = 45;
var height = 330;
ctx.clearRect(-cvs_width/2, -350, cvs_width, cvs_height);
ctx.strokeStyle="blue";
ctx.fillStyle="blue";
var x = -width/2;
ctx.lineWidth=2;
for (var i = 0; i <= 100; i+=5) {
var y = -(height - radius)*i/100 - radius - 5;
ctx.beginPath();
ctx.lineTo(x, y);
ctx.lineTo(x - 20, y);
ctx.stroke();
}
ctx.lineWidth=5;
for (var i = 0; i <= 100; i+=20) {
var y = -(height - radius)*i/100 - radius - 5;
ctx.beginPath();
ctx.lineTo(x, y);
ctx.lineTo(x - 25, y);
ctx.stroke();
ctx.font="20px Georgia";
ctx.textBaseline="middle";
ctx.textAlign="right";
ctx.fillText(i.toString(), x - 35, y);
}
ctx.lineWidth=16;
ctx.beginPath();
ctx.arc(0, 0, radius, 0, 2 * Math.PI);
ctx.stroke();
ctx.beginPath();
ctx.rect(-width/2, -height, width, height);
ctx.stroke();
ctx.beginPath();
ctx.arc(0, -height, width/2, 0, 2 * Math.PI);
ctx.stroke();
ctx.fillStyle="#e6e6ff";
ctx.beginPath();
ctx.arc(0, 0, radius, 0, 2 * Math.PI);
ctx.fill();
ctx.beginPath();
ctx.rect(-width/2, -height, width, height);
ctx.fill();
ctx.beginPath();
ctx.arc(0, -height, width/2, 0, 2 * Math.PI);
ctx.fill();
ctx.fillStyle="#ff1a1a";
ctx.beginPath();
ctx.arc(0, 0, radius - offset, 0, 2 * Math.PI);
ctx.fill();
temp = Math.round(temp * 100) / 100;
var y = (height - radius)*temp/100.0 + radius + 5;
ctx.beginPath();
ctx.rect(-width/2 + offset, -y, width - 2*offset, y);
ctx.fill();
ctx.fillStyle="red";
ctx.font="bold 34px Georgia";
ctx.textBaseline="middle";
ctx.textAlign="center";
ctx.fillText(temp.toString() + "°C", 0, 100);
}
window.onload = init;
</script>
</head>
<body>
<h1>Arduino Nano ESP32 - Web Temperature</h1>
<canvas id="cvs"></canvas>
</body>
</html>
)=====";
마찬가지로, 다음 내용을 가진 error_404.h 파일을 Arduino IDE에서 생성하세요.
const char *HTML_CONTENT_404 = R"=====(
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="icon" href="data:,">
<title>404 - Page Not Found</title>
<style>
h1 {color: #ff4040;}
</style>
</head>
<body>
<h1>404</h1>
<p>Oops! The page you are looking for could not be found on Esp32 Web Server.</p>
<p>Please check the URL or go back to the <a href="/">homepage</a>.</p>
<p>Or check <a href="https://esp32io.com/tutorials/esp32-web-server-multiple-pages"> Esp32 Web Server</a> tutorial.</p>
</body>
</html>
)=====";
마찬가지로, 아래의 내용을 가진 error_405.h 파일을 Arduino IDE에 만드십시오.
const char *HTML_CONTENT_405 = R"=====(
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="icon" href="data:,">
<title>405 - Method Not Allowed</title>
<style>
h1 {color: #ff4040;}
</style>
</head>
<body>
<h1>405 - Method Not Allowed</h1>
<p>Oops! The requested method is not allowed for this resource.</p>
<p>Please check your request or go back to the <a href="/">homepage</a>.</p>
<p>Or check <a href="https://esp32io.com/tutorials/esp32-web-server-multiple-pages"> Esp32 Web Server</a> tutorial.</p>
</body>
</html>
)=====";
이제 다음과 같이 아두이노 IDE에 여러 파일이 있습니다: