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.
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
Tiết lộ: Một số liên kết trong bài viết này là liên kết tiếp thị Amazon và có thể nhận hoa hồng theo chính sách của chương trình.
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.
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.
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 NETWORKconstchar WIFI_SSID[] = "YOUR_WIFI_SSID";constchar WIFI_PASSWORD[] = "YOUR_WIFI_PASSWORD";// Create WebApp server and page instancesUnoR4ServerFactory serverFactory;DIYablesWebAppServerwebAppsServer(serverFactory, 80, 81);DIYablesHomePage homePage;DIYablesWebSliderPage webSliderPage;// Current slider valuesint slider1Value = 64; // Default 25%int slider2Value = 128; // Default 50%voidsetup() {Serial.begin(9600);delay(1000);// TODO: Initialize your hardware pins hereSerial.println("DIYables WebApp - Web Slider Example");// Add home and web slider pageswebAppsServer.addApp(&homePage);webAppsServer.addApp(&webSliderPage);// Optional: Add 404 page for better user experiencewebAppsServer.setNotFoundPage(DIYablesNotFoundPage());// Start the WebApp serverif (!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)); });}voidloop() {// Handle WebApp server communicationswebAppsServer.loop();// TODO: Add your main application code heredelay(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:
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
Newbiely | Arduino IDE 2.3.8
──
☐
✕
File
Edit
Sketch
Tools
Help
Arduino Uno R4 WiFi
Newbiely.ino
···
8Serial.println("Hello World!");
Output
Serial Monitor
Message (Enter to send message to 'Arduino Uno R4 WiFi' on 'COM15')
New Line
9600 baud
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
==========================================
Ln 11, Col 1
Arduino Uno R4 WiFi on COM15
2
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:
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:
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)
Nhấn và Kéo: Nhấn vào tay cầm slider và kéo để điều chỉnh giá trị
Nhấn Vị trí: Nhấn bất kỳ đâu trên track slider để nhảy đến giá trị đó
Đ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)
Chạm và Kéo: Chạm tay cầm slider và kéo đến vị trí mới
Chạm Vị trí: Chạm trên track slider để đặt giá trị
Đ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
voidsetup() {// 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 LEDconstint LED1_PIN = 9; // Chân PWM cho LED đầu tiênconstint LED2_PIN = 10; // Chân PWM cho LED thứ haivoidsetup() {// Cấu hình chân LED như outputspinMode(LED1_PIN, OUTPUT);pinMode(LED2_PIN, OUTPUT);// Đặt độ sáng ban đầuanalogWrite(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;voidsetup() {// 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 driverconstint MOTOR1_PWM = 9; // Điều khiển tốc độ Motor 1constint MOTOR1_DIR1 = 2; // Chân hướng Motor 1 pin 1constint MOTOR1_DIR2 = 3; // Chân hướng Motor 1 pin 2constint MOTOR2_PWM = 10; // Điều khiển tốc độ Motor 2constint MOTOR2_DIR1 = 4; // Chân hướng Motor 2 pin 1constint MOTOR2_DIR2 = 5; // Chân hướng Motor 2 pin 2voidsetup() {// Cấu hình chân motorpinMode(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ếpanalogWrite(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 LEDconstint RED_PIN = 9;constint GREEN_PIN = 10;constint BLUE_PIN = 11;voidsetup() {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 sliderint redValue = slider1;int blueValue = slider2;int greenValue = (slider1 + slider2) / 2; // Trung bình của cả hai slideranalogWrite(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;unsignedlong lastUpdate = 0;constint SMOOTH_RATE = 5; // Thay đổi mỗi chu kỳ cập nhậtpublic:void setTarget(int target) { targetValue = target; }int getCurrentValue() {return currentValue; }boolupdate() {if (millis() - lastUpdate > 10) { // Cập nhật mỗi 10msbool changed = false;if (currentValue < targetValue) { currentValue = min(currentValue + SMOOTH_RATE, targetValue); changed = true; } elseif (currentValue > targetValue) { currentValue = max(currentValue - SMOOTH_RATE, targetValue); changed = true; } lastUpdate = millis();return changed; }returnfalse; }};SliderSmoother smoother1, smoother2;voidsetup() { 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); });}voidloop() { server.loop();// Cập nhật giá trị được làm mịnbool changed1 = smoother1.update();bool changed2 = smoother2.update();if (changed1 || changed2) {// Áp dụng giá trị được làm mịn cho phần cứnganalogWrite(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ạcconstint LOW_THRESHOLD = 85; // 33%constint MEDIUM_THRESHOLD = 170; // 66%// Điều khiển outputs số dựa trên ngưỡng slider 1if (slider1 < LOW_THRESHOLD) {// Mức thấp: Tắt tất cả outputsdigitalWrite(2, LOW);digitalWrite(3, LOW);digitalWrite(4, LOW); } elseif (slider1 < MEDIUM_THRESHOLD) {// Mức trung: Bật output đầu tiêndigitalWrite(2, HIGH);digitalWrite(3, LOW);digitalWrite(4, LOW); } else {// Mức cao: Bật tất cả outputsdigitalWrite(2, HIGH);digitalWrite(3, HIGH);digitalWrite(4, HIGH); }// Sử dụng slider 2 cho điều khiển PWM analoganalogWrite(9, slider2); });}
Hệ thống Giá trị Preset
// Giá trị preset được định nghĩa trướcconstint 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ứnganalogWrite(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ạnanalogWrite(9, slider1);analogWrite(10, slider2); });}voidloop() { 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 digitalstaticbool lastButton = false;bool currentButton = digitalRead(7); // Nút preset trên chân 7if (currentButton && !lastButton) { // Nút được nhấnstaticint 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)constint LED_STRIP_PIN = 6;constint 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 hueuint8_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)); });}
// Cho điều khiển bộ khuếch đại audio hoặc IC âm lượngconstint VOLUME1_PIN = 9; // Output PWM đến điều khiển âm lượngconstint VOLUME2_PIN = 10; // Kênh thứ hai hoặc điều khiển âm sắcvoid 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ơnfloat volume1 = pow(slider1 / 255.0, 2) * 255; // Quy luật bình phươngfloat 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