LVGL và Robot Mochi: Xây dựng giao diện cảm xúc cho thiết bị nhúng - Phần 2: Mochi & LVGL
Phần 2 series Mochi LVGL: tổ chức khuôn mặt, biểu cảm, pin, kết nối, screen, component và state cho giao diện robot.
Chia sẻ

Ở phần trước, mình đã giới thiệu LVGL như một thư viện đồ họa cho thiết bị nhúng. Phần này đi thẳng vào ví dụ gần gũi hơn: dùng LVGL để làm khuôn mặt và giao diện cho Robot Mochi.
Với Mochi robot, màn hình không chỉ dùng để báo trạng thái. Nó còn là khuôn mặt của robot: mắt, miệng, biểu cảm, animation, trạng thái pin, chế độ hoạt động và sau này có thể là menu cấu hình. Đây là lý do LVGL trở thành một lựa chọn rất đáng để tìm hiểu nếu muốn phát triển Mochi theo hướng sản phẩm lâu dài.
Ứng dụng LVGL cho Robot Mochi
Với Mochi, mình có thể dùng LVGL cho toàn bộ phần hiển thị. Thay vì chỉ phát GIF hoặc bitmap cảm xúc cố định, bạn có thể chia giao diện thành nhiều màn hình, trạng thái và component nhỏ dễ quản lý hơn.
Ví dụ, màn hình chính có thể là khuôn mặt robot. Khi Mochi ở trạng thái bình thường, màn hình hiển thị một khuôn mặt vui nhẹ. Khi người dùng chạm vào robot, Mochi có thể đổi sang biểu cảm vui, ngạc nhiên hoặc tò mò. Khi pin yếu, góc màn hình có thể hiện icon pin. Khi đang sạc, Mochi có thể hiển thị hiệu ứng sạc. Khi kết nối Wi-Fi hoặc Bluetooth, màn hình có thể hiển thị icon trạng thái tương ứng.

Các biến thể của Robot Mochi, LVGL giúp Mochi trông giống sản phẩm thật hơn
Nếu Mochi có thêm màn cảm ứng, LVGL còn có thể xử lý các thao tác chạm để mở menu, đổi biểu cảm, chỉnh âm lượng, chọn chế độ hoạt động hoặc vào màn hình cấu hình.
Điểm hay của LVGL là nó cho phép kết hợp nhiều thành phần UI lại với nhau. Khuôn mặt có thể là image hoặc canvas. Dòng trạng thái có thể là label. Icon pin có thể là image nhỏ. Menu có thể là list hoặc button. Hiệu ứng chuyển cảnh có thể dùng animation. Nhờ vậy, phần giao diện của Mochi không còn là vài hình ảnh rời rạc, mà trở thành một hệ thống UI có cấu trúc rõ ràng.
LVGL giúp Mochi trông giống sản phẩm thật hơn
Một robot nhỏ có thể chạy được là một chuyện. Nhưng để nó tạo cảm giác như một sản phẩm hoàn chỉnh, phần UI đóng vai trò rất lớn.
Nếu Mochi chỉ hiển thị một ảnh tĩnh, người dùng sẽ thấy nó giống một món đồ chơi đơn giản. Nhưng nếu Mochi có animation mượt, chuyển biểu cảm tự nhiên, phản hồi khi chạm, báo pin yếu, báo đang sạc, báo đang kết nối và có các trạng thái cảm xúc rõ ràng, trải nghiệm sẽ khác hẳn.
LVGL giúp sắp xếp các chi tiết đó có tổ chức hơn. Thay vì dồn mọi thứ vào những hàm vẽ rời rạc, mình có thể tách giao diện thành screen, component và state.
Ví dụ, Mochi có thể có một screen chính để hiển thị khuôn mặt, một screen cấu hình, một screen báo lỗi, một screen sạc pin và một screen sleep. Mỗi screen lại có các component riêng như mặt robot, icon pin, icon Wi-Fi, nút bấm hoặc dòng trạng thái.

Biến mô hình Robot Mochi đơn giản trở thành một trợ lý hoàn hảo
Cách tổ chức này rất quan trọng nếu Mochi sau này phát triển thành nhiều phiên bản khác nhau như Mochi Basic, Mochi Car, Mochi Desk, Mochi Voice hoặc Mochi AI Assistant.
Khi nào Mochi nên dùng LVGL?
Không phải lúc nào Mochi cũng bắt buộc phải dùng LVGL. Nếu phiên bản đầu tiên chỉ dùng OLED 128x64 để hiển thị vài biểu cảm đơn giản, dùng bitmap hoặc frame animation với thư viện nhẹ hơn có thể là lựa chọn nhanh và dễ hơn.
Trong trường hợp đó, các thư viện như Adafruit SSD1306, U8g2 hoặc driver OLED tự viết có thể đủ dùng. Code sẽ nhẹ hơn, ít cấu hình hơn và dễ chạy trên các board nhỏ như ESP32-C3.
Tuy nhiên, LVGL sẽ phù hợp hơn nếu Mochi bắt đầu có màn hình màu, nhiều màn hình giao diện, icon trạng thái, menu cấu hình, cảm ứng, animation phức tạp hoặc cần mở rộng lâu dài.
Với Mochi, hướng hợp lý là chia thành hai nhánh. Phiên bản OLED 128x64 cơ bản có thể dùng thư viện nhẹ để hiển thị bitmap hoặc frame GIF. Phiên bản màn TFT màu hoặc màn cảm ứng nên cân nhắc dùng LVGL ngay từ đầu để dễ mở rộng UI sau này.
Gợi ý kiến trúc UI cho Mochi
Một kiến trúc đơn giản cho Mochi có thể chia thành ba lớp chính.

