Brazo Robótico Tối Giản Dễ In 3D với Micro Servo MG90

Mô hình cánh tay robot tối giản, dễ in 3D và lắp ráp với 3 bậc tự do, sử dụng micro servo MG90. Thiết kế tối ưu hóa kẹp, đi kèm hai tùy chọn đế cho từng loại servo MG90. Tích hợp mạch PCB với ESP32, màn hình OLED và chiết áp cho phép điều khiển chính xác. Bao gồm mã Arduino mẫu để kiểm tra chức năng.

👁️
911
Lượt Xem
❤️
23
Lượt Thích
📥
190
Lượt Tải
Cập Nhật Dec 26, 2025
Chi tiết
Tải xuống
Bình Luận
Khoe bản in
Remix

Mô tả

Nội dung được dịch bằng AI

Cánh tay robot tối giản với micro servo MG90, dễ in và lắp ráp, có 3 bậc tự do chưa tính servo của bộ gắp.

Thông số kỹ thuật
  • Kẹp được tối ưu hóa, thiết kế mới này loại bỏ các bộ phận không cần thiết, giúp quá trình in 3D nhanh hơn và dễ dàng hơn, cùng việc lắp ráp không gặp rắc rối.
  • Điều quan trọng cần lưu ý là hiện tại có hai phiên bản của micro servo MG90 trên thị trường, có một số khác biệt giữa chúng. Bộ phận duy nhất trong thiết kế của chúng tôi bị ảnh hưởng bởi sự khác biệt này là đế. Do đó, chúng tôi đã tạo ra hai thiết kế riêng biệt cho đế: Đế 1 v4 và Đế 2 v4. Tất cả các bộ phận khác của cánh tay robot đều hoạt động hoàn hảo với cả hai loại servo mà không cần điều chỉnh thêm.
  • Một mạch PCB với ESP32, màn hình OLED và chiết áp tuyến tính đã được triển khai để điều khiển các servo. Một tệp .zip đính kèm bao gồm thiết kế PCB ở định dạng GERBER để sản xuất.
  • Trong các tệp STL, bạn sẽ tìm thấy một đế chung được thiết kế cho cánh tay robot và mạch PCB. Cánh tay được gắn vào đế này bằng vít M4 dài 8mm, trong khi PCB sử dụng vít M3 dài 5mm. Đế được thiết kế đặc biệt để các vít này có thể ấn chặt vào, tự tạo ren trong nhựa và đảm bảo độ bám chắc chắn.
  • Đi kèm với các tệp là chương trình thử nghiệm cho Arduino. Mã này sẽ cho phép bạn dễ dàng kiểm tra hoạt động chính xác của cánh tay robot và mạch PCB. Bạn có thể điều khiển trực tiếp chuyển động của các servo bằng chiết áp tuyến tính và xem góc của từng servo theo thời gian thực thông qua màn hình OLED.
  • Mạch PCB có thể được cấp nguồn bằng pin hoặc bộ nguồn DC ngoài từ 5V đến 24V.
Sơ đồ Mạch PCB Cánh Tay Robot Racbots

Thiết kế Vật lý Mạch PCB Cánh Tay Robot Racbots

Mã Arduino Cánh Tay Robot Racbots

#include <ESP32Servo.h>
#include <Wire.h> // Để giao tiếp I2C với OLED
#include <Adafruit_GFX.h> 
#include <Adafruit_SSD1306.h> 

// --- Định nghĩa Chân (Pins) ---

// Chân của Servo
#define SERVO_BASE_PIN   16
#define SERVO_BRAZO1_PIN 17
#define SERVO_BRAZO2_PIN 18
#define SERVO_PINZA_PIN  19

// Chân của Chiết áp (Potentiometers)
#define POT_BASE_PIN    33
#define POT_BRAZO1_PIN  25
#define POT_BRAZO2_PIN  26
#define POT_PINZA_PIN   27

// Chân cho OLED (I2C)
#define OLED_SDA_PIN    21
#define OLED_SCL_PIN    22
#define SCREEN_WIDTH    128 // Chiều rộng màn hình OLED (pixel)
#define SCREEN_HEIGHT   32  // Chiều cao màn hình OLED (pixel)
#define OLED_RESET      -1  // Chân reset (hoặc -1 nếu nối chung VCC)

// --- Đối tượng Servo ---
Servo servoBase;
Servo servoBrazo1;
Servo servoBrazo2;
Servo servoPinza;

