아두이노 우노 R4 웹을 통한 컬러 센서

이 재미있는 프로젝트는 TCS3200D/TCS230 컬러 센서와 웹 기반 미니언 캐릭터를 결합합니다. Arduino UNO R4 WiFi가 센서에서 색상을 읽어 WebSocket을 통해 웹 브라우저로 감지된 색상을 전송합니다. 웹 페이지의 미니언은 센서 앞에 놓은 물체의 색상에 맞춰 피부색을 실시간으로 변경합니다! 웹 인터페이스 구축과 실시간 통신 처리를 쉽게 하기 위해 아두이노 맞춤형 웹앱 예제 - 초보자를 위한 간단한 웹 인터페이스 튜토리얼를 사용합니다.

이 튜토리얼 하단에서 단계별 동영상 설명도 제공합니다.

아두이노 우노 R4 tcs3200 tcs230 컬러 센서 웹 미니언

필요한 하드웨어

1×아두이노 우노 R4 와이파이 쿠팡 | 아마존
1×(또는) DIYables STEM V4 IoT 쿠팡 | 아마존
1×USB 케이블 타입-A to 타입-C (USB-A PC용) 쿠팡 | 아마존
1×USB 케이블 타입-C to 타입-C (USB-C PC용) 아마존
1×TCS3200D/TCS230 Color Recognition Sensor Module 아마존
1×점퍼케이블 쿠팡 | 아마존
1×(추천) 아두이노 우노 R4용 스크루 터미널 블록 쉴드 쿠팡 | 아마존
1×(추천) Sensors/Servo Expansion Shield for Arduino UNO R4 아마존
1×(추천) 아두이노 우노 R4용 브레드보드 쉴드 쿠팡 | 아마존
1×(추천) 아두이노 우노 R4용 케이스 쿠팡 | 아마존
1×(추천) 아두이노 우노 R4용 전원 분배기 쿠팡 | 아마존
1×(추천) 아두이노 우노용 프로토타이핑 베이스 플레이트 & 브레드보드 키트 아마존
공개: 이 포스팅 에 제공된 일부 링크는 아마존 제휴 링크입니다. 이 포스팅은 쿠팡 파트너스 활동의 일환으로, 이에 따른 일정액의 수수료를 제공받습니다.
Arduino Uno R4 WiFi Compatible Boards

TCS3200D/TCS230 컬러 센서 및 DIYables WebApps 소개

아래 튜토리얼에서 TCS3200D/TCS230 컬러 센서, DIYables WebApps 라이브러리, 그리고 커스텀 웹 앱 만드는 방법을 알아보세요:

배선도

이 이미지는 TCS3200 컬러 센서를 Arduino UNO R4 WiFi에 연결하는 방법을 보여줍니다:

TCS3200 컬러 센서Arduino UNO R4
VCC5V
GNDGND
S0핀 4
S1핀 3
S2핀 6
S3핀 5
OUT핀 7
아두이노 우노 R4와 tcs3200 컬러 센서 배선도 - 핀 연결 방법

이 이미지는 Fritzing을 사용하여 만들어졌습니다. 이미지를 확대하려면 클릭하세요.

Arduino Uno R4와 기타 부품에 전원을 공급하는 가장 효과적인 방법을 확인하시려면, 아래 링크를 참조하세요: 아두이노 우노 R4 전원 공급 방법.

