PDA

View Full Version : RC Servo (tt)


motu
05-03-2011, 08:37 AM
E đang làm cái toy sử dụng cảm biến gia tốc MMA7260Q của Thiên Minh để điều khiển servo, đại khái là nghiêng bên nào thì servo sẽ nghiêng theo. code cơ bản như sau:

#include <16F877A.H>
#include <def_877a.h>
#device *=16 ADC=10
#FUSES NOWDT, HS, NOPUT, NOPROTECT, NODEBUG, BROWNOUT, NOLVP, NOCPD, NOWRT
#use delay(clock=4000000)
#use i2c(MASTER, SDA=PIN_C4, SCL=PIN_C3, force_hw)
#include <lcd_4bit.c>
#define MAX_VALUE 667
#define Right 658
#define Left 642
#define Center 650
unsigned int16 pulse_max=0;
unsigned int16 pulse_top=0;
unsigned int16 top_value=0;
int16 adc;
#INT_TIMER0
void interrupt_timer0()
{
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
}
set_timer0(241);
}
/* TIMER0 period = [(TMR0 + 1)] x 4 x Tosc x (TIMER0 prescaler value) second
TIMER0 period = [((255 - 241) + 1)] x 4 x 1/4000000 x 2 = 0.00003 second = 0.03 ms*/
//===================================

void main()
{
unsigned int16 tilt;
set_tris_a(0xFF);
set_tris_b(0x00);
set_tris_c(0x00);
set_tris_d(0x00);
PORTC = 0x00;
PORTD = 0x00;
//ADC
setup_adc(adc_clock_internal);
setup_adc_ports(AN0);
//ADC
//LCD
delay_ms(1000);
lcd_init();
delay_ms(200);
printf(lcd_putc, "\f");
lcd_gotoxy(2, 1);
printf(lcd_putc,"$WELCOM EVERYBODY$");
lcd_gotoxy(4, 2);
printf(lcd_putc,"HAPPY NEW YEAR");
delay_ms(1000);
printf(lcd_putc, "\f");
delay_ms(1000);
//LCD
//Servo init
pulse_max=0;
pulse_top=0;
top_value = Center;
enable_interrupts(global);
enable_interrupts(int_timer0);
setup_timer_0(RTCC_INTERNAL|RTCC_DIV_2);
set_timer0(241);
//i=7;
//Servo init
while(1)
{
set_adc_channel(0);
adc = read_adc();
tilt = adc / 20;
top_value = 628 + tilt;
lcd_gotoxy(1,1);
printf(lcd_putc, "ADC: %Lu",adc);
lcd_gotoxy(1,2);
printf(lcd_putc, "Vi tri: %Lu",top_value);
delay_ms(50);
}
}

Mạch cơ bản đã chạy, nhưng e có một số thắc mắc sau nhờ ae giúp đỡ.
1/Theo tính toán thì chu kì Timer0 sẽ là
TIMER0 period = [((255 - 241) + 1)] x 4 x 1/4000000 x 2 = 0.00003 second = 0.03 ms
khi đó biến top_value sẽ nằm trong khoảng 601-634 để có độ rộng xung là 1ms-2ms nhưng thực tế e phải sử để top_value trong khoảng 642-658 thì mới điều khiển được con servo, e muốn hỏi có phải do chất lượng linh kiện là ảnh hưởng tới xung nhịp của PIC (e đã thử với các chu kỳ TIMER0 khác, cả theo y chang hướng dẫn trên website khác nhưng vẫn phải thay đổi giá trị top_value một chút mới điều khiển chuẩn được) hay do code e sai chỗ nào?
2/E xài con RC servo TowardPro MG946R (tháo ra từ con xe RC của e) nhưng không điều khiển được góc quay 180 (chỉ được 160), cái này có phải do thiết kế của Servo không?
3/E chỉ có thể giảm TIMER0 xuống 0,03ms là hết cỡ, giảm nữa mạch chạy o chuẩn (chắc do ngắt xảy ra liên tục nên không đủ thời gian thực hiện các lệnh khác), cho nên độ phân giải của Servo chỉ được 658-642=16 bước, quá bèo để Servo chạy mịn màng như Comfort. E định thay con thạch anh 20MHz để giảm thời gian xung lệnh, nhưng không biết nó có đúng như e nghĩ không (e không có căn bản về điện tử, nên toàn đoán mò) hơn nữa nếu đúng thì cũng không cải thiện được bao nhiêu. Nên mọi người cho e giải pháp khác, có thể đổi sang con vi xử lý khác mạnh hơn chăng?
4/Khả năng đáp ứng của mạch khá chậm (thật ra là rất chậm, nói khá chậm để tự an ủi mình thôi), e biết là do code e viết còn gà lắm + do tốc độ xử lý của PIC. Nên ae có thể cho e một định hướng (về sử dụng vi xử lý gì, code theo hướng nào) để e có thể nghiên cứu tiếp, chứ nghiên cứu lan man mất thời gian lắm. E có đọc bài viết nói về code cho cảm biến gia tốc phải qua bộ lọc Kalman gì đó, mà đọc về bộ lọc Kalman thấy toàn nói về đạo hàm, tích phân, mấy cái đó giờ chắc nó quên e mất rồi, :(.
5/Cuối cùng e muốn hỏi con cảm biến gia tốc nó khác cảm biến gyro chỗ nào vậy, ae nào có thể giải thích một cách mộc mạc dễ hiểu dùm e, chứ nghe mấy từ thuật ngữ con quay hồi chuyển, hồi tiếp, hồi sức e chả hiểu mô tê gì.
Đầu năm hỏi nhiều quá :). Chúc cả nhà năm mới hạnh phúc với picvietnam.com.

motu
24-03-2011, 10:45 PM
Sao o ai giúp em hết vậy trời. Chắc phải tự thân vận động tiếp, hix!