Điều khiển module động cơ step 2 pha và thư viện

Mô tả dự án: 

Bài viết này đi  sâu vào tìm hiểu cấu tạo, cách thức điều khiển động cơ step 2 pha lưỡng cực trong ổ DVD/VCD.

Bên cạnh đó là xây dựng một mạch lái (ic driver) và sử dụng thư viện STEP_2_PHASE. 

Tìm hiểu chung

Mình sẽ nói sơ qua về cấu tạo.

Cấu tạo

  • Động cơ có stato gồm 2 cuộn dây pha (2 pha), là pha A(A+,A-) và pha B(B+, B-).
  • Đây là loại động cơ lưỡng cực: chiều dòng điện chạy qua cuộn dây thay đổi .( động cơ đơn cực là loại 3 hoặc 4 pha trong đó một đầu cực của các pha sẽ được nối chung lên KATOT hoặc ANOT).
  • Roto (phần quay): là nam châm vĩnh cửu có ít nhất 2 cực từ (N/S).

Điều khiển

Ví dụ đối với động cơ có roto là nam châm vĩnh cửu 1 cặp cực từ.

Điều khiển động cơ bằng cách thay đổi từ trường cùng lúc trên 2 cuộn stato, lực tương hỗ của từ trường trên stato (cuộn dây) và roto(nam châm) sẽ khiến trục roto bị lệch một góc tới vị trí cân bằng.

Khi đó góc điều khiển có độ chính xác 100%.

Một vòng quay của roto gồm 4 step:

STEP
Điện áp Pha A
Điện áp Pha B
1
+ 5v
+5v
2
+5v
-5v
3
-5v
-5v
4
-5v
+5v

Chú ý:

  • Một vòng quay của roto bắt buộc phải theo trình tự step.
  • Để điều khiển một step, ta phải đặt cùng lúc hai điện áp lên cả 2 pha.

Đảo chiều dòng điện bằng mạch cầu

Mạch cầu sử dụng khóa điện (tranzitor, JFET, MOSFET,Thyristor,..) giống như công tắc K chuyển mạch . (một cách có điều khiển).

Chúng ta cần 2 mạch cầu để điều khiển 2 pha của động cơ.

Sử dụng driver l293D

L293D thực chất chỉ là ic gồm 2 mạch cầu.

Mỗi mạch cầu lại gồm 2 bộ chuyển mạch.

Mình minh họa một bộ chuyển mạch như hình sau:

  • Khi cấp một điện áp logic mức cao vào cực input (5v) thì ở output sẽ được nối lên điện áp nguồn dương.
  • Khi cấp một điện áp logic mức thấp vào cực input (0v) thì ở output sẽ được nối xuống 0v.

Trên thực tế, các khóa điện tử làm từ vật liệu bán dẫn được phân cực, nên chiều dòng điện qua khóa điện là một chiều.

IC l293d có tổng cộng 4 bộ chuyển mạch như vậy với pinout như hình vẽ.

Đối với 2 chân Enable 1 và Enable 2:

  • Nối chân này lên 5v để điều khiển.
  • Nôi xuống 0v để ngăn không cho điều khiển. (Bất cứ sự thay đổi nào trên đầu IN đều không làm OUT thay đổi)

Test

Nối mạch test

Các bạn chú ý nguồn âm (GND) của arduino phải nối chung với GND của ic.

Viết chương trình

//code test này không an toàn khi sử dụng
// chỉ để test
#define in_A_1 4
#define in_A_2 5
#define in_B_1 6
#define in_B_2 7

void setup()
{
    pinMode(in_A_1, OUTPUT);
    pinMode(in_A_2, OUTPUT);
    pinMode(in_B_1, OUTPUT);
    pinMode(in_B_2, OUTPUT);
}
unsigned int time_delay = 10;
void loop()
{

    //step1
    //A+,B+
    digitalWrite(in_A_1, 1);
    digitalWrite(in_A_2, 0);
    digitalWrite(in_B_1, 1);
    digitalWrite(in_B_2, 0);
    delay(time_delay);

    //step2
    //A+,B-
    digitalWrite(in_A_1, 1);
    digitalWrite(in_A_2, 0);
    digitalWrite(in_B_1, 0);
    digitalWrite(in_B_2, 1);
    delay(time_delay);
    //step3
    //A-,B-
    digitalWrite(in_A_1, 0);
    digitalWrite(in_A_2, 1);
    digitalWrite(in_B_1, 0);
    digitalWrite(in_B_2, 1);
    delay(time_delay);
    //step4
    //A-,B+
    digitalWrite(in_A_1, 0);
    digitalWrite(in_A_2, 1);
    digitalWrite(in_B_1, 1);
    digitalWrite(in_B_2, 0);
    delay(time_delay);
}

