아두이노 - 웹소켓 | Arduino - WebSocket

이 가이드에서는 WebSocket이 무엇인지, Arduino 제어에 효과적인 이유는 무엇인지, 그리고 Arduino와 WebSocket을 어떻게 구현하는지에 대해 알아보겠습니다. 실습 예제를 통해 웹 브라우저와 Arduino를 연결하는 채팅 응용 프로그램을 구축하는 방법을 보여드리겠습니다. 이를 통해 여러분이 할 수 있게 됩니다:

Arduino websocket

준비물

1×Arduino UNO R4 WiFi Amazon
1×USB Cable Type-C 쿠팡 | Amazon
1×(Optional) 9V Power Adapter for Arduino Amazon
1×(Recommended) Screw Terminal Block Shield for Arduino Uno 쿠팡 | Amazon
1×(Optional) Transparent Acrylic Enclosure For Arduino Uno Amazon
공개: 이 섹션에서 제공된 링크 중 일부는 제휴 링크입니다. 이 링크를 통해 구매한 경우 추가 비용없이 수수료를 받을 수 있습니다. 지원해 주셔서 감사합니다.

아두이노 웹소켓이란 무엇인가요?

당신은 아마도 "WebSocket이 무엇인가?"라고 궁금해할 수 있습니다. 그것은 매우 단순합니다: WebSocket은 웹 브라우저가 실시간으로 웹 서버와 직접 통신할 수 있게 하는 기술입니다.

  • WebSocket이 없다면 새 업데이트를 보기 위해 웹페이지를 새로고침해야 합니다. 이는 별로 실용적이지 않습니다.
  • WebSocket을 사용하면 웹페이지가 서버와 지속적으로 연결됩니다. 이를 통해 페이지를 새로고침하지 않고도 즉시 정보를 교환할 수 있습니다.

당신은 온라인 게임, 인스턴트 메시징, 주식 시장 업데이트와 같은 일상적인 웹 응용 프로그램에서 정기적으로 WebSocket 기술을 접하게 될 것입니다.

우리가 아두이노를 원활하게 제어하기 위해 WebSocket이 필요한 이유는 무엇일까요?

상상해보세요, 여러분이 휴대폰이나 컴퓨터의 웹 인터페이스를 사용하여 원격 조종 자동차를 조종하고 싶습니다. WebSocket이 없다면, 차의 방향이나 속도를 변경할 때마다 웹 페이지를 새로고침해야 합니다. 마치 차에 명령을 내릴 때마다 "새로고침" 버튼을 눌러야 하는 것과 같습니다.

WebSocket을 사용하면, 마치 휴대폰이나 컴퓨터와 차량이 계속해서 직접 연결되어 있는 것처럼 됩니다. 차를 조종하거나 속도를 변경하기 위해 페이지를 새로고침할 필요가 없습니다. 페이지를 다시 로드해야 하는 지연 없이 차량이 실시간으로 꾸준히 사용자의 명령을 듣는 것처럼 됩니다.

전반적으로 WebSocket은 다음을 용이하게 합니다:

  • 웹 브라우저에서 웹페이지를 새로고침할 필요 없이 아두이노로 데이터를 보내는 방법.
  • 페이지를 새로고침하지 않고 아두이노에서 웹 브라우저로 데이터를 되돌려 보내는 방법.

이것은 실시간으로 원활한 양방향 통신을 가능하게 합니다.

아두이노에서 WebSocket의 장점:

  • 실시간 제어: WebSocket을 이용하면 아두이노와 즉각적으로 통신할 수 있어 명령에 대한 빠른 응답을 보장하고, 사용자 경험을 원활하게 합니다.
  • 지속적 연결: 제어 페이지를 새로고침할 필요 없이 지속적인 연결을 유지하여 즉시 지시를 위한 항상 준비된 통신 라인을 생성합니다.
  • 효율성: 페이지를 지속적으로 새로고침할 필요 없이 신속한 응답을 경험함으로써 전반적인 사용자 즐거움 및 효율성을 향상시킵니다.

웹소켓을 통한 아두이노와의 웹 채팅

웹페이지의 콘텐츠(HTML, CSS, JavaScript)는 index.h 파일에 별도로 저장되어 있습니다. 그러므로 우리는 Arduino IDE에 두 개의 코드 파일을 가지게 될 것입니다:

  • 아두이노 코드인 .ino 파일은 웹 서버 및 웹소켓 서버를 생성합니다.
  • 웹 페이지의 내용을 담고 있는 .h 파일입니다.

