Arduino WebSlider Example Hướng dẫn Giao diện Điều khiển Dual Slider

Tổng quan

Ví dụ WebSlider cung cấp hai điều khiển slider độc lập có thể truy cập qua trình duyệt web. Được thiết kế cho Arduino Uno R4 WiFi và DIYables STEM V4 IoT - nền tảng giáo dục với khả năng analog nâng cao, tính năng điều khiển chính xác, và các module giáo dục tích hợp để học PWM và điện tử analog. Mỗi slider cung cấp giá trị từ 0-255, làm cho chúng hoàn hảo cho điều khiển PWM, điều chỉnh độ sáng, điều khiển tốc độ động cơ, và bất kỳ ứng dụng nào yêu cầu giá trị điều khiển tương tự analog.

Arduino webslider example - hướng dẫn giao diện Điều khiển dual slider

Tính năng

  • Dual Sliders: Hai điều khiển slider độc lập (mỗi slider có phạm vi 0-255)
  • Giá trị Thời gian Thực: Cập nhật giá trị tức thì qua giao tiếp WebSocket
  • Tương thích PWM: Giá trị 8-bit (0-255) hoàn hảo cho các hàm analogWrite()
  • Phản hồi Trực quan: Hiển thị giá trị thời gian thực cho mỗi slider
  • Nút Preset: Truy cập nhanh đến các giá trị thông dụng
  • Hỗ trợ Cảm ứng & Chuột: Hoạt động trên máy tính, tablet và thiết bị di động
  • Thiết kế Responsive: Thích ứng với các kích thước màn hình khác nhau
  • Duy trì Giá trị: Sliders nhớ vị trí cuối khi trang reload
  • Mở rộng Nền tảng: Hiện được triển khai cho Arduino Uno R4 WiFi, nhưng có thể mở rộng cho các nền tảng phần cứng khác. Xem DIYables_WebApps_ESP32

Phần cứng cần thiết

1×Arduino UNO R4 WiFi
1×Alternatively, DIYables STEM V4 IoT
1×(Tùy chọn) DIYables STEM V4 IoT
1×Cáp USB Type-C
1×(Khuyến nghị) Screw Terminal Block Shield for Arduino UNO R4
1×(Khuyến nghị) Breadboard Shield for Arduino UNO R4
1×(Khuyến nghị) Enclosure for Arduino UNO R4
1×(Khuyến nghị) Power Splitter for Arduino UNO R4
1×(Khuyến nghị) Prototyping Base Plate & Breadboard Kit for Arduino UNO

Or you can buy the following kits:

1×DIYables STEM V4 IoT Starter Kit (Arduino included)
1×DIYables Sensor Kit (30 sensors/displays)
1×DIYables Sensor Kit (18 sensors/displays)

Hướng dẫn Thiết lập

Các bước nhanh

Thực hiện theo các hướng dẫn từng bước:

  • Mới sử dụng Arduino Uno R4 WiFi/DIYables STEM V4 IoT? Hãy bắt đầu với hướng dẫn Arduino UNO R4 - Cài Đặt Phần Mềm để học các kiến thức cơ bản trước.
  • Kết nối bo mạch Arduino Uno R4/DIYables STEM V4 IoT với máy tính của bạn bằng cáp USB.
  • Khởi động Arduino IDE trên máy tính của bạn.
  • Chọn bo mạch Arduino Uno R4 phù hợp (ví dụ: Arduino Uno R4 WiFi) và cổng COM.
  • Điều hướng đến biểu tượng Libraries ở thanh bên trái của Arduino IDE.
  • Tìm kiếm "DIYables WebApps", sau đó tìm thư viện DIYables WebApps của DIYables
  • Nhấn nút Install để cài đặt thư viện.
Arduino UNO R4 diyables webapps thư viện
  • Bạn sẽ được yêu cầu cài đặt một số thư viện phụ thuộc khác
  • Nhấn nút Install All để cài đặt tất cả các thư viện phụ thuộc.
Arduino UNO R4 diyables webapps dependency
  • Trên Arduino IDE, đi đến File Examples DIYables WebApps WebSlider example, hoặc copy code trên và dán vào editor của Arduino IDE