Khi đó sơ đồ chuyển mạch như sau:

Như đã nói ở phần đầu, với động cơ có roto gồm 1 cặp cực từ thì động cơ sẽ quay một vòng với 4 step.

Trên thực tế,  động cơ (trong ổ DVD) có độ phân giải cao hơn, roto của nó có tới 5 cặp cực từ, khi đó nó cần tới 20 step để quay được 1 vòng.   

OK , vậy làm sao để cho nó quay ngược chiều ?

Đơn giản thôi, chúng ta chỉ cần đảo thứ tự điều khiển step 1-2-3-4 thành 4-3-2-1  như sau:

//code test này không an toàn khi sử dụng
// chỉ để test

#define in_A_1 4
#define in_A_2 5
#define in_B_1 6
#define in_B_2 7

void setup()
{
    pinMode(in_A_1, OUTPUT);
    pinMode(in_A_2, OUTPUT);
    pinMode(in_B_1, OUTPUT);
    pinMode(in_B_2, OUTPUT);
}
unsigned int time_delay = 10;
void loop()
{

    //step4
    //A-,B+
    digitalWrite(in_A_1, 0);
    digitalWrite(in_A_2, 1);
    digitalWrite(in_B_1, 1);
    digitalWrite(in_B_2, 0);
    delay(time_delay);
    //step3
    //A-,B-
    digitalWrite(in_A_1, 0);
    digitalWrite(in_A_2, 1);
    digitalWrite(in_B_1, 0);
    digitalWrite(in_B_2, 1);
    delay(time_delay);

    //step2
    //A+,B-
    digitalWrite(in_A_1, 1);
    digitalWrite(in_A_2, 0);
    digitalWrite(in_B_1, 0);
    digitalWrite(in_B_2, 1);
    delay(time_delay);
    //step1
    //A+,B+
    digitalWrite(in_A_1, 1);
    digitalWrite(in_A_2, 0);
    digitalWrite(in_B_1, 1);
    digitalWrite(in_B_2, 0);
    delay(time_delay);
}

Vấn đề phát nhiệt trên ic và hướng giải quyết

2  đoạn code vừa rồi chỉ để chứng minh là lý thuyết đã đúng.

Điều khiển như vậy còn được gọi là điều khiển đối xứng.

Đồ thị điện áp đặt lên pha:

Như đã biết, arduino sẽ cấp một xung điều khiển để chuyển trạng thái step, tuy nhiên sau khi roto đã quay đến vị trí cân bằng thì xung điều khiển vẫn còn đó, dòng điện đi qua cuộn dây stato lúc này là dòng có hại và không sinh công ,

Nó làm ngắn mạch đầu ra của ic, sinh nhiệt rất lớn và làm hỏng ic.

(2 ví dụ trên mình chỉ moto quay khoảng 3 phút (chạy không tải ) là ic đã phát nhiệt rất lớn rồi).

Hướng giải quyết:

Sau khi cấp xung điều khiển, đợi cho roto quay tới vị trí cân bằng (time_level), ta sẽ tắt xung điều khiển trong toàn bộ thời gian còn lại.

#define in_A_1 4
#define in_A_2 5
#define in_B_1 6
#define in_B_2 7

void setup()
{
    pinMode(in_A_1, OUTPUT);
    pinMode(in_A_2, OUTPUT);
    pinMode(in_B_1, OUTPUT);
    pinMode(in_B_2, OUTPUT);
}
unsigned int time_delay = 10;
unsigned int time_level = 5;
void loop()
{

    delay(time_delay);
    step_1();
    delay(time_level);
    tat_xung();
    delay(time_delay);
    step_2();
    delay(time_level);
    tat_xung();
    delay(time_delay);
    step_3();
    delay(time_level);
    tat_xung();
    delay(time_delay);
    step_4();
    delay(time_level);
    tat_xung();
}
void tat_xung()
{

    digitalWrite(in_A_1, 0);
    digitalWrite(in_A_2, 0);
    digitalWrite(in_B_1, 0);
    digitalWrite(in_B_2, 0);
}
void step_1()
{

    //step1
    //A+,B+
    digitalWrite(in_A_1, 1);
    digitalWrite(in_A_2, 0);
    digitalWrite(in_B_1, 1);
    digitalWrite(in_B_2, 0);
}
void step_2()
{

    //step2
    //A+,B-
    digitalWrite(in_A_1, 1);
    digitalWrite(in_A_2, 0);
    digitalWrite(in_B_1, 0);
    digitalWrite(in_B_2, 1);
}
void step_3()
{

    //step3
    //A-,B-
    digitalWrite(in_A_1, 0);
    digitalWrite(in_A_2, 1);
    digitalWrite(in_B_1, 0);
    digitalWrite(in_B_2, 1);
}
void step_4()
{

    //step4
    //A-,B+
    digitalWrite(in_A_1, 0);
    digitalWrite(in_A_2, 1);
    digitalWrite(in_B_1, 1);
    digitalWrite(in_B_2, 0);
}