사용 방법

  • 아두이노 우노 R4를 처음 사용하는 경우, 아두이노 우노 R4 환경 설정 방법을 참조하세요.
  • 아두이노 보드를 PC에 마이크로 USB 케이블을 통해 연결하세요.
  • PC에서 아두이노 IDE를 엽니다.
  • 올바른 아두이노 보드(아두이노 우노 R4 WiFi)와 COM 포트를 선택하세요.
  • 아두이노 IDE의 왼쪽 내비게이션 바에 있는 Library Manager 아이콘을 클릭하여 라이브러리 관리자를 엽니다.
  • “mWebSockets”을 검색한 다음, Dawid Kurek이 만든 mWebSockets를 찾습니다.
  • Install 버튼을 클릭하여 mWebSockets 라이브러리를 설치하세요.
Arduino mWebSockets library
  • Arduino IDE에서 새 스케치를 만들고 이름을 지정하세요. 예를 들어, ArduinoGetStarted.com.ino
  • 아래 코드를 복사하고 Arduino IDE로 열어보세요.
/* * 이 Arduino 코드는 newbiely.kr 에서 개발되었습니다 * 이 Arduino 코드는 어떠한 제한 없이 공개 사용을 위해 제공됩니다. * 상세한 지침 및 연결도에 대해서는 다음을 방문하세요: * https://newbiely.kr/tutorials/arduino/arduino-websocket */ #include <WiFiS3.h> #include <WebSocketServer.h> #include "index.h" using namespace net; WebSocketServer wss(81); WiFiServer server(80); const char ssid[] = "YOUR_WIFI_SSID"; // change your network SSID const char pass[] = "YOUR_WIFI_PASSWORD"; // change your network password int status = WL_IDLE_STATUS; void setup() { //Initialize serial and wait for port to open: Serial.begin(9600); String fv = WiFi.firmwareVersion(); if (fv < WIFI_FIRMWARE_LATEST_VERSION) Serial.println("Please upgrade the firmware"); // attempt to connect to WiFi network: while (status != WL_CONNECTED) { Serial.print("Attempting to connect to SSID: "); Serial.println(ssid); // Connect to WPA/WPA2 network. Change this line if using open or WEP network: status = WiFi.begin(ssid, pass); // wait 4 seconds for connection: delay(4000); } // print your board's IP address: 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(); // listen for incoming clients WiFiClient client = server.available(); if (client) { // read the HTTP request header line by line while (client.connected()) { if (client.available()) { String HTTP_header = client.readStringUntil('\n'); // read the header line of HTTP request if (HTTP_header.equals("\r")) // the end of HTTP request break; Serial.print("<< "); Serial.println(HTTP_header); // print HTTP request to Serial Monitor } } // send the HTTP response header client.println("HTTP/1.1 200 OK"); client.println("Content-Type: text/html"); client.println("Connection: close"); // the connection will be closed after completion of the response client.println(); // the separator between HTTP header and body String html = String(HTML_CONTENT); client.println(html); client.flush(); // give the web browser time to receive the data delay(50); // close the connection: client.stop(); } }
  • 코드 내의 WiFi 정보(SSID 및 비밀번호)를 자신의 네트워크 자격 증명과 일치하도록 수정하세요.
  • Arduino IDE에서 index.h 파일을 작성하려면:
    • 시리얼 모니터 아이콘 바로 아래에 있는 버튼을 클릭하고 새 탭을 선택하거나, Ctrl+Shift+N 키를 사용하세요.
    Arduino IDE 2 adds file

    파일의 이름을 index.h로 지정하고 OK 버튼을 클릭하세요.

    Arduino IDE 2 adds file index.h

    아래의 코드를 복사하여 index.h에 붙여넣으세요.

    /* * 이 Arduino 코드는 newbiely.kr 에서 개발되었습니다 * 이 Arduino 코드는 어떠한 제한 없이 공개 사용을 위해 제공됩니다. * 상세한 지침 및 연결도에 대해서는 다음을 방문하세요: * https://newbiely.kr/tutorials/arduino/arduino-websocket */ const char *HTML_CONTENT = R"=====( <!DOCTYPE html> <html> <head> <title>Arduino 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> /* Add some basic styling for the chat window */ 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; /* bigger length causes uart0 buffer overflow with low speed smart device */ 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>'); // You can send the message to the server or process it as needed } } } function connect_onclick() { if(ws == null) { ws = new WebSocket("ws://" + window.location.host + ":81"); 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; // MessageEvent console.log(e_msg.data); update_text('<p class="message-received">' + e_msg.data + '</p>'); } </script> </head> <body> <div class="chat-container"> <h2>Arduino 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> )=====";
    • 이제 코드를 두 파일에 가지고 있습니다: ArduinoGetStarted.com.inoindex.h
    • 아두이노 IDE에서 Upload 버튼을 클릭하여 아두이노에 코드를 업로드하세요.

    아래와 같은 오류를 보게 될 것입니다:

    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\ArduinoGetStarted.com\ArduinoGetStarted.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\YOU_ACCOUNT\Documents\Arduino\libraries\mWebSockets\src\ 디렉토리로 이동하세요.
    • Config.h 파일을 찾아 텍스트 에디터로 열어주세요.
    • 26번째 줄을 살펴보세요, 아래와 같이 보일 것입니다:
    #define NETWORK_CONTROLLER ETHERNET_CONTROLLER_W5X00

    아래와 같이 이 줄을 변경하고 저장하세요:

    #define NETWORK_CONTROLLER NETWORK_CONTROLLER_WIFI
    • 아두이노 IDE에서 Upload 버튼을 클릭하여 아두이노에 코드를 업로드하세요.
    • 시리얼 모니터를 엽니다.
    • 시리얼 모니터에서 결과를 확인하세요.
    COM6
    Send
    Connecting to WiFi... Connected to WiFi Arduino Web Server's IP address IP address: 192.168.0.2
    Autoscroll Show timestamp
    Clear output
    9600 baud  
    Newline  
    • 표시된 IP 주소를 확인하고 이 주소를 스마트폰 또는 PC의 웹 브라우저 주소 창에 입력하세요.
    • 아래와 같은 웹페이지를 볼 수 있습니다:
    Arduino websocket web browser
    • WebSocket을 통해 웹페이지를 Arduino에 연결하려면 CONNECT 버튼을 클릭하세요.
    • 몇 가지 단어를 입력하고 Arduino에 전송하세요.
    • Arduino로부터의 응답을 볼 수 있습니다.
    Arduino websocket chat server

    ※ NOTE THAT:

    • index.h 파일의 HTML 내용을 수정하고 ArduinoGetStarted.com.ino 파일은 건드리지 않으면, Arduino에 코드를 컴파일하고 업로드할 때 Arduino IDE가 HTML 내용을 업데이트하지 않습니다.
    • 이 경우에 Arduino IDE가 HTML 내용을 업데이트하게 하려면, ArduinoGetStarted.com.ino 파일에 변경을 가하십시오 (예: 빈 줄 추가, 주석 추가 등).

    코드 설명 줄별로

    위의 아두이노 코드에는 줄별 설명이 포함되어 있습니다. 코드의 주석을 읽어주세요!