/* * DIYables WebApp Library - Web Slider Example * * This example demonstrates the Web Slider feature: * - Two independent sliders (0-255) * - Real-time value monitoring * - Template for hardware control * * Hardware: Arduino Uno R4 WiFi or DIYables STEM V4 IoT * * Setup: * 1. Update WiFi credentials below * 2. Upload the sketch to your Arduino * 3. Open Serial Monitor to see the IP address * 4. Navigate to http://[IP_ADDRESS]/webslider */ #include <DIYablesWebApps.h> // WiFi credentials - UPDATE THESE WITH YOUR NETWORK const char WIFI_SSID[] = "YOUR_WIFI_SSID"; const char WIFI_PASSWORD[] = "YOUR_WIFI_PASSWORD"; // Create WebApp server and page instances UnoR4ServerFactory serverFactory; DIYablesWebAppServer webAppsServer(serverFactory, 80, 81); DIYablesHomePage homePage; DIYablesWebSliderPage webSliderPage; // Current slider values int slider1Value = 64; // Default 25% int slider2Value = 128; // Default 50% void setup() { Serial.begin(9600); delay(1000); // TODO: Initialize your hardware pins here Serial.println("DIYables WebApp - Web Slider Example"); // Add home and web slider pages webAppsServer.addApp(&homePage); webAppsServer.addApp(&webSliderPage); // Optional: Add 404 page for better user experience webAppsServer.setNotFoundPage(DIYablesNotFoundPage()); // Start the WebApp server if (!webAppsServer.begin(WIFI_SSID, WIFI_PASSWORD)) { while (1) { Serial.println("Failed to start WebApp server!"); delay(1000); } } // Set up slider callback for value changes webSliderPage.onSliderValueFromWeb([](int slider1, int slider2) { // Store the received values slider1Value = slider1; slider2Value = slider2; // Print slider values (0-255) Serial.println("Slider 1: " + String(slider1) + ", Slider 2: " + String(slider2)); // TODO: Add your control logic here based on slider values // Examples: // - Control PWM: analogWrite(LED_PIN, slider1); // - Control servos: servo.write(map(slider1, 0, 255, 0, 180)); // - Control motor speed: analogWrite(MOTOR_PIN, slider2); // - Control brightness: strip.setBrightness(slider1); // - Send values via Serial, I2C, SPI, etc. }); // Set up callback for config requests (when client requests current values) webSliderPage.onSliderValueToWeb([]() { webSliderPage.sendToWebSlider(slider1Value, slider2Value); Serial.println("Web client requested values - Sent: Slider1=" + String(slider1Value) + ", Slider2=" + String(slider2Value)); }); } void loop() { // Handle WebApp server communications webAppsServer.loop(); // TODO: Add your main application code here delay(10); }
  • Cấu hình thông tin đăng nhập WiFi trong code bằng cách cập nhật các dòng này:
const char WIFI_SSID[] = "YOUR_WIFI_NETWORK"; const char WIFI_PASSWORD[] = "YOUR_WIFI_PASSWORD";
  • Nhấn nút Upload trên Arduino IDE để upload code lên Arduino UNO R4/DIYables STEM V4 IoT
  • Mở Serial Monitor
  • Kiểm tra kết quả trên Serial Monitor. Nó sẽ trông như thế này
COM6
Send
DIYables WebApp - Web Slider Example INFO: Added app / INFO: Added app /web-slider DIYables WebApp Library Platform: Arduino Uno R4 WiFi Network connected! IP address: 192.168.0.2 HTTP server started on port 80 Configuring WebSocket server callbacks... WebSocket server started on port 81 WebSocket URL: ws://192.168.0.2:81 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/ 🎚️ Web Slider: http://192.168.0.2/web-slider ==========================================
Autoscroll Show timestamp
Clear output
9600 baud  
Newline  
  • Nếu bạn không thấy gì, hãy khởi động lại bo mạch Arduino.
  • Ghi nhớ địa chỉ IP hiển thị, và nhập địa chỉ này vào thanh địa chỉ của trình duyệt web trên smartphone hoặc PC của bạn.
  • Ví dụ: http://192.168.0.2
  • Bạn sẽ thấy trang chủ như hình dưới đây:
