Lập trình Arduino – Điều khiển động cơ SERVO siêu chuẩn với biên độ góc cực nhỏ!

0
5506

Sử dụng TIMER1 trên arduino, việc ứng dụng nó để xuất ra xung điều khiển servo với độ chính xác cao là rất khả thi. Nó cho phép servo quay với góc cực nhỏ, nhỏ đến cỡ nào ? Xin mời bạn đọc bài viết dưới đây!

1.Nhỏ nhất là bao nhiêu ?

Mình nói luôn nè, xung điều khiển xuất ra cho phép ta điều khiển servo với góc lệch nhỏ nhất là 0.006 độ.

2.Tìm hiểu xung điều khiển SERVO.

Là xung PPM (Cũng là một xung PWM ). Với độ rộng xung cao tỷ lệ thuận với góc lệch của SERVO.

Với độ rộng xung  từ 1ms (1000us) => 2ms (2000us) thì servo được đặt với góc lệch tương ứng trong khoảng 0 =>180 (độ). Xung có chu kì 20ms, cho phép đặt lên 10 kênh servo khác nhau.

3.Tạo xung điều khiển có độ chính xác cao hơn.

Ta đã biết ưu điểm của bộ TIMER 1 là cho phép đếm với độ phân giải 16bit. Cùng với đó là khả năng tùy chỉnh ngắt tràn (TOP_value).

Đề bài

Tạo xung chu kì 5ms, với độ rộng xung cao thay đổi được trong khoảng 1000us => 2000 us.

Code tạo xung trên pin ~9 theo đề bài

Test servo

Giữ nguyên code trên, sửa hàm loop thành:

Kết quả

Servo chỉ lệch góc trong khoảng 0 đến 90 độ !!!!!!!!!!!!!!!!!!!

Code sai ??!!!

Đến đây, mình đã bối rối khi làm đúng lý thuyết mà nó lại không như lý thuyết tí nào .

Lý thuyết nói: Xung có độ rộng 1ms => lệch 0, xung rộng 2ms => lệch 180. Xung có tần số 50 hz. (xung PPM cần độ dài tối thiểu 20ms để (có thể) ghép tối đa 10 servo).

Tất nhiên mình đã đáp ứng đúng tiêu chí trên.

Sự thật đằng sau!

Đã vậy thì mình sẽ kiểm tra xung của thư viện điều khiển Servo (servo.h) xem có sự sai khác gì không.

Kết quả

F_pwm=50hz.

Độ rộng xung: 530us (0.53ms) tương ứng góc lệch 0.

Độ rộng xung : 2410us (2.41ms) tương ứng góc lệc 180.

Đó, thực tế đó.!

Sửa lại độ rộng xung

OK, thành công!

4.TỐI ƯU HÓA

Sử dụng P_clock=16mhz nâng tối đa độ phân giải của Timer 16bit. Khi đó độ phân giải nhỏ nhất là 0.0625us trên 1 xung P_clock.

5.Nén thư viện và sử dụng.

1. Tải về thư viện

Chú ý:

  • Thư viện này chỉ sử dụng cho 2 pin là ~9 (PB1) và ~10 (PB2)
  • (Ở phiên bản này) Bạn sẽ không thể sử dụng thư viện <Servo.h> để điều khiển Servo ở các pin còn lại. (Tranh chấp timer1)

Link: <Tải lên lần 1 . 3:29PM 8/1/2017>

https://drive.google.com/file/d/0BzM… (mirror)

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

Thực chất việc cài thư viện  chỉ là Inlude các hàm .

— void  port_attach(select_port);

Gọi hàm này 1 lần để cài đặt đầu ra cho chân PORT.

select_port” chỉ được phép mang 2 giá trị là “PB1” tương ứng pin ~9, và “PB2” tương ứng pin ~10.

Ví dụ: port_attach(PB1);// chọn pin ~9 làm đàu ra điều khiển Servo

— void correct_write(select_port,  val);

 Tương ứng trong đoạn
val
8480 – > 38550
Góc lệch
0.000->180.000 độ
Độ rộng xung
0.53ms – 2.41 ms

 

Ví dụ

correct_write(PB1,8480);// pin~9, servo lệch góc 0.000 độ

Mỗi đơn vị của “val” tương ứng với góc lệch 0.006 độ. Đây cũng là độ chia nhỏ nhất mà Servo có thể nhích được nhờ thư viện này .

— void write(select_port,  goc);

Một kiểu khác để điều khiển thay cho hàm correct_write.

 Tương ứng trong đoạn
goc
0.000 – > 180.000
Góc lệch
0.000->180.000 độ
Độ rộng xung
0.53ms – 2.41 ms

 

“goc” có kiểu dữ liệu ở dạng số thực. Float.

Ví dụ:

write(PB1, 30.005);// pin~9, servo lệch góc 30,005 độ

3. Code ví dụ

Sử dụng 1 servo

write

Correct_write


 

 

Sử dụng 2 servo

Sử dụng 2 thư viện một cách an toàn. ? 

Do có sự tranh chấp TIMER 1, cách duy nhất để sử dụng cùng lúc 2 thư viện là ta cần phải đặt attach/detach mỗi lần sử dụng.

Tổng kết

  • Thư viện này chỉ sử dụng cho 2 pin là ~9 (PB1) và ~10 (PB2)
  • Bạn cần khéo léo khi muốn sử dụng cùng lúc 2 thư viện “Servo.h” và” TIMER1_SERVO.h”
  • (38550-4880=30070),  Tương đương 30070/180=167 xung / 1 độ, Tức 1 xung cho ta góc lệch nhỏ nhất là 0,006 độ (tương ứng độ rộng 0.0625us).
  • Servo có thể đáp ứng được góc lệch 0.006 độ ?
    • Như ta đã biết, mỗi lần Val tăng thêm 1 giá trị thì độ rộng xung điều khiển cũng tăng thêm  0.0625us, nếu như servo nhận ra sự khác biệt đó rồi đáp tuyến lại thì điều này là có thể. Tuy nhiên, đối với các loại servo mô hình như đang dùng, chúng không được thiết kế để phản ứng quay ở góc lệch nhỏ như vậy . Điều này cũng có nghĩa,  bạn phải tăng ít nhất 0.200 -> 0.500 độ thì mới thấy Servo nhích (nhìn vào trục của môtơ). Việc sử dụng thư viện trên là quá tiên tiến đối với một Servo mô hình.
  • Trong thư viện này: Xung điều khiển có chu kì 6,5 ms (ngắt TOP_val), ( chu kì tối thiểu là 5ms)
  •  Sau bài này, cả mình và bạn cần mở rộng thêm quy ước về độ rộng xung điều khiển SERVO:  lấy 1,5ms làm trung tâm, khi đó 0->180 tương ứng với xung 0.5ms->2,50ms hoặc  1ms -> 2ms (Tùy từng loại Servo).  Vấn đề này được nói rõ ở đây: http://www.opencircuits.com/Servo_co…. Bạn có thể đạt được điều này bằng cách cho hàm correct_write(8000 ->40000); hoặc correct_write(16000->32000);

Code test trong video

 

Trao đổi học tập

Comments