Nick Chung gửi vào
- 42353 lượt xem
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
|
|
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é.
Download thư viện.
Link (11:09PM 12/27/2016):
https://drive.google.com/file/d/0BzMEcyRK_uUFVEJybVFkVXdzOHM/view?usp=sharing
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.