Arduino UNO R4 diyables webapp home page with web slider app
  • Nhấn vào link Web Slider, bạn sẽ thấy giao diện của ứng dụng Web Slider như hình dưới:
Arduino UNO R4 diyables webapp web slider app
  • Hoặc bạn cũng có thể truy cập trang trực tiếp bằng địa chỉ IP theo sau bởi /web-slider. Ví dụ: http://192.168.0.2/web-slider
  • Thử di chuyển hai slider để điều khiển các giá trị analog (0-255) và quan sát phản hồi thời gian thực trong Serial Monitor.

Tùy chỉnh Sáng tạo - Điều chỉnh Code cho Dự án của bạn

Đặt Giá trị Mặc định cho Slider

Cấu hình vị trí ban đầu của slider:

// Giá trị slider hiện tại (0-255) int slider1Value = 64; // Mặc định 25% (64/255) int slider2Value = 128; // Mặc định 50% (128/255)

Cách Sử dụng Sliders

Điều khiển Giao diện Web

Giao diện slider cung cấp:

  • Slider 1: Slider điều khiển đầu tiên với hiển thị giá trị (0-255)
  • Slider 2: Slider điều khiển thứ hai với hiển thị giá trị (0-255)
  • Hiển thị Giá trị: Giá trị số thời gian thực cho cả hai slider
  • Nút Preset: Truy cập nhanh đến các giá trị thông dụng (0%, 25%, 50%, 75%, 100%)

Vận hành Sliders

Máy tính (Điều khiển chuột)

  1. Nhấn và Kéo: Nhấn vào tay cầm slider và kéo để điều chỉnh giá trị
  2. Nhấn Vị trí: Nhấn bất kỳ đâu trên track slider để nhảy đến giá trị đó
  3. Điều khiển Tinh: Sử dụng chuyển động chuột nhỏ để điều chỉnh chính xác

Di động/Tablet (Điều khiển cảm ứng)

  1. Chạm và Kéo: Chạm tay cầm slider và kéo đến vị trí mới
  2. Chạm Vị trí: Chạm trên track slider để đặt giá trị
  3. Điều khiển Mượt: Kéo bằng ngón tay cung cấp thay đổi giá trị mượt mà

Phạm vi Giá trị

Mỗi slider cung cấp:

  • Giá trị Tối thiểu: 0 (0% - tắt hoàn toàn)
  • Giá trị Tối đa: 255 (100% - cường độ tối đa)
  • Độ phân giải: 256 bước rời rạc (độ chính xác 8-bit)
  • Tương thích PWM: Sử dụng trực tiếp với hàm analogWrite()

Ví dụ Lập trình

Handler Slider Cơ bản