// --- Đối tượng OLED ---
// Địa chỉ I2C phổ biến là 0x3C, nhưng một số mẫu có thể dùng 0x3D
// Nếu không hoạt động, hãy thử display.begin(SSD1306_SWITCHCAPVCC, 0x3D)
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);

// --- Biến lưu trữ góc của servo ---
int anguloBase = 90;
int anguloBrazo1 = 90;
int anguloBrazo2 = 90;
int anguloPinza = 90;

// Biến lưu trữ góc mục tiêu (đọc từ chiết áp)
int anguloObjetivoBase = 90;
int anguloObjetivoBrazo1 = 90;
int anguloObjetivoBrazo2 = 90;
int anguloObjetivoPinza = 90;

// --- Tham số ổn định và tốc độ ---
const int THRESHOLD = 2;   // Ngưỡng thay đổi: servo chỉ di chuyển nếu góc mục tiêu thay đổi quá giá trị này (độ).
const int STEP_SIZE = 3;   // Kích thước bước cho chuyển động nhanh hơn.
const int UPDATE_DELAY_MS = 5; // Độ trễ nhỏ hơn giữa các lần cập nhật để phản hồi nhanh hơn.

void setup() {
  Serial.begin(115200); // Khởi tạo giao tiếp serial để gỡ lỗi

  // --- Khởi tạo OLED (phải là đầu tiên để hiển thị thông báo) ---
  Wire.begin(OLED_SDA_PIN, OLED_SCL_PIN); // Khởi tạo I2C với các chân đã định nghĩa
  if (!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) { // Địa chỉ I2C phổ biến 0x3C
    Serial.println(F("SSD1306 allocation failed"));
    for (;;); // Không tiếp tục nếu khởi tạo thất bại
  }

  display.display(); // Hiển thị bộ đệm khởi động (logo Adafruit)
  // Không có delay ở đây để thông báo xuất hiện ngay trên logo
  display.clearDisplay(); // Xóa bộ đệm

  // --- Thông báo chào mừng "RACBOTS INDUSTRIES" ---
  display.setTextSize(2); // Cỡ chữ lớn hơn cho "RACBOTS"
  display.setTextColor(SSD1306_WHITE); // Màu chữ

  display.setCursor(0, 0); // Vị trí cho "RACBOTS"
  display.println("RACBOTS");

  display.setTextSize(1); // Cỡ chữ nhỏ hơn cho "INDUSTRIES"
  display.setCursor(0, 16); // Vị trí cho "INDUSTRIES" (dưới "RACBOTS")
  display.println("INDUSTRIES");

  display.display(); // Hiển thị thông báo lên màn hình
  delay(2500); // Chờ 2.5 giây (2500 mili giây)

  display.clearDisplay(); // Xóa màn hình sau thông báo

  // --- Khởi tạo Servo ---
  servoBase.attach(SERVO_BASE_PIN);
  servoBrazo1.attach(SERVO_BRAZO1_PIN);
  servoBrazo2.attach(SERVO_BRAZO2_PIN);
  servoPinza.attach(SERVO_PINZA_PIN);

  // Di chuyển servo đến vị trí ban đầu (trong phạm vi mới của chúng)
  anguloBase = 90;
  anguloBrazo1 = 60;
  anguloBrazo2 = 90;
  anguloPinza = 130;

  servoBase.write(anguloBase);
  servoBrazo1.write(anguloBrazo1);
  servoBrazo2.write(anguloBrazo2);
  servoPinza.write(anguloPinza);

  // Khởi tạo góc mục tiêu với vị trí ban đầu
  anguloObjetivoBase = anguloBase;
  anguloObjetivoBrazo1 = anguloBrazo1;
  anguloObjetivoBrazo2 = anguloBrazo2;
  anguloObjetivoPinza = anguloPinza;
}

