TODOPIC
Microcontroladores PIC => Lenguaje C para microcontroladores PIC => Mensaje iniciado por: patricklebu1 en 04 de Noviembre de 2009, 14:52:59
-
Hola tengo un problema con crear un PWM para controlar un servomotor en el pic16f84a, a traves del pin RA0 debo ir aumentando los angulos del servo los cuales los pulson salen a traves del pin RB0. cree dos formulas una para el periodo activo y el inactivo. El periodo es de 20milsegundos.
El problema que tengo es que al apretar el pin RA0 el servo pasa de 0 grados hasta su maximo en grados, y no se como hacer que solo me valla contando de un grado en uno.
Ojala alguien me pueda ayudar.
Al final este trabajo debo hacer que con un pin aumente en grados y con otro pin debo hacer decrementar 4 servos , pero primero quiero aprender a aumentar los grados de un solo servo, para ir de paso a paso.
#include <16f84a.h>
#fuses XT,NOWDT
#use delay(clock= 4000000)
#bit RA0=0x05.0
#bit RB0=0x06.0
int k,servo,grad;
void main()
{
set_tris_b(0x00);
while (true)
{
if(RA0==1&&grad<180)
{ delay_ms(25);
grad=grad+1; // va sumando los click del boton RA0
servo=grad*100+200; //ecuacion del tiempo activo del periodo
k=2000-servo; //tiempo del periodo inactivo del periodo
output_high(PIN_B0);
delay_us(servo);
output_low(PIN_B0);
delay_us(k);
}
}
}
-
Hola patricklebu1 aqui te dejo el enlace a un link que empece donde se comenta como hacerlo
http://www.todopic.com.ar/foros/index.php?topic=26069.0
Saludos.
-
estube mirando tu programa, pero yo debo controlar los servos mediante dos pines y y el control debe ser de 1 grado en uno, es como un escalamiento
-
Hola de nuevo, no se si es que no has entendido el link que te he pasado o si es que no te entiendo yo a ti, si es asi disculpa.
Para ir subiendo de grado en grado, si tu sabes que el servo empieza a tope a la izquierda con 850ms, lo que tienes que hacer es ir subiendo de 1 en 1 los milisegundos.
Seria algo asi:
void Centra_Servo_1(int Repeticiones)
{
int Bucle;
for(Bucle=1;Bucle<=Repeticiones;++Bucle)
{
output_high(pin_B0);
delay_us(850);
output_low(pin_B0);
delay_ms(20);
output_high(pin_B0);
delay_us(851);
output_low(pin_B0);
Ponemos el pin_B0 a nivel alto temporizamos 850ms tope a la izquierda.
Pasamos a nivel bajo pin_B0
Pasamos otra vez a nivel alto temporizando 851ms (acabas de avanzar un grado)
otra vez a nivel bajo
etc etc...
PD: Debes tener en cuenta que sumando el nivel alto y el nivel bajo no debes exceder de los 20ms.
-
Miquel_S eso mismo quiero hacer yo, pero debo controlarlo a traves de un pin_RA0 la cantidad de grados de incremento que deba moverse. Lo otro es que no puedo escribir 180 veces el programa
output_high(pin_B0);
delay_us(850);
output_low(pin_B0);
delay_ms(20);
yo debo manejarlo a traves de la construccion de un PWM o a traves del TMR0, el programa que escribi al comienzo del tema esta hecho construyendo el PWM.
output_high(pin_B0); output_high(PIN_B0);
delay_us(850); delay_us(servo); aca el mio va a incrementando mediante una formula para no escribirlo 180 veces
output_low(pin_B0); output_low(PIN_B0);
delay_ms(20); delay_us(k); aca va decrementando mediante formula para no escribirlo 180 veces
pero lo malo de mi programa es que pasa de cero grados al maximo de grados en un solo click del pin RA0
Saludos
-
yo tambien estoy realicando algo parecido a ti, tengo dos pulsadores uno para incrementar, B1, y el otro para decrementar, B2, el problema es que el pulsador 1 funciona bien, va incrementando de 0 grados hasta 180 grados, mientras que el pulsador b2, que tiene que funcionar igual pero restando de 180 a 0 grados, no funciona, ha veces se queda pillao el pic. si a la rutina de b2 le pongo lo mismo pero sumando, funciona a las mil meravillas, pero restando no funciona, ya no se que puedo hacer mal.
adjunto el proyecto. si alguien me puede hechar una mano se lo agradeceria.
saludos.
mi codigo:
(no se como ponerlo en una ventana deslizante, perdonen las molestias)
#include <16f84a.h>
#include <math.h>
#use delay(clock=4000000)
#byte portb= 0x06
#byte porta= 0x05
#bit rb0= 0x06.0
#bit ra0=0x5.0
#bit ra1=0x5.1
int cont;
long int angulo1;
long int angulo2, angulo3;
#int_timer0
interr()
{
rb0=1;
delay_us(angulo2);
rb0=0;
delay_us(angulo3);
}
void calcular_servo(long int angul, long int& angulo2, long int& angulo3)
{
long int a=11;
long int b=300;
long int z=20000;
angulo2=a*angul+b;
angulo3=z-(a*angul+b);
return;
}
void main()
{
set_tris_b(0); // puerto rb0
set_tris_a(0xFF); // puerto ra0 y ra1
portb=0;
porta=0;
cont=0;
setup_timer_0(rtcc_internal);
enable_interrupts(int_rtcc);
enable_interrupts(GLOBAL);
set_timer0(200);
angulo1=0;
calcular_servo(angulo1,angulo2,angulo3);
while(1)
{
if(ra0==0) // testeamos RA0.
{
angulo1=angulo1+5;
calcular_servo(angulo1,angulo2,angulo3);
if (angulo1>=179)
{
angulo1=179;
}
}
if(ra1==0) // testeamos RA1.
{
angulo1=angulo1-5;
calcular_servo(angulo1,angulo2,angulo3);
if (angulo1<=1)
{
angulo1=1;
}
}
delay_ms(1);
}
}