Si además quieres enviarnos un Artículo para el Blog y redes sociales, pulsa el siguiente botón:
Buenas a todos.
Últimamente he estado mirándome el tema del PWM estoy intentando controlar un servomotor FUTABA 3003, pero tengo dos problemas.
En primer lugar, la mecánica del servo tiene un ángulo de 360 grados (ya que le quite el tope al trucarlo). Pero controlándolo por PWM el ángulo que puedo recorrer del máximo al mínimo es de menos de 50 grados. Me gustaría saber cómo puedo hacerlo para ampliar ese rango.
En segundo lugar, cuando el servo llega a la posición (media, mínima o máxima), se queda vibrando. ¿Eso es normal? En caso de que no lo sea me gustaría saber cómo puedo evitar que vibre. He comprobado que vibra ya que estoy todo el rato enviándole pulsos. ¿Como lo puedo hacer para que cuando el servo este posicionado donde lo quiero pare de enviar pulsos?
Adjunto el código que utilizo para controlar el servo:
#include <16F876A>
#device adc=8
#FUSES NOWDT //No Watch Dog Timer
#FUSES RC //Resistor/Capacitor Osc with CLKOUT
#FUSES NOPUT //No Power Up Timer
#FUSES NOPROTECT //Code not protected from reading
#FUSES NODEBUG //No Debug mode for ICD
#FUSES BROWNOUT //Reset when brownout detected
#FUSES LVP //Low Voltage Programming on B3(PIC16) or B5(PIC18)
#FUSES NOCPD //No EE protection
#FUSES NOWRT //Program memory not write protected
#use delay(clock=20000000)
#use rs232(baud=9600,parity=N,xmit=PIN_C6,rcv=PIN_C7,bits=8)
//------------------------------------------------------------------------------
//Registros
#byte PORTB = 0x06
#byte TRISB = 0x86
//LED
#bit LED = PORTB.1
//SERVOS
#bit servo1 = PORTB.0
//Otros
#define ON 1
#define OFF 0
const int AJUSTE_FINO_DE_RTCC = 61;
const int ticks_PULSO_MINIMO = 62;
const int ticks_PULSO_MEDIO = 93;
const int ticks_PULSO_MAXIMO = 125;
int1 flagRTCC = 0;
int contRTCC = 0;
int1 flagSERVO1 = 0;
int tSERVO1 = ticks_PULSO_MEDIO;
int ValTIMER0;
#int_RTCC
void RTCC_isr()
{
++contRTCC;
if(contRTCC == 4)
{
set_TIMER0(AJUSTE_FINO_DE_RTCC);
}
if(contRTCC == 5)
{
flagRTCC = 1;
contRTCC = 0x00;
}
}
void main(){
//Configuracion
//---------------------------------------------------------------------------
setup_adc_ports(NO_ANALOGS);
setup_adc(ADC_OFF);
setup_spi(SPI_SS_DISABLED);
setup_timer_0(RTCC_INTERNAL|RTCC_DIV_1);
setup_timer_1(T1_DISABLED);
setup_timer_2(T2_DISABLED,0,1);
setup_comparator(NC_NC_NC_NC);
setup_vref(FALSE);
//---------------------------------------------------------------------------
setup_counters(RTCC_INTERNAL,RTCC_DIV_16);
// Configura les interrupciones.
enable_interrupts(global);
enable_interrupts(int_RTCC);
// Inicialitza el timer a 0
set_TIMER0(0);
TRISB = 0x00;
PORTB = 0
while(1){
// DISPARO DEL PULSO PWM
if(flagRTCC == 1)
{
flagRTCC = 0;
servo1 = ON;
flagSERVO1 = 1;
}
// CONTROL DE ANCHO DEL PULSO PWM
if(flagSERVO1 == 1)
{
valTIMER0 = get_TIMER0();
if(valTIMER0 > tSERVO1)
{
flagSERVO1 = 0;
servo1 = OFF;
}
}
}
}
Saludos y gracias.
Que funcione a más de 50Hz, depende única y exclusivamente del servo y de la marca. Creo que Futaba suele permitir meter más caña, pero no es lo típico. Por ejemplo, mis Hitec puedo mandar pulsos cada 2Seg y sigue funcionando bien, pero en unos Chinos que tengo yo les da un patatús si hago eso... y a otros no... vamos, que lo mejor es seguir el estándar que te asegura que siempre te va a funcionar.
Hola, exactamente Bastian, el cristal que uso es de 4MHz.
Con respecto a lo de la frecuencia de la señal, hice caso a estoPor tanto, lo realmente importante es el ancho de pulso. Que le varies la frecuencia, a veces sigue funcionando, a veces produce desviaciones, eso puede depender de la electrónica del servo. Si te ajustas a los 50Hz te curas en salud y te aseguras que todos los servos funcionarán correctamente.
Con esta configuración los servos funcionan pero no logro detenerlos, así que supongo que dragonet lleva razón.
Explicame mejor eso de como lo harias con la interrupción que dices.
Buenas, estoy intentando sacar el PWM para un servo que tengo, y buscando algo de información por internet he caído por aqui y he probado el programa que has puesto. No se si lo has probado, pero ese programa saca una frecuencia demasiada alta, para ser exactos el programa tiene unos pulsos de 70ms, cuando debería de sacar unos pulsos de 20ms para que el servo funcione a 50hz, a que se debe ?
un saludo y gracias!
Qué reloj estás usando?
S2
Ranganok Schazaman
Entonces revisa los timers que es muy posible que el problema esté ahí.
S2
Ranganok Schahzaman