작동 원리

  1. 아두이노가 1초마다 컬러 센서를 읽습니다.
  2. 각 읽기마다 S2/S3 핀을 사용하여 빨강, 초록, 파랑 필터를 순서대로 선택한 다음, OUT 핀에서 펄스 폭을 측정합니다.
  3. 원시 펄스 폭 값은 보정 값(아두이노 우노 R4 - TCS3200D/TCS230 컬러 센서 참조)을 사용하여 0-255 RGB 값으로 매핑됩니다.
  4. RGB 값은 HEX 색상 문자열(예: #FF8000)로 변환됩니다.
  5. HEX 색상 문자열은 DIYables WebApps 라이브러리를 사용하여 WebSocket을 통해 웹 브라우저로 전송됩니다.
  6. 웹 페이지가 색상을 받아 미니언의 몸통, 팔, 눈꺼풀을 실시간으로 해당 색상으로 업데이트합니다.

Arduino UNO R4 코드 - 컬러 센서 미니언 웹 앱

코드는 4개의 파일로 구성됩니다:

  • ColorSensor.ino - 메인 아두이노 스케치: 컬러 센서를 읽고 색상을 웹 페이지로 전송합니다
  • CustomWebApp.h - 헤더 파일: 커스텀 웹 앱 페이지 클래스를 정의합니다
  • CustomWebApp.cpp - 구현 파일: "Color Sensor:" 식별자를 사용하여 WebSocket 통신을 처리합니다
  • custom_page_html.h - 웹 페이지: 색상을 받아 미니언 피부색을 업데이트하는 애니메이션 미니언 HTML/CSS/JavaScript가 포함되어 있습니다

ColorSensor.ino

/* * 이 아두이노 우노 R4 코드는 newbiely.kr 에서 개발되었습니다 * 이 아두이노 우노 R4 코드는 어떠한 제한 없이 공개 사용을 위해 제공됩니다. * 상세한 지침 및 연결도에 대해서는 다음을 방문하세요: * https://newbiely.kr/tutorials/arduino-uno-r4/arduino-uno-r4-color-sensor-via-web */ #include <DIYablesWebApps.h> #include "CustomWebApp.h" // CHANGE THESE TO YOUR WIFI DETAILS const char WIFI_SSID[] = "YOUR_WIFI_SSID"; const char WIFI_PASSWORD[] = "YOUR_WIFI_PASSWORD"; int status = WL_IDLE_STATUS; // TCS3200 Pins const int S0 = 4, S1 = 3, S2 = 6, S3 = 5, sensorOut = 7; UnoR4ServerFactory serverFactory; DIYablesWebAppServer webAppsServer(serverFactory, 80, 81); DIYablesHomePage homePage; CustomWebAppPage customPage; unsigned long lastColorRead = 0; void setup() { Serial.begin(9600); // Initialize TCS3200 pins pinMode(S0, OUTPUT); pinMode(S1, OUTPUT); pinMode(S2, OUTPUT); pinMode(S3, OUTPUT); pinMode(sensorOut, INPUT); digitalWrite(S0, HIGH); digitalWrite(S1, LOW); // 20% frequency scaling webAppsServer.addApp(&homePage); webAppsServer.addApp(&customPage); // Check for the WiFi module if (WiFi.status() == WL_NO_MODULE) { Serial.println("Communication with WiFi module failed!"); // Stop program execution while (true); } 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) { // Connect to WPA/WPA2 network (change if using open or WEP) status = WiFi.begin(WIFI_SSID, WIFI_PASSWORD); // Wait 10 seconds for connection delay(10000); } webAppsServer.begin(); Serial.println("Color Web Server Ready!"); } void loop() { webAppsServer.loop(); // Read color every 1 second if (millis() - lastColorRead > 1000) { // Read Red color digitalWrite(S2, LOW); digitalWrite(S3, LOW); int r = map(pulseIn(sensorOut, LOW), 31, 150, 255, 0); // Read Green color digitalWrite(S2, HIGH); digitalWrite(S3, HIGH); int g = map(pulseIn(sensorOut, LOW), 35, 180, 255, 0); // Read Blue color digitalWrite(S2, LOW); digitalWrite(S3, HIGH); int b = map(pulseIn(sensorOut, LOW), 30, 150, 255, 0); // Convert to HEX and send to Web char hexColor[8]; sprintf(hexColor, "#%02X%02X%02X", constrain(r, 0, 255), constrain(g, 0, 255), constrain(b, 0, 255)); customPage.sendToWeb(String(hexColor)); Serial.println("Sent to Minion: " + String(hexColor)); lastColorRead = millis(); } }

CustomWebApp.h

/* * 이 아두이노 우노 R4 코드는 newbiely.kr 에서 개발되었습니다 * 이 아두이노 우노 R4 코드는 어떠한 제한 없이 공개 사용을 위해 제공됩니다. * 상세한 지침 및 연결도에 대해서는 다음을 방문하세요: * https://newbiely.kr/tutorials/arduino-uno-r4/arduino-uno-r4-color-sensor-via-web */ #ifndef CUSTOM_WEBAPP_H #define CUSTOM_WEBAPP_H #include <DIYablesWebApps.h> /** * Simple Custom WebApp Page * * This is a template for creating your own custom web applications. * It provides basic controls like buttons and sliders that communicate * with your Arduino in real-time. */ class CustomWebAppPage : public DIYablesWebAppPageBase { private: // WebSocket message identifier for this custom app static const String APP_IDENTIFIER; public: CustomWebAppPage(); // ======================================== // REQUIRED METHODS - USED BY LIBRARY - DON'T CHANGE THESE! // ======================================== void handleHTTPRequest(IWebClient& client) override; void handleWebSocketMessage(IWebSocket& ws, const char* message, uint16_t length) override; const char* getPageInfo() const override; String getNavigationInfo() const override; // ======================================== // YOUR METHODS - USE THESE IN YOUR CODE! // ======================================== void onCustomMessageReceived(void (*callback)(const String& payload)); void sendToWeb(const String& message); }; #endif

CustomWebApp.cpp

/* * 이 아두이노 우노 R4 코드는 newbiely.kr 에서 개발되었습니다 * 이 아두이노 우노 R4 코드는 어떠한 제한 없이 공개 사용을 위해 제공됩니다. * 상세한 지침 및 연결도에 대해서는 다음을 방문하세요: * https://newbiely.kr/tutorials/arduino-uno-r4/arduino-uno-r4-color-sensor-via-web */ #include "CustomWebApp.h" #include "custom_page_html.h" // Define the static member - WebSocket message identifier for this custom app const String CustomWebAppPage::APP_IDENTIFIER = "Color Sensor:"; // Callback function for handling messages from web browser void (*customMessageCallback)(const String& payload) = nullptr; CustomWebAppPage::CustomWebAppPage() : DIYablesWebAppPageBase("/custom") { } void CustomWebAppPage::handleHTTPRequest(IWebClient& client) { // Send the HTML page to web browser sendHTTPHeader(client); client.print(CUSTOM_PAGE_HTML); } void CustomWebAppPage::handleWebSocketMessage(IWebSocket& ws, const char* message, uint16_t length) { String messageStr = String(message, length); Serial.print("Color Sensor WebApp received: "); Serial.println(messageStr); // Only handle messages that start with our app identifier if (messageStr.startsWith(APP_IDENTIFIER)) { String payload = messageStr.substring(APP_IDENTIFIER.length()); // Remove identifier // Call your callback function with the payload if (customMessageCallback) { customMessageCallback(payload); } } } void CustomWebAppPage::onCustomMessageReceived(void (*callback)(const String& payload)) { customMessageCallback = callback; } void CustomWebAppPage::sendToWeb(const String& message) { // Send message to web browser with app identifier String fullMessage = APP_IDENTIFIER + message; broadcastToAllClients(fullMessage.c_str()); } const char* CustomWebAppPage::getPageInfo() const { return "🔧 Color Sensor WebApp"; } String CustomWebAppPage::getNavigationInfo() const { String result = "<a href=\""; result += getPagePath(); result += "\" class=\"app-card custom\" style=\"background: linear-gradient(135deg, #007bff 0%, #0056b3 100%);\">"; result += "<h3>🔧 Color Sensor WebApp</h3>"; result += "<p>Simple template for your own apps</p>"; result += "</a>"; return result; }

custom_page_html.h

/* * 이 아두이노 우노 R4 코드는 newbiely.kr 에서 개발되었습니다 * 이 아두이노 우노 R4 코드는 어떠한 제한 없이 공개 사용을 위해 제공됩니다. * 상세한 지침 및 연결도에 대해서는 다음을 방문하세요: * https://newbiely.kr/tutorials/arduino-uno-r4/arduino-uno-r4-color-sensor-via-web */ #ifndef CUSTOM_PAGE_HTML_H #define CUSTOM_PAGE_HTML_H const char CUSTOM_PAGE_HTML[] PROGMEM = R"HTML_WRAPPER( <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no"> <title>Mobile Laughing Minion</title> <style> body { margin: 0; padding: 20px; box-sizing: border-box; display: flex; flex-direction: column; justify-content: flex-start; align-items: center; background-color: #f0f8ff; font-family: sans-serif; overflow-x: hidden; } .text { font-size: clamp(16px, 5vw, 24px); font-weight: bold; color: #333; margin-bottom: 20px; text-align: center; z-index: 10; } .scale-wrapper { transform-origin: top center; display: flex; justify-content: center; align-items: flex-start; } .minion-container { position: relative; width: 200px; height: 400px; } .body { position: absolute; top: 20px; left: 25px; width: 150px; height: 300px; background-color: #FFD90F; border-radius: 75px; box-shadow: inset -10px -10px 20px rgba(0,0,0,0.1); overflow: hidden; z-index: 2; transition: background-color 0.5s; } .overalls { position: absolute; bottom: 0; width: 100%; height: 90px; background-color: #225A94; border-radius: 0 0 75px 75px; box-shadow: inset -10px -10px 20px rgba(0,0,0,0.2); } .pocket { position: absolute; bottom: 30px; left: 50px; width: 50px; height: 40px; background-color: #1A4674; border-radius: 10px 10px 20px 20px; border: 2px dashed #fce144; } .strap { position: absolute; top: 65px; left: 0; width: 100%; height: 25px; background-color: #333; z-index: 1; } .goggles-wrapper { position: absolute; top: 50px; left: -5px; width: 160px; display: flex; justify-content: center; z-index: 3; } .goggle { position: relative; width: 50px; height: 50px; background-color: white; border: 12px solid #999; border-radius: 50%; box-shadow: 3px 3px 8px rgba(0,0,0,0.2), inset 3px 3px 8px rgba(0,0,0,0.1); margin: 0 -2px; overflow: hidden; } .pupil { position: absolute; top: 50%; left: 50%; width: 20px; height: 20px; background-color: #4B3621; border-radius: 50%; transform: translate(-50%, -50%); transition: transform 0.2s ease-out; } .pupil::after { content: ''; position: absolute; top: 4px; left: 4px; width: 6px; height: 6px; background-color: black; border-radius: 50%; } .catchlight { position: absolute; top: 2px; right: 4px; width: 4px; height: 4px; background-color: white; border-radius: 50%; z-index: 4; } .eyelid { position: absolute; top: 0; left: 0; width: 100%; height: 100%; background-color: #FFD90F; border-bottom: 3px solid #D4B200; transform-origin: top; transform: scaleY(0); z-index: 5; animation: blink 4s infinite; } .mouth { position: absolute; top: 145px; left: 35px; width: 80px; height: 45px; background-color: #3E2723; border-radius: 10px 10px 60px 60px; overflow: hidden; z-index: 3; box-shadow: inset 0 5px 10px rgba(0,0,0,0.5); animation: laugh 0.2s infinite alternate ease-in-out; } .teeth { position: absolute; top: 0; left: 0; width: 100%; height: 14px; background-color: #fff; border-radius: 0 0 5px 5px; } .tongue { position: absolute; bottom: -5px; left: 20px; width: 40px; height: 25px; background-color: #FF5252; border-radius: 50%; animation: wag 0.2s infinite alternate ease-in-out; } .arm { position: absolute; top: 140px; width: 25px; height: 80px; background-color: #FFD90F; border-radius: 12px; z-index: 1; transition: background-color 0.5s; } .arm.left { left: 10px; transform: rotate(35deg); } .arm.right { right: 15px; transform: rotate(-35deg); } .glove { position: absolute; bottom: -15px; left: -5px; width: 35px; height: 35px; background-color: #333; border-radius: 50%; } .leg { position: absolute; bottom: 50px; width: 25px; height: 40px; background-color: #225A94; z-index: 1; } .leg.left { left: 60px; } .leg.right { left: 115px; } .shoe { position: absolute; bottom: -15px; left: -10px; width: 45px; height: 20px; background-color: #222; border-radius: 20px 20px 5px 5px; border-bottom: 5px solid #111; } @keyframes blink { 0%, 94%, 100% { transform: scaleY(0); } 97% { transform: scaleY(1); } } @keyframes laugh { 0% { height: 40px; transform: scaleX(1); } 100% { height: 55px; transform: scaleX(1.05); } } @keyframes wag { 0% { transform: translateY(0); } 100% { transform: translateY(-3px); } } </style> </head> <body> <div class="text" id="status-text">Just watch him look around! 👀</div> <div class="scale-wrapper" id="minionWrapper"> <div class="minion-container"> <div class="arm left" id="armL"><div class="glove"></div></div> <div class="arm right" id="armR"><div class="glove"></div></div> <div class="leg left"><div class="shoe"></div></div> <div class="leg right"><div class="shoe"></div></div> <div class="body" id="minionBody"> <div class="overalls"> <div class="pocket"></div> </div> <div class="strap"></div> <div class="goggles-wrapper"> <div class="goggle"><div class="pupil"><div class="catchlight"></div></div><div class="eyelid" id="eyelidL"></div></div> <div class="goggle"><div class="pupil"><div class="catchlight"></div></div><div class="eyelid" id="eyelidR"></div></div> </div> <div class="mouth"> <div class="teeth"></div> <div class="tongue"></div> </div> </div> </div> </div> <script> const APP_IDENTIFIER = 'Color Sensor:'; let ws = null; function connectWebSocket() { ws = new WebSocket('ws://' + location.hostname + ':81'); ws.onopen = () => document.getElementById('status-text').textContent = "Arduino Uno R4 - Color Sensor"; ws.onclose = () => setTimeout(connectWebSocket, 2000); ws.onmessage = (event) => { if (event.data.startsWith(APP_IDENTIFIER)) { let color = event.data.substring(APP_IDENTIFIER.length); // Cập nhật màu cho thân, tay và mí mắt document.getElementById('minionBody').style.backgroundColor = color; document.getElementById('armL').style.backgroundColor = color; document.getElementById('armR').style.backgroundColor = color; document.getElementById('eyelidL').style.backgroundColor = color; document.getElementById('eyelidR').style.backgroundColor = color; document.getElementById('status-text').style.color = color; } }; } function resizeMinion() { const wrapper = document.getElementById('minionWrapper'); const availableWidth = window.innerWidth - 40; const minionTrueWidth = 260; const minionHeight = 400; let scaleFactor = availableWidth / minionTrueWidth; if (scaleFactor > 1.5) scaleFactor = 1.5; wrapper.style.transform = `scale(${scaleFactor})`; wrapper.style.height = `${minionHeight * scaleFactor}px`; } window.addEventListener('resize', resizeMinion); resizeMinion(); connectWebSocket(); const pupils = document.querySelectorAll('.pupil'); function moveEyesAutomatically() { const angle = Math.random() * Math.PI * 2; const distance = Math.random() * 15; const pupilX = Math.cos(angle) * distance; const pupilY = Math.sin(angle) * distance; pupils.forEach(pupil => { pupil.style.transform = `translate(calc(-50% + ${pupilX}px), calc(-50% + ${pupilY}px))`; }); } setInterval(moveEyesAutomatically, 600); </script> </body> </html> )HTML_WRAPPER"; #endif

빠른 단계

다음 지침을 단계별로 따르세요:

  • Arduino Uno R4 WiFi를 처음 사용하는 경우, 아두이노 우노 R4 - 소프트웨어 설치을 참조하세요.
  • 먼저 컬러 센서를 보정하세요: 아두이노 우노 R4 - TCS3200D/TCS230 컬러 센서를 따라 보정하세요. 보정 값(redMin, redMax, greenMin, greenMax, blueMin, blueMax)을 기록해 두세요.
  • 위의 배선도에 따라 부품을 연결하세요.
  • USB 케이블을 사용하여 Arduino Uno R4 WiFi 보드를 컴퓨터에 연결하세요.
  • 컴퓨터에서 Arduino IDE를 실행하세요.
  • 적절한 Arduino Uno R4 보드(예: Arduino Uno R4 WiFi)와 COM 포트를 선택하세요.
  • Arduino IDE 왼쪽 바의 라이브러리 아이콘으로 이동하세요.
  • "DIYables WebApps"를 검색한 다음, DIYables에서 만든 DIYables WebApps 라이브러리를 찾으세요.
  • 설치 버튼을 클릭하여 라이브러리를 설치하세요.
  • 다른 라이브러리 종속성 설치를 요청받을 것입니다.
  • 모두 설치 버튼을 클릭하여 모든 라이브러리 종속성을 설치하세요.
아두이노 우노 R4 diyaBLEs webapps 라이브러리
아두이노 우노 R4 diyaBLEs webapps 종속성 라이브러리
  • Arduino IDE에서 새 스케치를 만들고 ColorSensor로 이름을 지정하세요.
  • 위의 4개 파일 모두를 Arduino IDE 프로젝트에 복사하여 붙여넣으세요. 아래와 같이 Arduino IDE 프로젝트에 4개의 파일이 있어야 합니다:
아두이노 우노 R4 컬러 센서 웹 앱 프로젝트 파일 - 아두이노 ide
  • ColorSensor.ino 파일에서 Wi-Fi 정보(SSID 및 비밀번호)를 직접 사용하는 것으로 업데이트하세요:
const char WIFI_SSID[] = "YOUR_WIFI_NAME"; const char WIFI_PASSWORD[] = "YOUR_WIFI_PASSWORD";
  • 보정 단계에서 얻은 보정 값으로 loop()map() 호출 내 값을 업데이트하세요. 예를 들어, 보정에서 redMin = 42, redMax = 210, greenMin = 55, greenMax = 185, blueMin = 60, blueMax = 172가 나왔다면 다음 줄을 변경하세요:
int r = map(pulseIn(sensorOut, LOW), 42, 210, 255, 0); int g = map(pulseIn(sensorOut, LOW), 55, 185, 255, 0); int b = map(pulseIn(sensorOut, LOW), 60, 172, 255, 0);
  • Arduino IDE의 업로드 버튼을 클릭하여 Arduino UNO R4에 코드를 업로드하세요.
  • 시리얼 모니터를 여세요. 다음과 같은 출력이 표시됩니다:
Newbiely | Arduino IDE 2.3.8
──
File
Edit
Sketch
Tools
Help
Arduino Uno R4 WiFi
Newbiely.ino
···
8 Serial.println("Hello World!");
Output
Serial Monitor
Message (Enter to send message to 'Arduino Uno R4 WiFi' on 'COM15')
New Line
9600 baud
Color Web Server Ready! INFO: Added app / INFO: Added app /custom DIYables WebApp Library Platform: Arduino Uno R4 WiFi Network connected! IP address: 192.168.0.2 HTTP server started on port 80 WebSocket server started on port 81 ========================================== DIYables WebApp Ready! ========================================== 📱 Web Interface: http://192.168.0.2 🔗 WebSocket: ws://192.168.0.2:81 📋 Available Applications: 🏠 Home Page: http://192.168.0.2/ 🔧 Color Sensor WebApp: http://192.168.0.2/custom ========================================== Sent to Minion: #FFD200 Sent to Minion: #00C832 Sent to Minion: #0028FF
Ln 11, Col 1
Arduino Uno R4 WiFi on COM15
2
  • 아무것도 표시되지 않으면 아두이노 보드를 재부팅하세요.
  • 표시된 IP 주소를 기록하고, 스마트폰이나 PC의 웹 브라우저 주소창에 이 주소를 입력하세요.
  • 예: http://192.168.0.2
  • 홈 페이지가 표시됩니다. 컬러 센서 웹앱 링크를 클릭하세요.
  • 또는 IP 주소 뒤에 /custom을 붙여 미니언 페이지에 직접 접속할 수 있습니다. 예: http://192.168.0.2/custom
  • 웹 페이지에 애니메이션 미니언 캐릭터가 표시됩니다.
  • TCS3200 센서 앞에 색깔 있는 물체를 놓으면 미니언의 피부색이 실시간으로 감지된 색상에 맞춰 변경됩니다!

아래 동영상에서 단계별 설명을 확인할 수 있습니다.

코드 작동 원리

아두이노 측 (ColorSensor.ino)

메인 스케치는 다음을 수행합니다:

  • TCS3200 센서 핀 초기화: S0, S1은 20% 주파수 스케일링으로 설정됩니다. S2, S3은 색상 필터 선택에 사용됩니다.
  • 1초마다 색상 읽기: loop()에서 아두이노는 빨강, 초록, 파랑 필터를 순서대로 선택하고, pulseIn()을 사용하여 펄스 폭을 읽으며, 보정 값을 사용하여 원시 값을 0-255 RGB 값으로 매핑합니다.
  • HEX로 변환: RGB 값은 sprintf()를 사용하여 #FF8000과 같은 HEX 색상 문자열로 포맷됩니다.
  • 웹 브라우저로 전송: HEX 문자열은 customPage.sendToWeb()을 통해 연결된 모든 웹 클라이언트에게 전송됩니다.

웹 페이지 측 (custom_page_html.h)

HTML 페이지에는 다음이 포함됩니다:

  • CSS로 만든 애니메이션 미니언 캐릭터: 깜빡이는 눈, 웃는 입, 무작위로 움직이는 눈동자가 포함되어 있습니다.
  • WebSocket 연결: JavaScript가 아두이노의 WebSocket 서버(포트 81)에 연결하고 들어오는 색상 메시지를 수신 대기합니다.
  • 색상 업데이트: #FF8000과 같은 메시지를 받으면 미니언의 몸통, 팔, 눈꺼풀이 CSS transition을 사용하여 새 색상으로 부드럽게 전환됩니다.
  • 자동 재연결: WebSocket 연결이 끊어지면 페이지가 자동으로 2초마다 재연결을 시도합니다.
  • 반응형 디자인: 미니언이 다양한 화면 크기(휴대폰, 태블릿, 데스크톱)에 맞게 자동으로 크기가 조정됩니다.

통신 프로토콜

이 프로젝트는 "Color Sensor:" 식별자와 함께 DIYables WebApps 커스텀 웹 앱 프레임워크를 사용합니다:

  • 아두이노 전송: Color Sensor:#FF8000 (식별자 + HEX 색상)
  • 웹 페이지 수신: 식별자를 제거하고 나머지 HEX 색상 #FF8000을 미니언에 적용합니다

통신 프로토콜 및 웹 앱 커스터마이즈 방법에 대한 자세한 내용은 아두이노 맞춤형 웹앱 예제 - 초보자를 위한 간단한 웹 인터페이스 튜토리얼을 참조하세요.