Autor Tema: Servos y conversores  (Leído 1409 veces)

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

Desconectado hernanfire

  • PIC10
  • *
  • Mensajes: 32
Servos y conversores
« en: 14 de Julio de 2007, 23:48:10 »
Mirando una pagina de LordLafebre  :) vi que movia unos servos con potenciometros y no tuve mejor idea q tratar de hacerlo!!! (solo para aprender a usarlos!!)  :-/ y como soy muy novato trate de modificar un pequeño programa de RedPic  8) que estaba en su pagina que, por cierto , explica muy claramente el uso y abuso de los servos, el problema es que no puedo lograr que lo que lee en el ADC lo pase como la parte de PWM sobre el servo, no entiendo que modificar.... me parece que tengo problemas......  :shock: les dejo el codigo modificado (esta sin funcionar) para ver si me dan una mano y si se puede hacer de otra forma mas sencilla!! (porque esta hecho con pico y pala!!! ajaj  :D :D), desde ya muchas gracias por su ayuda!!  Saludos

#include <16f876.h>
#device ADC=8
#fuses XT,NOWDT,NOPROTECT,NOLVP,PUT,BROWNOUT
#use delay(clock=4000000)
#use standard_io(b)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7)

#define led_adc PIN_C0
#define PIN_SERVO1 PIN_C2

////////////////////////////////////////////////////////////////////////
// VARIABLES GLOBALES

const int AJUSTE_FINO_DE_RTCC =  30;
const int ticks_PULSO_MINIMO  =  31;
const int ticks_PULSO_MEDIO   =  93;
const int ticks_PULSO_MAXIMO  = 155;

int1 flagRTCC   = 0;
int  contRTCC   = 0;
int1 flagSERVO1 = 0;
int  tSERVO1    = ticks_PULSO_MEDIO;

float  adc_tension=0;
int  tension=0;
int valor;
//////////////////////////////////////////////////////////////////////

#int_RTCC
RTCC_isr(){

   ++contRTCC;
   if(contRTCC==4){
      set_TIMER0(AJUSTE_FINO_DE_RTCC);
   }
   if(contRTCC==5){
      flagRTCC=1;
      contRTCC=0x00;
   }
}

void toma_adc(void){
   setup_adc(ADC_CLOCK_INTERNAL); //configura el converso
   setup_adc_ports(RA0_analog); //entrada 0 como analogica
   set_adc_channel(1);
   output_low(led_adc);
   adc_tension=read_adc();
   tension = (int) (adc_tension);
    if(tension == 255){   // esta es la parte que menos me gusta, trate de hacerla con
                          // con formulas pero perdia definicion entonces opte por esto
     valor=155;           // valor maximo
      }
    if(tension == 230){
     valor=142;
      }
    if(tension == 204){
     valor=128;
      }
    if(tension == 179){
     valor=117;
      }
    if(tension == 153){
     valor=105;
      }
    if(tension == 127){   // valor medio
     valor=93;
      }
    if(tension == 102){
     valor=80;
      }
    if(tension == 76){
     valor=69;
      }
    if(tension == 51){
     valor=58;
      }
    if(tension == 25){
     valor=46;
      }
    if(tension == 0){   // valor minimo
     valor=31;
      }
   delay_ms(100);
   output_high(led_adc);  // para saber que adquiere
   printf("\r\n\ %u",valor); // para confirmar el valor de  los if
   }

void main() {

 int ValTIMER0;
   setup_counters(RTCC_INTERNAL,RTCC_DIV_16);
   enable_interrupts(global);
   set_TIMER0(0);
   enable_interrupts(INT_RTCC);

do {
      // DISPARO DEL PULSO PWM
      if(flagRTCC==1){
         flagRTCC=0;
         output_high(PIN_SERVO1);
         flagSERVO1=1;
      }
      // CONTROL DE ANCHO DEL PULSO PWM
      if(flagSERVO1==1){
         valTIMER0 = get_TIMER0();
         if(valTIMER0>tSERVO1){
            flagSERVO1=0;
            output_low(PIN_SERVO1);
         }
      }

//      toma_adc();         ////  esta es la parte que no entiendo
//      tSERVO1=valor;      //// asi como esta no funcionaria ya que los disparo
                            //// de control dejan de respetarse!!!!



   } while (TRUE);

}





Desconectado Marttyn

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 1835
    • IDEAA
Re: Servos y conversores
« Respuesta #1 en: 17 de Julio de 2007, 19:17:41 »
de otra cosa no.... pero de servos te puedo aconsejar algunas cosas  :mrgreen: sobre todo en conjuncion con un potenciometros  :-)
lo primero que puedo decirte es que mires este post, donde hay una solucion a lo que propones...
despues, mirando tu codigo, y sin ofender, veo algunos fallos....  :?
-no declaras la funcion "toma_adc"
-dentro de esta funcion configuras el adc
Citar
   setup_adc(ADC_CLOCK_INTERNAL); //configura el converso
   setup_adc_ports(RA0_analog); //entrada 0 como analogica
   set_adc_channel(1);
pero deberias hacerlo solo una vez en el main... ya que cada vez que cambies el canal del adc debes esperar unos 5uS antes de leerlo
-al final de esta funcion pones un delay de 100mS... los delay DETIENEN completamente al pic, no se ejecutan interrupciones ni nada, con lo cual, como el servo necesita un pulso cada 20mS este no funcionara...
-pides EN CADA vuelta del bucle del main una lectura del adc... lo que hace impresionantemente inestable al servo... deberias pedir una muestra al adc cada 50mS por ejemplo...

probablemente, como tu dices notes impresicion del pot, pero no es porque uses una formula para conseguir la posicion... sino porque pides una muestra con cada vuelta del bucle

ahora... te recomiendo que visites el post que te digo. el codigo con el que estas haciendo pruebas la verdad que no es muy eficiente para mover un servo con un pot, ya que la toma de muestras adc demora algo de tiempo, y esto demora el control del pulso del servo...
salu2 y ya contaras si lo has conseguido
La gente ve las cosas que existen y se pregunta por qué.
Yo prefiero imaginar lo que no existe y preguntarme por qué no.

Desconectado hernanfire

  • PIC10
  • *
  • Mensajes: 32
Re: Servos y conversores
« Respuesta #2 en: 18 de Julio de 2007, 19:38:38 »
Muchas Gracias Marttyn por responder! , muy buenas tus recomendaciones! lo voy a tener en cuenta para modificar el codigo, por lo menos la parte de la toma de muestras, es por eso que indicaba que estaba hecho con pico y pala el codigo ajajaja, leere el hilo que me dejaste de enlace a ver si me ayuda y pondre los resultados y el cdigo modificado para seguir buscando algo optimizado.
Saludos Y gracias


 

anything