Với code này, mình đã cho motor quay không tải liên tục trong 20 phút, kết quả là nhiệt độ của ic l923d chỉ nhỉnh hơn nhiệt độ trên chip AVR của arduino một chút mà thôi.

Ý nghĩa của time_level:

  • Nhiệt độ sẽ giảm hơn so với phương pháp điều khiển đối xứng theo tỷ lệ: g=time_high/time_level. Với time_high là thời gian xung cao của phương pháp đối xứng,
  • Nếu thời gian kích từ quá ngắn thì động cơ sẽ không quay được nếu có thêm tải. Đối với tải nhỏ như đầu đọc laser thì time_level vào cỡ 5ms, với các dự án CNC mini thì time_level khoảng 5-15ms.
  • Time_level càng cao thì càng khỏe, nhanh nóng ic. Time_level càng thấp thì bảo vệ được ic driver, tuy nhiên momen xoắn nhỏ, dễ bị hụt step, gây sai lệch

Stepper.cpp:

Hiện (27/12/2016) thư viện Stepper.cpp được arduino.cc chọn làm thư viện. Nhưng khá buồn khi chính nó cũng đang mắc phải lỗi điều khiển đối xứng, hẳn là sẽ làm giảm tuổi thọ hàng tá ic trong thời gian tới.

Mình đã test thử thư viện Stepper.cpp, cho dừng delay để đo tín hiệu các chân, thậm chí lục ra mã nguồn trong desktop của mình để xem họ viết gì. Kết quả mình dự đoán là đúng.

Nó đây: https://github.com/arduino/Arduino/blob/master/libraries/Stepper/src/Stepper.cpp

Có thể dễ thông cảm vì mọi thứ đều là do bàn tay khối óc của cộng đồng xây dựng lên, cái nào chưa hoàn thiện thì mọi người lại chung tay vun đắp thêm.

Giới thiệu thư viện.

Ok, tới đây mình giới thiệu thư viện được rồi. 

Nối 4 dây với arduino

Nối 3 dây với arduino

Vì xung điều khiển lên chân in1 (in3) luôn là NOT của in2 (in4)và ngược lại, do đó với cổng in còn lại ta chỉ cần thêm một cổng logic not mà không cần kết nối tới arduino. Để ngắt xung điều khiển ta cần sử dụng đến chân điều khiển ENABLE.  Cả chân enable được nối với nhau và nối vào pin của arduino.

 

R2 là điện trở kéo âm, nó dùng để bảo vệ ic trong trường hợp arduino chưa nối với ic.

Một cổng mạch NOT tương đương với mạch sử dụng một transistor NPN như hình vẽ. Với R = 10->50k

3.Thủ tục và khai báo

//B1:
#include "STEP_2_PHASE.h"
//B2:
STEP_2_PHASE moto_x(5,6,7); 
STEP_2_PHASE moto_y(4,5,6,7);

Ý nghĩa

B1 : thêm thư viện

B2:

Kiểu nối dây  pha
Tạo đối tượng
3 dây
STEP_2_PHASE moto(A+,B+,ENABLE);
4 dây
  • STEP_2_PHASE moto(A+,A-,B+,B-);

Các hàm chức năng 

  • set(time_level,time_delay);

    Cài đặt thời gian xung điều khiển (momen và nhiệt độ)  và thời gian delay ( làm chậm)

  • go_front(unsigned long  n_step);

    Đi về trước n step (quay cùng chiều kim đồng hồ)

  • go_back (unsigned long n_step);

    Đi lùi về sau  n bước (quay ngược chiều kim đồng hồ)

  • long get_step();

    Sử dụng một biến đếm là STEP,   khi cho moto quay thuận 1 step thì biến đếm cộng thêm 1, khi cho moto quay nghịch 1 step thì biến đếm trừ đi  1.

    Gọi hàm get_step để trả về  step.

  • set_zero();

    Gọi hàm này để đặt biến đếm STEP là 0.

  • goto_step (step);

    Tự động đi đến STEP x, với goto_step(0) là vị trí bắt đàu khởi động. (Các bạn nên cho con trượt về vị trí ban đầu trước khi khởi động arduino)

  • step(long n_step);

    n_step dương : tiến về phía trước n step

    n_step âm: lùi về sau n_step

  • TWO_MOTORS.goto_xy(STEP_2_PHASE &moto_x, long x_step, STEP_2_PHASE &moto_y, long y_step);

     Điều khiển cùng lúc 2 moto. Đây là hàm cơ bản nhất trong CNC.  