void loop() {
  // --- Đọc Chiết áp và Ánh xạ đến Góc Mục tiêu ---
  // ADC của ESP32 có độ phân giải 12 bit (0-4095)

  int valPotBase = analogRead(POT_BASE_PIN);
  // Đế giờ quay về toàn bộ dải 0 đến 180 độ
  anguloObjetivoBase = map(valPotBase, 0, 4095, 0, 180);

  int valPotBrazo1 = analogRead(POT_BRAZO1_PIN);
  // Giới hạn tay 1 từ 0 đến 120
  anguloObjetivoBrazo1 = map(valPotBrazo1, 0, 4095, 0, 120);

  int valPotBrazo2 = analogRead(POT_BRAZO2_PIN);
  // Tay 2 giữ nguyên toàn bộ dải 0 đến 180
  anguloObjetivoBrazo2 = map(valPotBrazo2, 0, 4095, 0, 180);

  int valPotPinza = analogRead(POT_PINZA_PIN);
  // Giới hạn kẹp từ 80 đến 180 (đầu dưới 80, đầu trên 180)
  anguloObjetivoPinza = map(valPotPinza, 0, 4095, 80, 180);


  // --- Di chuyển Servo Mượt mà với Ngưỡng ---

  // Servo Đế
  if (abs(anguloObjetivoBase - anguloBase) > THRESHOLD) {
    if (anguloObjetivoBase > anguloBase) {
      anguloBase += STEP_SIZE;
    } else {
      anguloBase -= STEP_SIZE;
    }
    // Đảm bảo không vượt quá mục tiêu cuối cùng
    if ((anguloBase > anguloObjetivoBase && STEP_SIZE > 0) || (anguloBase < anguloObjetivoBase && STEP_SIZE < 0)) {
      anguloBase = anguloObjetivoBase;
    }
    servoBase.write(anguloBase);
  }

  // Servo Tay 1
  if (abs(anguloObjetivoBrazo1 - anguloBrazo1) > THRESHOLD) {
    if (anguloObjetivoBrazo1 > anguloBrazo1) {
      anguloBrazo1 += STEP_SIZE;
    } else {
      anguloBrazo1 -= STEP_SIZE;
    }
    if ((anguloBrazo1 > anguloObjetivoBrazo1 && STEP_SIZE > 0) || (anguloBrazo1 < anguloObjetivoBrazo1 && STEP_SIZE < 0)) {
      anguloBrazo1 = anguloObjetivoBrazo1;
    }
    servoBrazo1.write(anguloBrazo1);
  }

  // Servo Tay 2
  if (abs(anguloObjetivoBrazo2 - anguloBrazo2) > THRESHOLD) {
    if (anguloObjetivoBrazo2 > anguloBrazo2) {
      anguloBrazo2 += STEP_SIZE;
    } else {
      anguloBrazo2 -= STEP_SIZE;
    }
    if ((anguloBrazo2 > anguloObjetivoBrazo2 && STEP_SIZE > 0) || (anguloBrazo2 < anguloObjetivoBrazo2 && STEP_SIZE < 0)) {
      anguloBrazo2 = anguloObjetivoBrazo2;
    }
    servoBrazo2.write(anguloBrazo2);
  }

  // Servo Kẹp
  if (abs(anguloObjetivoPinza - anguloPinza) > THRESHOLD) {
    if (anguloObjetivoPinza > anguloPinza) {
      anguloPinza += STEP_SIZE;
    } else {
      anguloPinza -= STEP_SIZE;
    }
    if ((anguloPinza > anguloObjetivoPinza && STEP_SIZE > 0) || (anguloPinza < anguloObjetivoPinza && STEP_SIZE < 0)) {
      anguloPinza = anguloObjetivoPinza;
    }
    servoPinza.write(anguloPinza);
  }

  // --- Hiển thị Giá trị lên OLED ---
  display.clearDisplay(); // Xóa bộ đệm để vẽ lại

  display.setCursor(0, 0); // Vị trí con trỏ ban đầu (x, y)
  display.print("Base: ");
  display.print(anguloBase);
  display.println(" deg");

  display.print("Brazo1: ");
  display.print(anguloBrazo1);
  display.println(" deg");

  display.print("Brazo2: ");
  display.print(anguloBrazo2);
  display.println(" deg");

  display.print("Pinza: ");
  display.print(anguloPinza);
  display.println(" deg");

  display.display(); // Cập nhật màn hình với những gì đã vẽ trong bộ đệm

  // Tạm dừng nhỏ để tránh đọc và cập nhật quá nhanh
  delay(UPDATE_DELAY_MS);
}

Giấy phép

Tác phẩm này được cấp phép theo

Creative Commons — Attribution

CC-BY

Yêu cầu ghi công
Remix & phái sinh Được phép
Sử dụng thương mại Được phép

File mô hình

TẤT CẢ FILE MÔ HÌNH (10 Tập tin)
Đang tải files, vui lòng chờ...
Vui lòng đăng nhập để bình luận.

Chưa có bình luận nào. Hãy là người đầu tiên!

Vui lòng đăng nhập để khoe bản in của bạn.

Chưa có bản in nào được khoe. Hãy là người đầu tiên!

Remix (0)