void setup() { // Thiết lập callback slider cho thay đổi giá trị webSliderPage.onSliderValueFromWeb([](int slider1, int slider2) { // Lưu trữ các giá trị nhận được slider1Value = slider1; slider2Value = slider2; // In giá trị slider (0-255) Serial.println("Slider 1: " + String(slider1) + ", Slider 2: " + String(slider2)); // Thêm logic điều khiển của bạn ở đây }); }

Điều khiển Độ sáng LED

// Định nghĩa chân cho PWM LED const int LED1_PIN = 9; // Chân PWM cho LED đầu tiên const int LED2_PIN = 10; // Chân PWM cho LED thứ hai void setup() { // Cấu hình chân LED như outputs pinMode(LED1_PIN, OUTPUT); pinMode(LED2_PIN, OUTPUT); // Đặt độ sáng ban đầu analogWrite(LED1_PIN, slider1Value); analogWrite(LED2_PIN, slider2Value); webSliderPage.onSliderValueFromWeb([](int slider1, int slider2) { // Lưu giá trị slider1Value = slider1; slider2Value = slider2; // Điều khiển độ sáng LED trực tiếp (0-255 PWM) analogWrite(LED1_PIN, slider1); analogWrite(LED2_PIN, slider2); Serial.println("LED1 Brightness: " + String(slider1) + ", LED2 Brightness: " + String(slider2)); }); }

Điều khiển Vị trí Servo

#include <Servo.h> Servo servo1, servo2; void setup() { // Gắn servos vào chân PWM servo1.attach(9); servo2.attach(10); // Đặt vị trí ban đầu servo1.write(map(slider1Value, 0, 255, 0, 180)); servo2.write(map(slider2Value, 0, 255, 0, 180)); webSliderPage.onSliderValueFromWeb([](int slider1, int slider2) { slider1Value = slider1; slider2Value = slider2; // Ánh xạ giá trị slider (0-255) sang góc servo (0-180°) int angle1 = map(slider1, 0, 255, 0, 180); int angle2 = map(slider2, 0, 255, 0, 180); // Di chuyển servos đến vị trí tính toán servo1.write(angle1); servo2.write(angle2); Serial.println("Servo1: " + String(angle1) + "°, Servo2: " + String(angle2) + "°"); }); }

Điều khiển Tốc độ Động cơ

// Chân motor driver const int MOTOR1_PWM = 9; // Điều khiển tốc độ Motor 1 const int MOTOR1_DIR1 = 2; // Chân hướng Motor 1 pin 1 const int MOTOR1_DIR2 = 3; // Chân hướng Motor 1 pin 2 const int MOTOR2_PWM = 10; // Điều khiển tốc độ Motor 2 const int MOTOR2_DIR1 = 4; // Chân hướng Motor 2 pin 1 const int MOTOR2_DIR2 = 5; // Chân hướng Motor 2 pin 2 void setup() { // Cấu hình chân motor pinMode(MOTOR1_PWM, OUTPUT); pinMode(MOTOR1_DIR1, OUTPUT); pinMode(MOTOR1_DIR2, OUTPUT); pinMode(MOTOR2_PWM, OUTPUT); pinMode(MOTOR2_DIR1, OUTPUT); pinMode(MOTOR2_DIR2, OUTPUT); // Đặt hướng motor ban đầu (tiến) digitalWrite(MOTOR1_DIR1, HIGH); digitalWrite(MOTOR1_DIR2, LOW); digitalWrite(MOTOR2_DIR1, HIGH); digitalWrite(MOTOR2_DIR2, LOW); webSliderPage.onSliderValueFromWeb([](int slider1, int slider2) { slider1Value = slider1; slider2Value = slider2; // Điều khiển tốc độ motor trực tiếp analogWrite(MOTOR1_PWM, slider1); analogWrite(MOTOR2_PWM, slider2); // Tính phần trăm để hiển thị int speed1Percent = map(slider1, 0, 255, 0, 100); int speed2Percent = map(slider2, 0, 255, 0, 100); Serial.println("Motor1: " + String(speed1Percent) + "%, " + "Motor2: " + String(speed2Percent) + "%"); }); }

Điều khiển Màu LED RGB

// Chân RGB LED const int RED_PIN = 9; const int GREEN_PIN = 10; const int BLUE_PIN = 11; void setup() { pinMode(RED_PIN, OUTPUT); pinMode(GREEN_PIN, OUTPUT); pinMode(BLUE_PIN, OUTPUT); webSliderPage.onSliderValueFromWeb([](int slider1, int slider2) { slider1Value = slider1; slider2Value = slider2; // Sử dụng sliders để điều khiển thành phần RGB // Slider 1 điều khiển cường độ đỏ // Slider 2 điều khiển cường độ xanh dương // Xanh lá được tính toán dựa trên cả hai slider int redValue = slider1; int blueValue = slider2; int greenValue = (slider1 + slider2) / 2; // Trung bình của cả hai slider analogWrite(RED_PIN, redValue); analogWrite(GREEN_PIN, greenValue); analogWrite(BLUE_PIN, blueValue); Serial.println("RGB - R:" + String(redValue) + " G:" + String(greenValue) + " B:" + String(blueValue)); }); }

Kỹ thuật Lập trình Nâng cao

Làm mịn Giá trị

class SliderSmoother { private: int currentValue = 0; int targetValue = 0; unsigned long lastUpdate = 0; const int SMOOTH_RATE = 5; // Thay đổi mỗi chu kỳ cập nhật public: void setTarget(int target) { targetValue = target; } int getCurrentValue() { return currentValue; } bool update() { if (millis() - lastUpdate > 10) { // Cập nhật mỗi 10ms bool changed = false; if (currentValue < targetValue) { currentValue = min(currentValue + SMOOTH_RATE, targetValue); changed = true; } else if (currentValue > targetValue) { currentValue = max(currentValue - SMOOTH_RATE, targetValue); changed = true; } lastUpdate = millis(); return changed; } return false; } }; SliderSmoother smoother1, smoother2; void setup() { webSliderPage.onSliderValueFromWeb([](int slider1, int slider2) { // Đặt giá trị mục tiêu cho chuyển tiếp mượt smoother1.setTarget(slider1); smoother2.setTarget(slider2); }); } void loop() { server.loop(); // Cập nhật giá trị được làm mịn bool changed1 = smoother1.update(); bool changed2 = smoother2.update(); if (changed1 || changed2) { // Áp dụng giá trị được làm mịn cho phần cứng analogWrite(9, smoother1.getCurrentValue()); analogWrite(10, smoother2.getCurrentValue()); } }

Điều khiển dựa trên Ngưỡng

void setupThresholdControl() { webSliderPage.onSliderValueFromWeb([](int slider1, int slider2) { slider1Value = slider1; slider2Value = slider2; // Điều khiển dựa trên ngưỡng cho outputs rời rạc const int LOW_THRESHOLD = 85; // 33% const int MEDIUM_THRESHOLD = 170; // 66% // Điều khiển outputs số dựa trên ngưỡng slider 1 if (slider1 < LOW_THRESHOLD) { // Mức thấp: Tắt tất cả outputs digitalWrite(2, LOW); digitalWrite(3, LOW); digitalWrite(4, LOW); } else if (slider1 < MEDIUM_THRESHOLD) { // Mức trung: Bật output đầu tiên digitalWrite(2, HIGH); digitalWrite(3, LOW); digitalWrite(4, LOW); } else { // Mức cao: Bật tất cả outputs digitalWrite(2, HIGH); digitalWrite(3, HIGH); digitalWrite(4, HIGH); } // Sử dụng slider 2 cho điều khiển PWM analog analogWrite(9, slider2); }); }

Hệ thống Giá trị Preset

// Giá trị preset được định nghĩa trước const int PRESETS[][2] = { {0, 0}, // Preset 0: Cả hai tắt {64, 128}, // Preset 1: Thấp/Trung bình {128, 128}, // Preset 2: Cả hai trung bình {255, 128}, // Preset 3: Cao/Trung bình {255, 255} // Preset 4: Cả hai tối đa }; void applyPreset(int presetNumber) { if (presetNumber >= 0 && presetNumber < 5) { slider1Value = PRESETS[presetNumber][0]; slider2Value = PRESETS[presetNumber][1]; // Cập nhật phần cứng analogWrite(9, slider1Value); analogWrite(10, slider2Value); // Gửi giá trị cập nhật đến giao diện web webSliderPage.sendToWebSlider(slider1Value, slider2Value); Serial.println("Applied preset " + String(presetNumber) + ": " + String(slider1Value) + ", " + String(slider2Value)); } } void setupPresetSystem() { // Bạn có thể kích hoạt presets dựa trên các input khác // Ví dụ, đọc chân digital cho các nút preset webSliderPage.onSliderValueFromWeb([](int slider1, int slider2) { slider1Value = slider1; slider2Value = slider2; // Xử lý slider bình thường của bạn analogWrite(9, slider1); analogWrite(10, slider2); }); } void loop() { server.loop(); // Kiểm tra điều kiện kích hoạt preset // Ví dụ: Đọc nút được kết nối với chân digital static bool lastButton = false; bool currentButton = digitalRead(7); // Nút preset trên chân 7 if (currentButton && !lastButton) { // Nút được nhấn static int currentPreset = 0; applyPreset(currentPreset); currentPreset = (currentPreset + 1) % 5; // Chu kỳ qua các preset } lastButton = currentButton; }

Ví dụ Tích hợp Phần cứng

Điều khiển Dải LED

// Cho dải LED có thể địa chỉ hóa WS2812B hoặc tương tự // (yêu cầu thư viện bổ sung như FastLED hoặc Adafruit NeoPixel) const int LED_STRIP_PIN = 6; const int NUM_LEDS = 30; void setupLEDStrip() { // Khởi tạo dải LED (phụ thuộc vào thư viện được sử dụng) webSliderPage.onSliderValueFromWeb([](int slider1, int slider2) { slider1Value = slider1; slider2Value = slider2; // Slider 1 điều khiển độ sáng (0-255) // Slider 2 điều khiển nhiệt độ màu hoặc hue uint8_t brightness = slider1; uint8_t hue = slider2; // Cập nhật dải LED (ví dụ với các hàm khái niệm) // strip.setBrightness(brightness); // strip.fill(CHSV(hue, 255, 255)); // strip.show(); Serial.println("LED Strip - Brightness: " + String(brightness) + ", Hue: " + String(hue)); }); }

Điều khiển Tốc độ Quạt

const int FAN1_PIN = 9; const int FAN2_PIN = 10; void setupFanControl() { pinMode(FAN1_PIN, OUTPUT); pinMode(FAN2_PIN, OUTPUT); webSliderPage.onSliderValueFromWeb([](int slider1, int slider2) { slider1Value = slider1; slider2Value = slider2; // Điều khiển tốc độ quạt với ngưỡng tối thiểu để khởi động int fan1Speed = (slider1 > 50) ? map(slider1, 50, 255, 100, 255) : 0; int fan2Speed = (slider2 > 50) ? map(slider2, 50, 255, 100, 255) : 0; analogWrite(FAN1_PIN, fan1Speed); analogWrite(FAN2_PIN, fan2Speed); Serial.println("Fan1: " + String(map(fan1Speed, 0, 255, 0, 100)) + "%, " + "Fan2: " + String(map(fan2Speed, 0, 255, 0, 100)) + "%"); }); }

Điều khiển Âm lượng Audio

// Cho điều khiển bộ khuếch đại audio hoặc IC âm lượng const int VOLUME1_PIN = 9; // Output PWM đến điều khiển âm lượng const int VOLUME2_PIN = 10; // Kênh thứ hai hoặc điều khiển âm sắc void setupAudioControl() { pinMode(VOLUME1_PIN, OUTPUT); pinMode(VOLUME2_PIN, OUTPUT); webSliderPage.onSliderValueFromWeb([](int slider1, int slider2) { slider1Value = slider1; slider2Value = slider2; // Sử dụng tỷ lệ logarithm cho nhận thức audio tốt hơn float volume1 = pow(slider1 / 255.0, 2) * 255; // Quy luật bình phương float volume2 = pow(slider2 / 255.0, 2) * 255; analogWrite(VOLUME1_PIN, (int)volume1); analogWrite(VOLUME2_PIN, (int)volume2); Serial.println("Volume1: " + String((int)volume1) + ", Volume2: " + String((int)volume2)); }); }

Khắc phục Sự cố

Các vấn đề Thường gặp

1. Sliders không phản hồi

  • Kiểm tra kết nối WebSocket trong console của trình duyệt
  • Xác minh kết nối mạng giữa thiết bị và Arduino
  • Refresh trang trình duyệt để reset kết nối
  • Kiểm tra Serial Monitor để tìm lỗi kết nối

2. Giá trị không đạt phạm vi đầy đủ

  • Xác minh cài đặt phạm vi slider trong giao diện web
  • Kiểm tra vấn đề ánh xạ giá trị trong hàm callback
  • Kiểm tra với các trình duyệt hoặc thiết bị khác nhau

3. Điều khiển giật hoặc không ổn định

  • Triển khai làm mịn giá trị cho thay đổi dần dần
  • Kiểm tra vấn đề độ trễ mạng
  • Thêm debouncing cho thay đổi giá trị nhanh

4. Output PWM không hoạt động

  • Xác minh chân hỗ trợ PWM (kiểm tra sơ đồ chân Arduino)
  • Đảm bảo analogWrite() được gọi với số chân chính xác
  • Kiểm tra kết nối phần cứng và yêu cầu tải