Kiến trúc tổng thể của tầng ui cho Robot Mochi sử dụng lvgl
Lớp đầu tiên là display backend. Lớp này phụ trách giao tiếp với màn hình thông qua các driver như ST7789, SSD1306, GC9A01 hoặc ILI9341. Mục tiêu là giúp project có thể đổi màn hình mà không phải viết lại toàn bộ phần UI.
Lớp thứ hai là UI framework. Nếu dùng LVGL, đây là nơi khởi tạo LVGL, tạo buffer, đăng ký display driver, input driver và timer tick. Lớp này đóng vai trò trung gian giữa logic giao diện và phần cứng hiển thị.
Lớp thứ ba là Mochi UI logic. Lớp này quản lý các trạng thái như idle, happy, sad, angry, sleepy, charging, low battery, listening, talking hoặc thinking. Mỗi trạng thái sẽ quyết định biểu cảm nào được hiển thị, animation nào chạy và icon nào xuất hiện.
Cách chia này giúp Mochi không bị phụ thuộc quá chặt vào một loại màn hình hay một kiểu giao diện duy nhất. Khi đổi từ OLED sang TFT, phần display backend có thể thay đổi, nhưng logic UI của Mochi vẫn có thể giữ lại phần lớn.
Ví dụ các trạng thái UI của Mochi
Một hệ thống UI cho Mochi có thể bắt đầu từ vài trạng thái đơn giản.

Hiển thị trạng thái của Mochi với LVGL
Ở trạng thái idle, Mochi hiển thị khuôn mặt bình thường và thỉnh thoảng có animation chớp mắt. Khi người dùng chạm vào robot, trạng thái có thể chuyển sang happy hoặc surprised. Khi pin yếu, Mochi chuyển sang low battery và hiển thị icon cảnh báo nhỏ. Khi đang sạc, khuôn mặt có thể dịu hơn kèm icon pin đang sạc. Khi robot đang lắng nghe, màn hình có thể hiển thị hiệu ứng sóng âm hoặc biểu cảm tập trung. Khi robot đang phản hồi, Mochi có thể chuyển sang trạng thái talking.
Những trạng thái này không quá phức tạp, nhưng nếu được tổ chức tốt, chúng sẽ làm Mochi có cảm giác sống động hơn rất nhiều.
Những điểm cần chú ý khi dùng LVGL
Khi dùng LVGL trên vi điều khiển, cần chú ý đến RAM, kích thước buffer, tốc độ bus màn hình và cách cập nhật giao diện.
Không nên render toàn màn hình quá thường xuyên nếu màn hình lớn và bus truyền dữ liệu chậm. Nên tối ưu asset hình ảnh, giảm kích thước icon, dùng màu phù hợp với màn hình và tránh animation quá nặng.
Với ESP32, nếu dùng màn TFT qua SPI, bạn nên ưu tiên SPI tốc độ cao và buffer hợp lý. ESP32-S3 cho mình nhiều không gian hơn với UI màu, animation và màn hình độ phân giải cao. Còn với ESP32-C3, giao diện nên gọn hơn để tránh thiếu RAM hoặc refresh chậm.
Nếu dùng OLED đen trắng như SSD1306, cần cân nhắc kỹ hơn. LVGL vẫn có thể dùng, nhưng không phải lúc nào cũng là lựa chọn nhẹ nhất. Với màn OLED nhỏ, đôi khi bitmap/frame animation trực tiếp sẽ thực tế hơn.

LVGL lập trình UI cho ra những sản phẩm đẹp mắt, mang tính chuyên nghiệp cao
Kết luận
LVGL không phải là lựa chọn bắt buộc cho mọi phiên bản Mochi, nhưng nó là một nền tảng rất đáng học nếu muốn xây dựng giao diện bài bản cho robot.
Với Mochi robot, LVGL có thể giúp biến phần hiển thị từ một màn hình emoji đơn giản thành một hệ thống UI có trạng thái, animation, phản hồi và khả năng mở rộng. Phiên bản đầu tiên có thể chỉ cần OLED và bitmap đơn giản, nhưng khi Mochi tiến tới màn TFT màu, cảm ứng hoặc AI assistant, LVGL sẽ trở thành một lựa chọn rất hợp lý.
Nếu xem Mochi là một sản phẩm dài hạn chứ không chỉ là một project thử nghiệm, việc tìm hiểu LVGL từ sớm sẽ giúp phần UI sạch hơn, dễ mở rộng hơn và gần với tư duy phát triển sản phẩm nhúng thực tế hơn.
Đọc thêm liên quan
Chia sẻ
Tiếp tục khám phá
Đọc tiếp
Bài viết liên quan
MEMS mic thực sự là gì? Từ màng rung silicon đến I2S trên ESP32
Tìm hiểu microphone MEMS, khác biệt analog, PDM, I2S, thông số quan trọng và lỗi PCB, nguồn, acoustic port khi dùng với ESP32.
ESP32-C3 hay ESP32-S3: Nên chọn chip nào cho robot có màn hình và âm thanh?
So sánh ESP32-C3 và ESP32-S3 theo GPIO, RAM, PSRAM, USB, I2S và khả năng chạy LVGL, kèm lựa chọn cụ thể cho Mochi cơ bản và Mochi AI.
Kiến trúc phần cứng hoàn chỉnh cho một robot Mochi dùng ESP32-S3
Phân tích các khối phần cứng chính của robot Mochi dùng ESP32-S3: màn hình, touch, microphone I2S, amplifier, loa, pin, sạc, nguồn và lưu ý chọn GPIO.