Autor Tema: Servo pic16f84a  (Leído 4200 veces)

0 Usuarios y 1 Visitante están viendo este tema.

Desconectado patricklebu1

  • PIC10
  • *
  • Mensajes: 5
Servo pic16f84a
« 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);                 
       }             
 }
}

Desconectado Miquel_S

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 1251
Re: Servo pic16f84a
« Respuesta #1 en: 04 de Noviembre de 2009, 15:07:37 »
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.
Todos somos muy ignorantes. Lo que ocurre es que no todos ignoramos las mismas cosas.

Desconectado patricklebu1

  • PIC10
  • *
  • Mensajes: 5
Re: Servo pic16f84a
« Respuesta #2 en: 04 de Noviembre de 2009, 16:18:29 »
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

Desconectado Miquel_S

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 1251
Re: Servo pic16f84a
« Respuesta #3 en: 04 de Noviembre de 2009, 17:56:20 »
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.
Todos somos muy ignorantes. Lo que ocurre es que no todos ignoramos las mismas cosas.

Desconectado patricklebu1

  • PIC10
  • *
  • Mensajes: 5
Re: Servo pic16f84a
« Respuesta #4 en: 04 de Noviembre de 2009, 19:57:10 »
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  
« Última modificación: 04 de Noviembre de 2009, 20:03:25 por patricklebu1 »

Desconectado illusionista_86

  • PIC10
  • *
  • Mensajes: 23
Re: Servo pic16f84a
« Respuesta #5 en: 22 de Noviembre de 2009, 09:13:27 »


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);
      
      
  }
 }