IoTLabs

Nghiên cứu, Sáng tạo và Thử nghiệm

Điều Khiển Servo Motor với Arduino — Góc Quay Chính Xác từ 0° đến 180°

Servo Motor Là Gì?

Servo motor là động cơ điều khiển vị trí góc — khác với DC motor chỉ quay tròn, servo giữ ở một góc cụ thể với độ chính xác cao.

Cấu tạo:

  • Động cơ DC nhỏ
  • Hộp số giảm tốc (gear box)
  • Mạch phản hồi vị trí (encoder/potentiometer)
  • Bộ điều khiển PID tích hợp

Thông số servo SG90 (phổ biến nhất, giá ~20.000 VNĐ):

Thông sốGiá trị
Góc quay0° – 180°
Điện áp4.8V – 6V
Mô-men1.8 kg·cm (4.8V)
Tốc độ0.1s/60°
Màu dâyVàng=Signal, Đỏ=VCC, Nâu=GND

Nguyên Lý Điều Khiển — Tín Hiệu PWM

Servo nhận tín hiệu PWM 50Hz (chu kỳ 20ms), độ rộng xung xác định góc:

Góc   0°: xung 1.0ms trong 20ms → 5% duty cycle
Góc  90°: xung 1.5ms trong 20ms → 7.5% duty cycle
Góc 180°: xung 2.0ms trong 20ms → 10% duty cycle

Arduino dùng Timer1 (pin D9, D10) để tạo tín hiệu này — thư viện Servo.h lo hết phần này.

📷 [Hình minh hoạ: Sơ đồ Arduino Uno kết nối servo SG90 — PWM signal pin 9, VCC đỏ, GND đen, tín hiệu PWM pulse diagram 1ms–2ms, nền trắng]

Kết Nối Phần Cứng

Servo Vàng (Signal) ── D9 Arduino
Servo Đỏ   (VCC)    ── 5V Arduino
Servo Nâu  (GND)    ── GND Arduino

Lưu ý: SG90 kéo ~200–250 mA khi chạy. Nếu dùng nhiều servo (2+) cần nguồn ngoài 5V — không lấy hết từ USB vì Arduino chỉ cung cấp tối đa 500 mA.

Thư Viện Servo.h

Servo.h là thư viện tích hợp sẵn trong Arduino IDE — không cần cài thêm.

#include <Servo.h>

Hàm chính:

HàmChức năng
myServo.attach(pin)Kết nối servo với chân PWM
myServo.write(angle)Quay đến góc (0–180)
myServo.writeMicroseconds(us)Điều khiển trực tiếp bằng microsecond
myServo.read()Đọc góc hiện tại
myServo.detach()Ngắt tín hiệu (servo tự do)

Code Cơ Bản

Quét Góc 0° → 180° → 0°

#include <Servo.h>

Servo myServo;
const int SERVO_PIN = 9;

void setup() {
  myServo.attach(SERVO_PIN);
  Serial.begin(9600);
}

void loop() {
  // Quét từ 0° đến 180°
  for (int angle = 0; angle <= 180; angle += 1) {
    myServo.write(angle);
    delay(15); // ~15ms để servo đến vị trí
    Serial.println(angle);
  }

  // Quét ngược từ 180° về 0°
  for (int angle = 180; angle >= 0; angle -= 1) {
    myServo.write(angle);
    delay(15);
  }
}

Điều Khiển Bằng Biến Trở

#include <Servo.h>

Servo myServo;
const int SERVO_PIN = 9;
const int POT_PIN = A0;

void setup() {
  myServo.attach(SERVO_PIN);
  Serial.begin(9600);
}

void loop() {
  int rawPot = analogRead(POT_PIN);              // 0–1023
  int angle = map(rawPot, 0, 1023, 0, 180);     // Chuyển sang 0–180°

  myServo.write(angle);

  Serial.print("Pot: "); Serial.print(rawPot);
  Serial.print(" → Angle: "); Serial.print(angle);
  Serial.println("°");

  delay(15);
}

Xoay biến trở — servo quay theo thời gian thực!

Điều Khiển Qua Serial

#include <Servo.h>

Servo myServo;

void setup() {
  myServo.attach(9);
  Serial.begin(9600);
  Serial.println("Nhập góc (0-180) và Enter:");
}

void loop() {
  if (Serial.available() > 0) {
    int angle = Serial.parseInt(); // Đọc số nguyên từ Serial

    if (angle >= 0 && angle <= 180) {
      myServo.write(angle);
      Serial.print("Đã quay đến: ");
      Serial.print(angle);
      Serial.println("°");
    } else {
      Serial.println("Góc hợp lệ: 0–180");
    }
  }
}

Gõ số trong Serial Monitor → servo quay đến góc đó.

Nhiều Servo

Một Arduino Uno có thể điều khiển đến 12 servo (thư viện Servo.h chiếm dụng Timer1, ảnh hưởng PWM trên D9, D10):

#include <Servo.h>

Servo servo1, servo2, servo3;

void setup() {
  servo1.attach(9);
  servo2.attach(10);
  servo3.attach(11);
}

void loop() {
  // Tất cả về 0°
  servo1.write(0); servo2.write(0); servo3.write(0);
  delay(1000);

  // Tất cả về 90°
  servo1.write(90); servo2.write(90); servo3.write(90);
  delay(1000);

  // Tất cả về 180°
  servo1.write(180); servo2.write(180); servo3.write(180);
  delay(1000);
}

Ứng Dụng Thực Tế

Dự ánServo dùng
Cánh tay robot3–6 servo ở các khớp
Pan-tilt camera2 servo (ngang + dọc)
Khóa cửa1 servo xoay chốt
Cánh máy bay RC4+ servo điều khiển aileron, elevator, rudder
Búp bê robotServo điều khiển miệng, mắt

Tổng Kết

#include <Servo.h>
Servo myServo;

myServo.attach(9);      // Gắn vào chân 9
myServo.write(90);      // Quay đến 90°
myServo.read();         // Đọc góc hiện tại
myServo.detach();       // Ngắt tín hiệu

Bài tiếp theo: LCD 16×2 với I2C — hiển thị text, số và ký tự custom trên màn hình 2 dòng × 16 ký tự. Chuẩn bị module LCD và board I2C adapter.