시스템 작동 방식

아두이노 코드는 웹 서버와 웹소켓 서버를 설정하여 작동합니다. 작동 방식은 다음과 같습니다:

  • 웹 브라우저에 아두이노의 IP 주소를 입력하면, 웹 브라우저는 아두이노에서 웹페이지(사용자 인터페이스)를 요청합니다.
  • 그러면 아두이노의 웹 서버가 웹페이지의 내용(HTML, CSS, JavaScript)을 브라우저로 전송합니다.
  • 웹 브라우저가 웹페이지를 표시합니다.
  • 웹페이지에서 CONNECT 버튼을 클릭하면 페이지 내의 JavaScript 코드가 아두이노의 WebSocket 서버와의 WebSocket 연결을 시작합니다.
  • WebSocket 연결이 활성화된 후, 무엇인가를 입력하고 SEND 버튼을 누르면, JavaScript가 배경에서 WebSocket 연결을 통해 텍스트를 아두이노로 전송합니다.
  • 입력을 받은 후, 아두이노의 WebSocket 서버는 웹페이지로 응답을 다시 보냅니다.

아래에서 다른 아두이노 웹소켓 예제들을 배울 수 있습니다:

※ OUR MESSAGES

  • Please feel free to share the link of this tutorial. However, Please do not use our content on any other websites. We invested a lot of effort and time to create the content, please respect our work!