아두이노 나노 웹 서버
이 가이드에서는 이더넷 모듈이 장착된 Arduino Nano 보드를 웹 서버로 프로그래밍하는 방법을 보여드립니다. 여러분은 컴퓨터나 스마트폰을 통해 접근 가능한 웹 페이지를 통해 데이터를 보고 Arduino Nano를 제어할 수 있습니다. 아래에 설명된 대로 간단한 작업부터 시작하여 보다 고급 작업으로 진행할 것입니다.
아두이노 나노 웹 서버 - 헬로 월드!
아두이노 나노 웹 서버 - 웹페이지를 통한 센서 값 모니터링.
아두이노 나노 웹 서버 - 웹페이지에서 값 자동 업데이트.
아두이노 나노 웹 서버 - 아두이노 코드에서 HTML, CSS, JavaScript 분리.
아두이노 나노 웹 서버 - 웹페이지를 통한 아두이노 나노 제어.
1 | × | Arduino Nano | Amazon | |
1 | × | USB A to Mini-B USB cable | 쿠팡 | Amazon | |
1 | × | W5500 Ethernet Module | 쿠팡 | Amazon | |
1 | × | Ethernet Cable | 쿠팡 | Amazon | |
1 | × | Jumper Wires | Amazon | |
1 | × | Breadboard | 쿠팡 | Amazon | |
1 | × | (추천) Screw Terminal Expansion Board for Arduino Nano | 쿠팡 | Amazon | |
1 | × | (추천) Breakout Expansion Board for Arduino Nano | Amazon | |
1 | × | (추천) Power Splitter For Arduino Nano | Amazon | |
공개: 이 섹션에서 제공된 링크 중 일부는 제휴 링크입니다. 이 링크를 통해 구매한 경우 추가 비용없이 수수료를 받을 수 있습니다. 지원해 주셔서 감사합니다.
이 이미지는 Fritzing을 사용하여 만들어졌습니다. 이미지를 확대하려면 클릭하세요.
image source: diyables.io
이것은 비교적 간단합니다. Arduino Nano 코드는 다음 작업을 수행합니다:
웹 브라우저로부터 HTTP 요청을 듣는 웹 서버 생성.
웹 브라우저로부터 요청을 받으면, Arduino Nano는 다음 정보를 제공합니다:
다음은 위의 작업을 수행하는 Arduino Nano 코드입니다:
#include <SPI.h>
#include <Ethernet.h>
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
IPAddress ip(192, 168, 1, 177);
EthernetServer server(80);
void setup() {
Serial.begin(9600);
if (Ethernet.begin(mac) == 0) {
Serial.println(F("Failed to configure Ethernet using DHCP"));
Ethernet.begin(mac, ip);
}
server.begin();
Serial.print(F("Arduino Nano Web Server's IP address: "));
Serial.println(Ethernet.localIP());
}
void loop() {
EthernetClient client = server.available();
if (client) {
while (client.connected()) {
if (client.available()) {
String HTTP_header = client.readStringUntil('\n');
if (HTTP_header.equals("\r"))
break;
Serial.print(F("<< "));
Serial.println(HTTP_header);
}
}
client.println(F("HTTP/1.1 200 OK"));
client.println(F("Content-Type: text/html"));
client.println(F("Connection: close"));
client.println();
client.println(F("<!DOCTYPE HTML>"));
client.println(F("<html>"));
client.println(F("<head>"));
client.println(F("<link rel=\"icon\" href=\"data:,\">"));
client.println(F("</head>"));
client.println(F("<p>"));
client.println(F("Hello World!"));
client.println(F("</p>"));
client.println(F("</html>"));
client.flush();
delay(10);
client.stop();
}
}
위의 배선도에 따라 Arduino Nano를 이더넷 모듈에 연결하세요.
이더넷 모듈에 이더넷 케이블을 연결하세요.
Arduino Nano를 USB 케이블을 사용하여 PC에 연결하세요.
PC에서 Arduino IDE를 실행하세요.
Arduino Nano 보드와 해당하는 COM 포트를 선택하세요.
Arduino IDE 왼쪽 바에서 Libraries 아이콘을 클릭하세요.
“Ethernet”를 검색한 후 Various에서 제공하는 Ethernet 라이브러리를 찾으세요.
Install 버튼을 클릭하여 Ethernet 라이브러리를 설치하세요.
Arduino Nano Web Server's IP address: 192.168.0.3
Arduino Nano Web Server's IP address: 192.168.0.3
<< GET / HTTP/1.1
<< Host: 192.168.0.3
<< Connection: keep-alive
<< Upgrade-Insecure-Requests: 1
<< User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/129.0.0.0 Safari/537.36 Edg/129.0.0.0
<< Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7
<< Accept-Encoding: gzip, deflate
<< Accept-Language: en-US,en;q=0.9,ko;q=0.8
다음 Arduino Nano 코드는 다음 작업을 수행합니다:
웹 브라우저에서 오는 HTTP 요청을 수신하는 웹 서버 만들기.
웹 브라우저로부터 요청을 받으면, Arduino Nano는 다음 정보를 포함하여 응답합니다:
#include <SPI.h>
#include <Ethernet.h>
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
IPAddress ip(192, 168, 1, 177);
EthernetServer server(80);
float getTemperature() {
float temp_x100 = random(0, 10000);
return temp_x100 / 100;
}
void setup() {
Serial.begin(9600);
if (Ethernet.begin(mac) == 0) {
Serial.println(F("Failed to configure Ethernet using DHCP"));
Ethernet.begin(mac, ip);
}
server.begin();
Serial.print(F("Server is at: "));
Serial.println(Ethernet.localIP());
}
void loop() {
EthernetClient client = server.available();
if (client) {
while (client.connected()) {
if (client.available()) {
String HTTP_header = client.readStringUntil('\n');
if (HTTP_header.equals("\r"))
break;
Serial.print(F("<< "));
Serial.println(HTTP_header);
}
}
client.println(F("HTTP/1.1 200 OK"));
client.println(F("Content-Type: text/html"));
client.println(F("Connection: close"));
client.println();
client.println(F("<!DOCTYPE HTML>"));
client.println(F("<html>"));
client.println(F("<head>"));
client.println(F("<link rel=\"icon\" href=\"data:,\">"));
client.println(F("</head>"));
client.println(F("<p>"));
client.print(F("Temperature: <span style=\"color: red;\">"));
float temperature = getTemperature();
client.print(temperature, 2);
client.println(F("°C</span>"));
client.println(F("</p>"));
client.println(F("</html>"));
client.flush();
delay(10);
client.stop();
}
}
위의 코드를 복사하여 Arduino IDE에서 엽니다.
Arduino IDE에서 Upload 버튼을 클릭하여 코드를 Arduino Nano에 업로드합니다.
이전 웹 페이지를 다시 로드(Ctrl + F5)하면 아래와 같이 표시됩니다:
제공된 코드로 온도를 업데이트하려면 웹 브라우저에서 페이지를 새로 고쳐야 합니다. 다음 섹션에서는 페이지를 새로 고침하지 않고 백그라운드에서 온도 값을 자동으로 업데이트하는 방법을 배워보겠습니다.
사용자가 웹 브라우저에 Arduino Nano의 IP 주소를 입력합니다.
웹 브라우저는 Arduino Nano의 홈페이지(/)로 HTTP 요청을 보냅니다.
Arduino는 HTML, CSS, JavaScript로 응답합니다.
웹 브라우저는 수신한 HTML과 CSS를 사용하여 웹페이지를 표시합니다.
매 3초마다 웹 브라우저는 JavaScript 코드를 실행하여 /temperature 엔드포인트에 HTTP 요청을 보냅니다.
Arduino는 센서 값을 읽고 응답으로 전송합니다.
웹 브라우저는 센서 값을 수신하고 웹페이지를 적절히 업데이트합니다.
다음은 위의 작업을 수행하는 Arduino Nano 코드입니다:
#include <SPI.h>
#include <Ethernet.h>
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
IPAddress ip(192, 168, 1, 177);
EthernetServer server(80);
const char* HTML_CONTENT = R"=====(
<!DOCTYPE html>
<html>
<head>
<title>Arduino Nano Temperature</title>
</head>
<body>
<h1>Arduino Nano Temperature</h1>
<p>Temperature: <span style="color: red;"><span id="temperature">Loading...</span> ℃</span></p>
<script>
function fetchTemperature() {
fetch("/temperature")
.then(response => response.text())
.then(data => {
document.getElementById("temperature").textContent = data;
});
}
fetchTemperature();
setInterval(fetchTemperature, 3000);
</script>
</body>
</html>
)=====";
float getTemperature() {
float temp_x100 = random(0, 10000);
return temp_x100 / 100;
}
void setup() {
Serial.begin(9600);
if (Ethernet.begin(mac) == 0) {
Serial.println(F("Failed to configure Ethernet using DHCP"));
Ethernet.begin(mac, ip);
}
server.begin();
Serial.print(F("Arduino Nano Web Server's IP address: "));
Serial.println(Ethernet.localIP());
}
void loop() {
EthernetClient client = server.available();
if (client) {
Serial.println(F("Client connected"));
while (client.connected()) {
if (client.available()) {
String request = client.readStringUntil('\r');
Serial.print(F("Request: "));
Serial.println(request);
client.flush();
if (request.indexOf("GET / ") >= 0) {
client.println(F("HTTP/1.1 200 OK"));
client.println(F("Content-Type: text/html"));
client.println(F("Connection: close"));
client.println();
client.println(HTML_CONTENT);
}
else if (request.indexOf("GET /temperature") >= 0) {
float temperature = getTemperature();
client.println(F("HTTP/1.1 200 OK"));
client.println(F("Content-Type: text/plain"));
client.println(F("Connection: close"));
client.println();
client.print(temperature, 2);
}
client.stop();
Serial.println(F("Client disconnected"));
}
}
}
}
위 코드를 복사하여 Arduino IDE에서 엽니다.
Arduino IDE에서 Upload 버튼을 클릭하여 코드를 Arduino Nano에 업로드합니다.
이전 웹 페이지를 다시 로드하십시오(Ctrl + F5), 그러면 아래와 같이 표시됩니다:
값이 3초마다 자동으로 업데이트되는 것을 볼 수 있습니다.
간단한 웹 페이지를 최소한의 콘텐츠로 만들고 싶다면, 이전에 설명한 것처럼 HTML을 Arduino Nano 코드에 직접 삽입할 수 있습니다.
그러나, 보다 복잡하고 기능이 풍부한 웹 페이지의 경우, 모든 HTML, CSS, 그리고 JavaScript를 Arduino Nano 코드에 직접 포함하는 것은 번거로울 수 있습니다. 이러한 경우에는 코드를 관리하는 다른 방법을 사용하는 것이 더 좋습니다.
Arduino Nano 코드는 여전히 .ino 파일에 저장됩니다.
웹 페이지 콘텐츠(HTML, CSS, JavaScript)는 별도의 .h 파일에 넣을 것입니다. 이 분리는 Arduino 코드에 방해가 되지 않으면서 웹 페이지를 더 쉽게 관리하고 업데이트할 수 있게 합니다.
#include <SPI.h>
#include <Ethernet.h>
#include "index.h"
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
IPAddress ip(192, 168, 1, 177);
EthernetServer server(80);
float getTemperature() {
float temp_x100 = random(0, 10000);
return temp_x100 / 100;
}
void setup() {
Serial.begin(9600);
if (Ethernet.begin(mac) == 0) {
Serial.println(F("Failed to configure Ethernet using DHCP"));
Ethernet.begin(mac, ip);
}
server.begin();
Serial.print(F("Arduino Nano Web Server's IP address: "));
Serial.println(Ethernet.localIP());
}
void loop() {
EthernetClient client = server.available();
if (client) {
Serial.println(F("Client connected"));
while (client.connected()) {
if (client.available()) {
String request = client.readStringUntil('\r');
Serial.print(F("Request: "));
Serial.println(request);
client.flush();
if (request.indexOf("GET / ") >= 0) {
client.println(F("HTTP/1.1 200 OK"));
client.println(F("Content-Type: text/html"));
client.println(F("Connection: close"));
client.println();
client.println(HTML_CONTENT);
}
else if (request.indexOf("GET /temperature") >= 0) {
float temperature = getTemperature();
client.println(F("HTTP/1.1 200 OK"));
client.println(F("Content-Type: text/plain"));
client.println(F("Connection: close"));
client.println();
client.print(temperature, 2);
}
client.stop();
Serial.println(F("Client disconnected"));
}
}
}
}
#ifndef WEBPAGE_H
#define WEBPAGE_H
const char* HTML_CONTENT = R"=====(
<!DOCTYPE html>
<html>
<head>
<title>Arduino Nano Temperature</title>
</head>
<body>
<h1>Arduino Nano Temperature</h1>
<p>Temperature: <span style="color: red;"><span id="temperature">Loading...</span> ℃</span></p>
<script>
function fetchTemperature() {
fetch("/temperature")
.then(response => response.text())
.then(data => {
document.getElementById("temperature").textContent = data;
});
}
fetchTemperature();
setInterval(fetchTemperature, 3000);
</script>
</body>
</html>
)=====";
#endif
이제 두 파일에 코드가 있습니다: newbiely.com.ino 및 index.h
Arduino IDE에서 Upload 버튼을 클릭하여 코드를 Arduino Nano에 업로드합니다.
웹 페이지를 새로고침하세요(Ctrl + F5 사용). 그러면 이전과 동일하게 나타날 것입니다.
※ NOTE THAT:
index.h 파일의 HTML 콘텐츠를 변경하더라도 newbiely.com.ino 파일을 변경하지 않으면, Arduino IDE는 코드 컴파일 및 업로드 시 업데이트된 HTML 콘텐츠를 갱신하거나 포함하지 않습니다.
Arduino IDE가 HTML 콘텐츠를 업데이트하도록 하려면, newbiely.com.ino 파일에 빈 줄이나 주석 추가와 같은 사소한 변경을 해야 합니다. 이렇게 하면 IDE가 변경 사항을 감지하여 업데이트된 HTML 콘텐츠가 업로드에 포함되도록 보장합니다.
Arduino Nano에 연결된 것을 제어하는 것은 단지 값을 읽는 것보다 약간 더 어렵습니다. 이는 Arduino Nano가 웹 브라우저로부터 받은 요청을 이해해야 어떤 조치를 취할지 알 수 있기 때문입니다.
더 포괄적이고 상세한 예시를 원하신다면, 아래에 나열된 튜토리얼을 확인해 보시길 추천합니다.