Ðề tài: RC Servo
View Single Post
Old 10-03-2010, 10:06 PM   #6
motu
Đệ tử 4 túi
 
Tham gia ngày: Oct 2007
Bài gửi: 79
:
Red face Không ai trả lời, tự xử luôn.

Sau 2 năm vật lộn với con RC Servo cuối cùng cũng điều khiển được nó, hỏi bên PICVIETNAM và DIENTUVIETNAM mà chẳng ai quan tâm, có vài kinh nghiệm bản thân post lên cho ae nào "gà" giống mình tham khảo.
- Theo tài liệu mình đọc thì RC Servo hoạt động ở dãy tần số 50Hz (T=20ms), độ rộng xung từ 1ms đến 2ms. Nên ta có 3 cách sau để điều khiển nó:
1. Sử dụng PWM của PIC, nhưng cách này để tạo ra xung tần số 50Hz hơi bị khó, mình không rành điện tử lắm nhưng hình như do tần số PWM phụ thuộc vào tần số thạch anh nên chỉ thích hợp tạo ra xung tần số cao >500Hz. Lúc đầu mình cũng đã dùng cách này và thất bại cay đắng .
2. Sử dụng PWM tự tạo bằng cách on off chân output và delay tá lả. Cách củ chuối này chỉ thích hợp để test chơi cho vui.
3. Tạo PWM dựa trên ngắt timer0, cách này có vẻ hợp lý (do chẳng biết còn cách nào hay hơn ). Dùng ngắt timer0 để on off chân RC2 (tương tự cách 2 nhưng pờ rồ hơn). Và code test được viết như sau:
Code:
#include <16F877A.H>
#include <def_877a.h>
#device *=16 ADC=8
#FUSES NOWDT, HS, NOPUT, NOPROTECT, NODEBUG, BROWNOUT, NOLVP, NOCPD, NOWRT
#use delay(clock=4000000)
#define MAX_VALUE 200
#define Right MAX_VALUE - 20
#define Left MAX_VALUE - 10
#define Center MAX_VALUE - 15
unsigned char pulse_max=0;
unsigned char pulse_top=0;
unsigned char top_value=0;
#INT_TIMER0
void interrupt_timer0()
 {
   set_timer0(156);
   pulse_max++;            
   pulse_top++;
   if (pulse_max >= MAX_VALUE) 
    {
      pulse_max=0;
      pulse_top=0;
      RC2=0;                // Turn off RC2
    }
   if (pulse_top == top_value) 
    {
      RC2=1;                // Turn On RC2
    } 
 }
/* TIMER0 period = [(TMR0 + 1)] x 4 x Tosc x (TIMER0 prescaler value) second
   Init TIMER0: Period: Fosc/4 x Prescaler x TMR0
   TIMER0 period = [((255 - 156) + 1)] x 4 x 1/4000000 x 1 = 0.0001 second = 0.1 ms*/
void main()
 {
   set_tris_c(0x00);
   portC = 0x00;
   top_value = Center;
   enable_interrupts(global);
   enable_interrupts(int_timer0);
   setup_timer_0(RTCC_INTERNAL|RTCC_DIV_1);
   set_timer0(156);
   while(1)
    {    
      top_value = Left;
      delay_ms(1000);
      top_value = Right;
      delay_ms(1000);    
    } 
 }
Thật ra những kinh nghiệm trên được dịch từ trang web www.ermicro.com/blog/?p=771 (trang hay nhất trong tất cả các trang hướng dẫn về RC Servo, đọc rất dễ hiểu và giải thích cụ thể) các bạn có thể vào đọc để nghiên cứu kỹ hơn, mình chỉ đọc, hiểu đại khái và cải biên lại vậy thôi, o dịch chính xác và toàn bộ (dịch hết lòi cái ngu ra sao )
Code này đã test chạy ok, nhưng có một điều không hiểu, đúng ra RC Servo phải quay 1 góc chính xác ứng với 1 độ rộng xung, nhưng thực tế chạy thử thì sau mỗi lần quay qua quay lại, con RC Servo bị lệch 1 góc nhỏ, quay 10 lần nó thành góc lớn, 100 lần nó lệch má nhìn không ra (, cao thủ nào giúp e với, h ...e ...l....p!!! (chắc chờ tiếp 2 năm nữa mới có lời giải đáp).
Thk cả nhà, chúc ngủ ngon, e đi làm việc kiếm tiền mua Servo về test tiếp.
P/S: Các bạn mới test với con RC Servo lần đầu, nhớ cắt cái chốt cản để có lỡ tay cũng không làm hư nó.
motu vẫn chưa có mặt trong diễn đàn   Trả Lời Với Trích Dẫn