Code test

Code 1

#include "STEP_2_PHASE.h"

STEP_2_PHASE moto(4, 5, 6, 7); //(A+,A-,B+,B-)
//set pin
void setup()
{
    moto.set(10, 5);
}
void loop()
{
    // quay thuận kim đồng hồ (tiến về trước) 90 step
    moto.go_front(90);
    delay(100);
    moto.go_back(90); // quay ngược 90 step
    delay(100);

    // tự tìm đến step(x)
    moto.goto_step(60);
    delay(100);
    moto.goto_step(0);
    delay(100);

    // quay thuận 20 step
    moto.step(20);
    delay(100);
    moto.step(-20); // quay ngược 20 step
    delay(100);
}

 

 

Code 2: Điều khiển đồng bộ 2 moto

//chú ý: truy cập phương thức với tên : " TWO_MOTORS"
#include "STEP_2_PHASE.h"
//(A+,A-,B+,B-)
STEP_2_PHASE moto_y(8, 9, 10, 11); // pha A(8,9), pha B(10,11)
STEP_2_PHASE moto_x(4, 5, 6, 7); //A(4,5) , B(6,7)
//set pin
void setup()
{
    moto_x.set(5, 10);
    moto_y.set(10, 10);
}
void loop()
{
    //vẽ tam giác
    TWO_MOTORS.goto_xy(moto_x, 50, moto_y, 50);
    TWO_MOTORS.goto_xy(moto_x, 100, moto_y, 0);
    TWO_MOTORS.goto_xy(moto_x, 0, moto_y, 0);
}

Bạn có thể tìm các code ví dụ trong thư mục Example của thư viện nhé.

Tất cả các trường hợp code (4 dây và 3 dây) đều đã được mình test nhiều lần, hiệu suất của 3 dây cao hơn.  Các bạn chú ý nối dây cho chắc chắn nhé. 

Tự chế mạch lái

Mình sẽ làm mạch cầu đơn giản từ các transistor.

Sơ đồ mạch được mình lấy lại từ mạch lái mô-tơ của ô tô điều khiển từ xa.

Hai loại transitor là NPN  và PNP. Ở đây mình chọn là npn 8050 và pnp 8550.

Phía trên là mạch đơn giản, nó cần có thêm cổng AND trước 4 cổng IN để sử dụng chức năng Anable, cần mắc thêm 2 diode ở mỗi đầu ra để dập tắt dòng ngược do hiện tượng cảm ứng từ và cộng hưởng từ gây ra bởi cuộn stato ( có tính cảm lớn).

Bạn hãy xem datasheet để xem mạch tương đương của họ nhé.

Tuy vậy mạch này cũng khá bền khi chỉ dùng để lái moto  chạy pin. ^^.

Test thực tế

Hệt như dùng ic. Nhiệt độ ổn định.

Hehe, sau vụ này chế thêm vài ic cho đỡ tốn!

 

Kết

Thư viện trên cũng đã được mình ứng dụng vào dự án CNC plotter.(sửa code cũ chút xíu), dưới đây là video demo.

 

Tác giả:  Thái Sơn.

lên
17 thành viên đã đánh giá bài viết này hữu ích.
Các dự án được truyền cảm hứng

Bộ điều khiển PID - ứng dụng phần 2 - xe dò line dùng thuật toán PID

Tiép nối bài viết về xe dò line cảm ơn Đỗ Hữu Toàn đã viết hộ mình phần 4. hôm nay mình sẽ làm cho chiếc xe dò line đi mượt và có hồn hơn 

lên
34 thành viên đã đánh giá bài viết này hữu ích.
Các bài viết cùng tác giả

Thư viện truyền dữ liệu bất kỳ (byte ,long, float , double ... ) theo gói tin cho arduino

Đây là bài viết chỉnh sửa  lại thư viện truyền kiểu dữ liệu bất kỳ (byte ,long, float , double ... )  UART_ARDUIINO.h.

Thư viện mới sẽ giúp truyền tin an toàn hơn, hỗ trợ truyền theo mảng nhị phân (binary), cho phép sử dụng nhiều cổng giao tiếp khác nhau cùng lúc.

Link bài cũ : http://arduino.vn/tutorial/1471-truyen-cac-so-kieu-long-int-float-trong-giao-tiep-serial-uart

lên
21 thành viên đã đánh giá bài viết này hữu ích.

GAME-ST7565 - Làm Game xe tăng với Arduino

Hôm nay sẽ là Game xe tăng – TANK WAR – tựa Game quen thuộc nhưng đầy hấp hẫn. Điểm đặc biệt là bạn có chơi ở chế độ cân TEAM 1-25 cực FUN devil.

lên
4 thành viên đã đánh giá bài viết này hữu ích.