아두이노 우노 R4 - 웹소켓
이 안내서는 WebSocket이 무엇인지, Arduino UNO R4를 사용하는 데 왜 도움이 되는지, 그리고 Arduino UNO R4와 함께 WebSocket을 사용하는 방법을 설명합니다. 웹 브라우저가 Arduino UNO R4와 통신할 수 있는 채팅 애플리케이션을 만드는 방법을 보여드리겠습니다. 이를 통해 다음과 같은 기능을 수행할 수 있습니다:
1 | × | Arduino UNO R4 WiFi | Amazon | |
1 | × | USB Cable Type-C | 쿠팡 | Amazon | |
1 | × | (Recommended) Screw Terminal Block Shield for Arduino UNO R4 | 쿠팡 | Amazon | |
1 | × | (Recommended) Breadboard Shield For Arduino UNO R4 | 쿠팡 | Amazon | |
1 | × | (Recommended) Enclosure For Arduino UNO R4 | Amazon | |
1 | × | (Recommended) Power Splitter For Arduino UNO R4 | Amazon | |
공개: 이 섹션에서 제공된 링크 중 일부는 제휴 링크입니다. 이 링크를 통해 구매한 경우 추가 비용없이 수수료를 받을 수 있습니다. 지원해 주셔서 감사합니다.
"웹소켓이란 무엇인가요?"라고 물으실 수 있습니다. 간단히 말해, 웹소켓은 웹 브라우저가 웹 서버와 즉시 직접 대화할 수 있도록 하는 기술입니다.
온라인 게임, 인스턴트 메시징, 주식 시장 업데이트와 같은 일상적인 웹 애플리케이션에서 WebSocket 기술을 자주 사용합니다.
스마트폰이나 컴퓨터의 웹 브라우저를 사용하여 원격 조종 자동차를 제어하고 싶다고 가정해 보세요. WebSocket을 사용하지 않으면, 자동차의 방향이나 속도를 변경할 때마다 웹 페이지를 새로고침해야 할 것입니다. 이는 자동차에 명령을 내릴 때마다 "새로고침" 버튼을 누르는 것과 유사합니다.
웹소켓은 웹 브라우저와 자동차 간의 지속적이고 직접적인 연결을 허용합니다. 페이지를 새로고침할 필요 없이 자동차의 방향과 속도를 제어할 수 있습니다. 마치 페이지를 다시 로드하는 데 지연이 없이 자동차가 실시간으로 명령에 즉시 반응하는 것과 같습니다.
WebSocket을 사용하면 다음이 더 쉬워집니다:
이를 통해 실시간으로 원활한 대화를 주고받을 수 있습니다.
실시간 제어: WebSocket은 Arduino UNO R4와의 즉각적인 상호작용을 가능하게 하여 명령에 빠른 응답을 제공함으로써 원활한 경험을 제공합니다.
지속적인 연결: 제어 페이지를 새로 고칠 필요 없이 항상 직접적인 지시를 처리할 준비가 된 통신 라인을 유지합니다.
효율성: 페이지를 반복적으로 다시 로드할 필요 없이 빠른 응답과 더 나은 경험을 즐길 수 있어 더욱 효율적이고 즐겁습니다.
웹페이지의 자료들인 HTML, CSS, 그리고 JavaScript는 index.h라는 별도의 파일에 저장됩니다. 그렇기 때문에 Arduino IDE에서는 두 개의 코드 파일을 사용하게 됩니다.
다음 지침을 단계별로 따르세요:
USB 케이블을 사용하여 Arduino Uno R4 보드를 컴퓨터에 연결합니다.
컴퓨터에서 Arduino IDE를 실행합니다.
적절한 Arduino Uno R4 보드(예: Arduino Uno R4 WiFi) 및 COM 포트를 선택합니다.
Arduino IDE의 왼쪽에 있는 Library Manager 아이콘을 클릭하여 라이브러리 관리자를 엽니다.
"mWebSockets"를 검색하고 Dawid Kurek의 mWebSockets를 찾습니다.
Install 버튼을 클릭하여 mWebSockets 라이브러리를 추가합니다.
#include <WiFiS3.h>
#include <WebSocketServer.h>
#include "index.h"
using namespace net;
WebSocketServer wss(81);
WiFiServer server(80);
const char ssid[] = "YOUR_WIFI_SSID";
const char pass[] = "YOUR_WIFI_PASSWORD";
int status = WL_IDLE_STATUS;
void setup() {
Serial.begin(9600);
String fv = WiFi.firmwareVersion();
if (fv < WIFI_FIRMWARE_LATEST_VERSION)
Serial.println("Please upgrade the firmware");
while (status != WL_CONNECTED) {
Serial.print("Attempting to connect to SSID: ");
Serial.println(ssid);
status = WiFi.begin(ssid, pass);
delay(4000);
}
Serial.print("IP Address: ");
Serial.println(WiFi.localIP());
server.begin();
wss.onConnection([](WebSocket &ws) {
const auto protocol = ws.getProtocol();
if (protocol) {
Serial.print(F("Client protocol: "));
Serial.println(protocol);
}
ws.onMessage([](WebSocket &ws, const WebSocket::DataType dataType,
const char *message, uint16_t length) {
switch (dataType) {
case WebSocket::DataType::TEXT:
Serial.print(F("Received: "));
Serial.println(message);
break;
case WebSocket::DataType::BINARY:
Serial.println(F("Received binary data"));
break;
}
String reply = "Received: " + String((char *)message);
ws.send(dataType, reply.c_str(), reply.length());
});
ws.onClose([](WebSocket &, const WebSocket::CloseCode, const char *,
uint16_t) {
Serial.println(F("Disconnected"));
});
Serial.print(F("New WebSocket Connnection from client: "));
Serial.println(ws.getRemoteIP());
const char message[]{ "Hello from Arduino server!" };
ws.send(WebSocket::DataType::TEXT, message, strlen(message));
});
wss.begin();
}
void loop() {
wss.listen();
WiFiClient 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("<< ");
Serial.println(HTTP_header);
}
}
client.println("HTTP/1.1 200 OK");
client.println("Content-Type: text/html");
client.println("Connection: close");
client.println();
String html = String(HTML_CONTENT);
client.println(html);
client.flush();
delay(50);
client.stop();
}
}
코드에서 WiFi 세부 정보(SSID 및 비밀번호)를 본인의 것으로 변경하세요.
Arduino IDE에서 index.h 파일을 만들려면:
const char *HTML_CONTENT = R"=====(
<!DOCTYPE html>
<html>
<head>
<title>Arduino Uno R4 WebSocket</title>
<meta name="viewport" content="width=device-width, initial-scale=0.7, maximum-scale=0.7">
<link rel="icon" href="https://diyables.io/images/page/diyables.svg">
<style>
body {
background-color: #E1EFEF;
font-size: 20px;
line-height: 1.3;
}
button, input {
font-size: 20px;
line-height: 1.3;
}
.chat-container {
margin: 0 auto;
padding: 10px;
}
.chat-messages {
height: 250px;
overflow-y: auto;
padding: 5px;
margin-bottom: 5px;
}
.user-input {
display: flex;
margin-bottom: 20px;
}
.user-input input {
flex: 1;
border: 1px solid #444;
padding: 5px;
}
.user-input button {
margin-left: 5px;
background-color: #007bff;
color: #fff;
border: none;
padding: 5px 10px;
cursor: pointer;
}
.websocket {
display: flex;
align-items: center;
margin-bottom: 5px;
}
.websocket button {
background-color: #007bff;
color: #fff;
border: none;
padding: 5px 10px;
cursor: pointer;
}
.websocket .label {
margin-left: auto;
}
.message-sent {
border-radius: 25px;
background-color: #d35400;
float: right;
width: fit-content;
padding: 10px 20px;
margin: 0;
}
.message-received {
border-radius: 25px;
background-color: white;
float: left;
width: fit-content;
padding: 10px 20px;
margin: 0;
}
</style>
<script>
var ws;
var wsm_max_len = 4096;
function update_text(text) {
var chat_messages = document.getElementById("chat-messages");
chat_messages.innerHTML += '<div style="width:100%;overflow: auto;">' + text + '</div>';
chat_messages.scrollTop = chat_messages.scrollHeight;
}
function send_onclick() {
if(ws != null) {
var message = document.getElementById("message").value;
if (message) {
document.getElementById("message").value = "";
ws.send(message + "\n");
update_text('<p class="message-sent">' + message + '</p>');
}
}
}
function connect_onclick() {
if(ws == null) {
ws = new WebSocket("ws:
document.getElementById("ws_state").innerHTML = "CONNECTING";
ws.onopen = ws_onopen;
ws.onclose = ws_onclose;
ws.onmessage = ws_onmessage;
} else
ws.close();
}
function ws_onopen() {
document.getElementById("ws_state").innerHTML = "<span style='color:blue'>CONNECTED</span>";
document.getElementById("bt_connect").innerHTML = "Disconnect";
document.getElementById("chat-messages").innerHTML = "";
}
function ws_onclose() {
document.getElementById("ws_state").innerHTML = "<span style='color:gray'>CLOSED</span>";
document.getElementById("bt_connect").innerHTML = "Connect";
ws.onopen = null;
ws.onclose = null;
ws.onmessage = null;
ws = null;
}
function ws_onmessage(e_msg) {
e_msg = e_msg || window.event;
console.log(e_msg.data);
update_text('<p class="message-received">' + e_msg.data + '</p>');
}
</script>
</head>
<body>
<div class="chat-container">
<h2>Arduino Uno R4 WebSocket</h2>
<div class="websocket">
<button class="connect-button" id="bt_connect" onclick="connect_onclick()">Connect</button>
<span class="label">WebSocket: <span id="ws_state"><span style="color:blue">CLOSED</span></span></span>
</div>
<div class="chat-messages" id="chat-messages"></div>
<div class="user-input">
<input type="text" id="message" placeholder="Type your message...">
<button onclick="send_onclick()">Send</button>
</div>
<div class="sponsor">Sponsored by <a href="https://amazon.com/diyables">DIYables</a></div>
</div>
</body></html>
)=====";
다음과 같은 오류 메시지가 표시될 것입니다:
In file included from c:\Users\YOU_ACCOUNT\Documents\Arduino\libraries\mWebSockets\src/utility.h:3:0,
from c:\Users\YOU_ACCOUNT\Documents\Arduino\libraries\mWebSockets\src/WebSocket.h:5,
from c:\Users\YOU_ACCOUNT\Documents\Arduino\libraries\mWebSockets\src/WebSocketServer.h:5,
from C:\Users\YOU_ACCOUNT\Documents\Arduino\newbiely.com\newbiely.com.ino:2:
C:\Users\YOU_ACCOUNT\Documents\Arduino\libraries\mWebSockets\src/platform.h:54:12: fatal error: Ethernet.h: No such file or directory
# include <Ethernet.h>
^~~~~~~~~~~~
compilation terminated.
exit status 1
이 문제를 해결하기 위해:
C:\Users\YOUR_ACCOUNT\Documents\Arduino\libraries\mWebSockets\src/ 디렉토리로 이동합니다.
Config.h라는 파일을 찾아 텍스트 편집기로 엽니다.
26번째 줄로 이동하면 다음 내용을 볼 수 있습니다:
#define NETWORK_CONTROLLER ETHERNET_CONTROLLER_W5X00
#define NETWORK_CONTROLLER NETWORK_CONTROLLER_WIFI
Connecting to WiFi...
Connected to WiFi
Arduino UNO R4 Web Server's IP address IP address: 192.168.0.2
웹페이지를 Arduino UNO R4와 WebSocket으로 연결하려면 CONNECT 버튼을 누르세요.
텍스트를 입력하고 Arduino UNO R4로 보내세요.
Arduino UNO R4로부터의 응답을 확인하세요.
※ NOTE THAT:
index.h 파일에서 HTML만 변경하고 newbiely.com.ino 파일을 수정하지 않으면, Arduino IDE는 코드 컴파일 및 업로드 시 HTML을 업데이트하지 않습니다.
Arduino IDE를 통해 HTML 내용을 업데이트하려면, newbiely.com.ino 파일에 빈 줄이나 주석 추가와 같은 작은 변경을 해야 합니다.
위의 Arduino Uno R4 코드에 대한 자세한 설명은 코드에 있는 주석을 참조하세요.
Arduino UNO R4 코드는 웹 서버와 WebSocket 서버를 설정합니다. 작동 방식은 다음과 같습니다:
Arduino UNO R4의 IP 주소를 웹 브라우저에 입력합니다.
Arduino UNO R4의 웹 서버가 웹페이지(HTML, CSS, JavaScript로 구성)를 브라우저로 전송합니다.
브라우저가 웹페이지를 표시합니다.
웹페이지에서 CONNECT 버튼을 클릭합니다. 이 작업은 Arduino UNO R4의 서버와 WebSocket 연결을 시작합니다.
텍스트를 입력하고 SEND 버튼을 클릭하면 JavaScript가 WebSocket을 통해 Arduino UNO R4로 텍스트를 보냅니다.
Arduino UNO R4의 WebSocket 서버가 텍스트를 수신하고 웹페이지로 응답을 다시 보냅니다.
다음은 배울 수 있는 Arduino UNO R4 WebSocket의 다른 예제입니다:
위의 코드가 작동한다면, Arduino UNO R4의 WiFi 모듈의 최신 버전을 업데이트해 주세요.
Arduino Uno R4 WiFi 보드와 포트를 선택하세요
업데이트 확인 버튼을 클릭하세요
사용 가능한 펌웨어 버전 목록이 나타납니다
최신 펌웨어 버전을 선택하세요
Install 버튼을 클릭하세요
완료될 때까지 기다리세요
Arduino Uno R4 WiFi를 재부팅하세요
코드를 다시 컴파일하고 Arduino Uno R4 WiFi에 업로드하세요
결과를 확인하세요