Hướng dẫn toàn tập chế tạo Cánh tay Robot EEZYbotARM: Từ lý thuyết cơ điện tử đến thực hành lắp ráp
Dự án EEZYbotARM là một trong những thiết kế mã nguồn mở kinh điển và chuẩn mực nhất dành cho giới chế tạo (Maker) và môi trường giáo dục STEM. Được thiết kế bởi tác giả Carlo Franciscone (daGHIZmo), dự án này sử dụng công nghệ in 3D kết hợp với linh kiện điện tử phổ thông để tạo ra một cánh tay robot 4 bậc tự do (4 DOF).
Bài viết này sẽ phân tích chi tiết nền tảng lý thuyết và cung cấp hướng dẫn từng bước để bạn có thể tự chế tạo thành công hệ thống này.
Phần 1: Phân tích Nền tảng Lý thuyết Cơ điện tử
Trước khi bắt tay vào lắp ráp, việc hiểu rõ tại sao cánh tay robot hoạt động ổn định là điều kiện tiên quyết đối với mọi kỹ sư.
1. Cơ chế Truyền động Thanh giằng song song (Parallel Linkage Mechanism) Khác với các cánh tay robot công nghiệp nối tiếp (nơi động cơ được đặt ngay tại các khớp khuỷu tay), EEZYbotARM sử dụng cơ chế thanh giằng song song.
- Tối ưu hóa trọng tâm: Thiết kế này cho phép dời các động cơ Servo (vật nặng nhất) về sát bệ đế (Base). Điều này làm giảm đáng kể mô-men quán tính khi robot vươn xa, giúp cánh tay không bị đổ gập hoặc rung lắc do quá tải trọng lượng.
- Ổn định góc tác động: Nhờ hệ thống hình bình hành cơ học, phần đầu gắp (Gripper) luôn được giữ ở một góc cố định (thường là song song với mặt bàn) bất kể tay robot vươn cao hay hạ thấp. Điều này làm giảm sự phức tạp của thuật toán Động học nghịch (Inverse Kinematics) khi gắp vật thể.
2. Lý thuyết Tín hiệu PWM trên RC Servo Động cơ sử dụng trong dự án là RC Servo. Khác với động cơ DC thông thường cấp điện là quay liên tục, Servo được điều khiển bằng tín hiệu Điều chế độ rộng xung (PWM – Pulse Width Modulation).
- Vi điều khiển (Arduino) sẽ phát ra một chuỗi xung với tần số cố định (thường là 50Hz, chu kỳ 20ms).
- Độ rộng của “mức cao” trong một chu kỳ (từ 1ms đến 2ms) sẽ quyết định góc quay của Servo từ 0 đến 180 độ. Mạch điều khiển kín (Closed-loop) bên trong Servo sẽ liên tục đọc biến trở nội bộ để giữ động cơ cứng tại góc mục tiêu này.
Phần 2: Danh sách Vật tư (Bill of Materials – BOM)
Để hoàn thiện dự án, bạn cần chuẩn bị các nhóm vật tư sau:
1. Khối Cơ khí và In 3D
- Chi tiết nhựa: Tải file STL (link ở cuối bài) và in 3D. Khuyến nghị sử dụng nhựa PLA hoặc PETG, độ điền đầy (Infill) tối thiểu 25% – 30%, độ dày thành (Wall thickness) 3 lớp để đảm bảo độ cứng vững cho các tay đòn. Dự án được thiết kế không cần in support vật liệu hỗ trợ.
- Ốc vít (Cực kỳ quan trọng):
- Bulong M3 và M4 với các chiều dài khác nhau (10mm, 12mm, 16mm, 20mm).
- Đai ốc chống trượt (Nyloc Nuts): Bắt buộc phải sử dụng đai ốc có vòng cao su chống trượt ở bên trong cho tất cả các khớp chuyển động.
- Vòng đệm (Washers) kim loại M3 và M4 để giảm ma sát giữa các chi tiết nhựa.
2. Khối Điện tử
- Vi điều khiển: 1x Bo mạch Arduino UNO R3 hoặc Arduino Nano.
- Động cơ: 4x Động cơ RC Servo. Khuyến nghị sử dụng loại MG90S (có bánh răng kim loại) thay vì SG90 (bánh răng nhựa) để tránh hiện tượng mẻ răng khi gắp vật nặng. (Nếu làm bản MK2 lớn hơn, cần dùng Servo MG996R).
- Nguồn điện: 1x Module nguồn giáng áp (LM2596 hoặc MP1584) hoặc Adapter 5V – 3A độc lập. Tuyệt đối không lấy nguồn 5V từ chân VCC của Arduino để nuôi 4 Servo, dòng khởi động cao sẽ làm cháy bo mạch ngay lập tức.
- Giao diện điều khiển: 2x Module Joystick Analog (giống tay cầm PS2) hoặc 4x Biến trở xoay (Potentiometer) 10k Ohm.
Phần 3: Hướng dẫn Lắp ráp Cơ khí và Đấu nối Điện
Bước 1: Xử lý nguội chi tiết in 3D Máy in 3D FDM thường có sai số dung sai (nhựa co ngót). Bạn cần dùng mũi khoan 3mm và 4mm để nong lại (khoét sạch) tất cả các lỗ bắt ốc trên chi tiết nhựa. Lỗ phải đủ rộng để ốc vít có thể xoay trơn tru bên trong mà không bị kẹt.
Bước 2: Căn chuẩn trung tâm động cơ (Centering Servos) – Bước Bắt Buộc Trước khi gắn các ngàm nhựa (Horn) vào Servo, bạn phải cấp nguồn và xuất code cho toàn bộ Servo quay về góc 90 độ (góc trung tâm). Nếu bỏ qua bước này, khi robot vận hành sẽ vượt quá hành trình cơ học, gây kẹt và cháy động cơ.
Bước 3: Lắp ráp các khớp nối
- Lắp theo thứ tự từ dưới lên: Đế xoay (Base) -> Trục vai (Shoulder) -> Cánh tay (Arm) -> Đầu gắp (Gripper).
- Kỹ thuật siết ốc: Tại các khớp nối, hãy lồng vòng đệm kim loại vào giữa hai chi tiết nhựa. Dùng tuốc nơ vít siết đai ốc chống trượt (Nyloc nut) cho đến khi hai chi tiết ép chặt vào nhau (cứng ngắc). Sau đó, nới lỏng đai ốc ngược lại khoảng 1/4 đến 1/2 vòng. Kiểm tra bằng tay: khớp nối phải đung đưa trơn tru nhưng không được lỏng lẻo lắc ngang.
Bước 4: Đấu nối điện tử (Wiring)
- Đường tín hiệu: Cấp chân tín hiệu (thường là dây màu cam/vàng) của 4 Servo vào 4 chân phát xung PWM của Arduino (ví dụ: chân số 3, 5, 6, 9). Chân tín hiệu của Joystick nối vào các chân Analog (A0, A1, A2, A3).
- Đường Nguồn: Nối tất cả dây Đỏ (VCC) và Nâu/Đen (GND) của 4 Servo vào nguồn 5V – 3A rời. Nối chung chân GND của nguồn rời này với chân GND của Arduino để đồng bộ mức điện áp tham chiếu.
Phần 4: Logic Lập trình Điều khiển cơ bản
Môi trường phát triển: Arduino IDE. Sử dụng thư viện tiêu chuẩn Servo.h.
Thuật toán điều khiển thủ công qua Joystick bao gồm 3 bước thực thi liên tục trong vòng lặp (Loop):
- Đọc tín hiệu (Read Analog): Arduino dùng bộ chuyển đổi ADC (Analog-to-Digital Converter) để đọc điện áp từ Joystick. Giá trị trả về nằm trong dải từ 0 đến 1023 (đối với ADC 10-bit). Khi để thả tự do, giá trị nằm ở khoảng giữa (khoảng 512).
- Nội suy dữ liệu (Mapping): Sử dụng hàm
map(giá_trị_đọc, 0, 1023, 0, 180)để quy đổi tuyến tính dải giá trị điện áp thành dải góc quay của Servo (từ 0 đến 180 độ). - Thực thi và Lọc nhiễu: Xuất giá trị góc đã quy đổi ra Servo thông qua lệnh
servo.write(). Lưu ý, cần thêm một đoạn delay ngắn (khoảng 15-20ms) để động cơ có thời gian cơ học dịch chuyển đến góc mục tiêu. Việc bổ sung thuật toán lọc nhiễu trung bình (Moving Average) cho tín hiệu Analog sẽ giúp cánh tay không bị giật (jitter).
Nguồn tham khảo và Bản vẽ thiết kế
Để tải file STL 3D gốc và xem hình ảnh hướng dẫn cơ khí trực quan từ tác giả daGHIZmo, bạn đọc vui lòng truy cập các liên kết chính thức sau trên Instructables:
- EEZYbotARM (Bản tiêu chuẩn dùng Servo nhỏ): https://www.instructables.com/EEZYbotARM/
- EEZYbotARM MK2 (Bản nâng cấp dùng Servo công suất lớn): https://www.instructables.com/EEZYbotARM-Mk2-3D-Printed-Robot/
Phần bổ sung thêm :
Nâng cấp Code Điều khiển – Xử lý nhiễu tín hiệu (Jitter) bằng Phần mềm
Nếu bạn sử dụng trực tiếp đoạn code mẫu trên Instructables (chỉ dùng hàm analogRead và map), bạn sẽ lập tức gặp phải một hiện tượng cực kỳ khó chịu: Servo liên tục phát ra tiếng kêu “è è” và cánh tay bị giật cục (jitter) ngay cả khi bạn không hề chạm tay vào Joystick.
Nguyên nhân do đâu? Joystick Analog giá rẻ thực chất là hai biến trở. Tín hiệu điện áp trả về bộ chuyển đổi ADC của Arduino không bao giờ là một đường thẳng hoàn hảo. Ngay cả khi đứng yên ở trung tâm (giá trị lý tưởng là 512), tín hiệu thực tế sẽ luôn dao động ngẫu nhiên (ví dụ: nhảy liên tục giữa 508, 510, 515). Hàm map lập tức quy đổi sự dao động nhỏ này thành các sai số góc quay (ví dụ: nhảy từ 90 độ sang 91 độ rồi về 89 độ), khiến động cơ Servo bị ép phải xoay qua xoay lại liên tục với tốc độ cao.
Giải pháp khắc phục: Để giải quyết bài toán này, chúng ta cần bổ sung hai thuật toán phần mềm vào code gốc:
- Deadband (Vùng chết): Ép vi điều khiển bỏ qua các dao động nhỏ xung quanh điểm trung tâm.
- Exponential Moving Average – EMA (Bộ lọc trung bình hàm mũ): Làm mượt sự thay đổi đột ngột của tín hiệu, giúp cánh tay di chuyển êm ái hơn khi bạn gạt cần đột ngột.
Dưới đây là đoạn code chuẩn C++ đã được Banhangdientu.com tối ưu hóa (bản minh họa cho 1 trục Servo, bạn có thể nhân bản lên cho 4 trục):
C++
#include <Servo.h>
Servo servoBase; // Khai báo trục xoay đế
const int joyPin = A0; // Chân cắm tín hiệu Joystick
const int servoPin = 3; // Chân phát PWM ra Servo
// --- CÁC BIẾN CÀI ĐẶT BỘ LỌC ---
float smoothedJoyVal = 512.0; // Giá trị khởi tạo ở giữa
const float alpha = 0.1; // Hệ số lọc (từ 0.0 đến 1.0). Càng nhỏ thì chạy càng mượt nhưng phản hồi sẽ hơi trễ.
const int deadband = 15; // Khoảng chết (Sai số cho phép khi Joystick đứng yên)
void setup() {
servoBase.attach(servoPin);
// Đưa servo về góc 90 độ (trung tâm) ngay khi khởi động
servoBase.write(90);
delay(500); // Chờ servo ổn định vị trí
}
void loop() {
// 1. Đọc tín hiệu thô từ phần cứng
int rawJoyVal = analogRead(joyPin);
// 2. Thuật toán Deadband (Vùng chết)
// Nếu tín hiệu dao động nhỏ trong khoảng (512 - 15) đến (512 + 15), ta coi như bằng 512
if (abs(rawJoyVal - 512) < deadband) {
rawJoyVal = 512;
}
// 3. Thuật toán lọc nhiễu EMA (Lọc thông thấp)
// Công thức: Giá_trị_mới = (Hệ_số * Giá_trị_thô) + ((1 - Hệ_số) * Giá_trị_cũ)
smoothedJoyVal = (alpha * rawJoyVal) + ((1.0 - alpha) * smoothedJoyVal);
// 4. Quy đổi tín hiệu đã lọc sang góc Servo
int targetAngle = map(smoothedJoyVal, 0, 1023, 0, 180);
// 5. Khóa giới hạn hành trình (Bảo vệ cơ khí, tránh kẹt ngàm)
// Không cho phép servo chạy sát vách 0 độ và 180 độ
targetAngle = constrain(targetAngle, 10, 170);
// 6. Xuất tín hiệu góc cuối cùng ra động cơ
servoBase.write(targetAngle);
// Độ trễ ngắn để giảm tải cho vi điều khiển và chờ cơ khí dịch chuyển
delay(15);
}
Đánh giá hiệu quả: Sau khi nạp đoạn code này, bạn sẽ thấy hiện tượng “è è” của Servo biến mất hoàn toàn khi thả tay. Đồng thời, khi gạt Joystick thật nhanh từ trái qua phải, cánh tay robot sẽ di chuyển đuổi theo một cách mượt mà nhờ hệ số alpha tạo ra một độ trễ gia tốc (soft-start/soft-stop) mô phỏng chính xác quán tính cơ học trong thực tế.

Để lại một bình luận