servo motor, como controlar? (PWM + RS232 + SERVO MOTOR)

Mecanica robotica e Automação Industrial (PLC)

Moderadores: 51, guest2003

servo motor, como controlar? (PWM + RS232 + SERVO MOTOR)

Mensagempor __JEREK__ » 14 Fev 2007 16:27

galera, eu estou tentando usar um servo motor aqui, só para aprender a controlar ele e não estou conseguindo fazer ele dár uma volta de 360°, nem sei calcular direito a velocidade dele e quanto ele deve andar, vou postar minhas dúvidas em um outro post para não bagunçar esse daqui.



o servo motor eu tirei de uma parabólica.

o modelo é MotorTECH, como na foto:
Imagem

site fabricante:
http://www.sollaris.com.br/motortech/

tentei fazer umas experiencias com ele atravez de RS232 e PWM, só que não consegui ele dar um giro de 360°, detalhe, já cortei o pino que trava a engrenagem mair dentro dele, mas mesmo assim não consegui.

Alguem já fez algo parecido??

o código que estou usando é:

arquivo main:

Código: Selecionar todos
#include <16F628A.h>
#fuses HS,NOWDT,NOPROTECT,NOLVP
#use delay(clock=4000000)
#use rs232(baud=9600, xmit=PIN_B2, rcv=PIN_B1)
#fuses NOMCLR,INTRC_IO,NOWDT,PUT,NOLVP

#include <string.h>     // Necessárioa para a função strcmp()
#include <stdlib.h>     // Necessário para a função atol()

#include "funcoes_PWM.h"

char x[8];              // string de caracteres que pode acumular no máximo 7 digitos
                        // para alterar a quantidade é só mudar esse valor

char y[8] = "freq";     // string de caracteres que pode acumular no máximo 7 digitos
                        // para alterar a quantidade é só mudar esse valor

char answer;

short int resultado;   // Guarda o resultado da comparação das strings

void get_string(char* s, int max)         // Função para receber uma string via rs232
{
   int len;
   char c;
   --max;
   len=0;

      do {

      c=getc();

     if(c==8)                            // Se apertar Backspace volta uma tecla
     {
        if(len>0)
        {
          len--;
          putc(c);
          putc(' ');
          putc(c);
        }
     } else if ((c>=' ')&&(c<='~'))         // não digitar caracteres
       if(len<max)
       {
         s[len++]=c;
         putc(c);
       }

      if(len==max)                     // MELHORIA NO CÓDIGO
      {                                // Sem esse BREAK o programa espera vc apertar
            Break;                     // a tecla ENTER para sair
      }

   } while(c!=13);
   s[len]=0;

}

void main()
{
   setup_ccp1(CCP_PWM);             // Coloca o ccp1 modo PWM

   printf("\n\r+------------------------------------------------------------------+");
   printf("\n\rTeste de RS232 GET_STRING - servo motor");
   printf("\n\r+------------------------------------------------------------------+");
   printf("\n\rdigite freq ou duty e <ENTER>: ");
   do {
            get_string(x,8);            // X é a string de caracteres
                                    // 8 é a quantidade de caracteres definido na string de caracteres

            resultado = strcmp(x,y);      // Compara as 2 strings

      if(resultado==0)
//      if(x==y)
            {
         printf("\r\nConfigurção atual da frequencia: ");
         muda_freq();
         printf("\r\nAlterar frequencia (y,n)?");

         do {
               answer=getch();
            }while(answer!='y' && answer!='n');

               if(answer=='y')
         {
            printf("\r\n 0 - T2_DIV_BY_16, 239, 1 ");
            printf("\r\n 1 - T2_DIV_BY_16, 212, 1 ");
                        printf("\r\n 2 - T2_DIV_BY_16, 192, 1 ");
            printf("\r\n 3 - T2_DIV_BY_16, 180, 1 ");
            printf("\r\n 4 - T2_DIV_BY_16, 159, 1 ");
            printf("\r\n 5 - T2_DIV_BY_16, 144, 1 ");
            printf("\r\n 6 - T2_DIV_BY_16, 128, 1 ");
            printf("\r\n 7 - T2_DIV_BY_16, 119, 1 ");
//            printf("\r\n 8 - T2_DIV_BY_4, 3, 4 ");

         opcao = getc();
         printf("\r\nA opcao escolhida foi: %c ",opcao);
         muda_freq();

         }

      } else
         {
            printf("\r\nValor atual do duty cicle: %lu",valor_duty);
            printf("\r\nDigite novo valor: ");

            get_string(x,8);  // X é a string de caracteres
                                    // 8 é a quantidade de caracteres definido na string de caracteres
            valor_duty = atol(x);   // Converte sting para long int
            muda_duty();
         }

 printf("\n\rdigite freq ou duty e <ENTER>: ");

      } while(1);
}


Arquivo "funcoes_PWM.h"

Código: Selecionar todos
// Funções de PWM
// #include "funcoes_PWM.h"
// PIC16F628A

char opcao='0';        // variavel encarregada de mostrar menu de frequencias
char duty=0;           // variavel encarregada de mostrar menu de larguras de pulso
long int valor_duty;   // Valor do duty cicle

// FUNÇÃO ENCARREGADA DE MUDAR A FREQUÊNCIA DO CCP1
void muda_freq(void)
{

   switch(opcao)    // menu para escolha das frequências
      {
      case '0':   setup_timer_2 (T2_DIV_BY_16, 239, 1);         // 3824ms ou 0,261506276150628 Khz
            printf("\n\rT2_DIV_BY_16, 239, 1");
            Break;

      case '1':   setup_timer_2 (T2_DIV_BY_16, 212, 1);         // 3392ms ou 0,294811320754717 Khz
            printf("\n\rT2_DIV_BY_16, 212, 1");
            Break;

      case '2':   setup_timer_2 (T2_DIV_BY_16, 192, 1);         // 3072ms ou 0,325520833333333 Khz
            printf("\n\rT2_DIV_BY_16, 192, 1");
                        Break;

      case '3':   setup_timer_2 (T2_DIV_BY_16, 180, 1);         // 2880ms ou 0,347222222222222 Khz
            printf("\n\rT2_DIV_BY_16, 180, 1");
                        Break;

      case '4':   setup_timer_2 (T2_DIV_BY_16, 159, 1);         // 2544ms ou 0,393081761006289 Khz
            printf("\n\rT2_DIV_BY_16, 159, 1");
                        Break;

      case '5':   setup_timer_2 (T2_DIV_BY_16, 144, 1);         // 2304ms ou 0,434027777777778 Khz C
            printf("\n\rT2_DIV_BY_16, 144, 1");
                        Break;

      case '6':   setup_timer_2 (T2_DIV_BY_16, 128, 1);         // 2048ms ou 0,48828125 Khz
            printf("\n\rT2_DIV_BY_16, 128, 1");
                        Break;

      case '7':   setup_timer_2 (T2_DIV_BY_16, 119, 1);         // 1904ms ou 0,525210084033613 Khz
            printf("\n\rT2_DIV_BY_16, 119, 1");
                        Break;
}

// FUNÇÃO ENCARREGADA DE MUDAR A LARGURA DO PULSO
void muda_duty(void)
{
   set_pwm1_duty(valor_duty);

}


alguem poderia me dar uma dica??

desde já agradeço quem puder me ajudar, valeu!!!
__JEREK__
Byte
 
Mensagens: 216
Registrado em: 11 Out 2006 17:53
Localização: BA

Mensagempor brasilma » 14 Fev 2007 20:24

JERE,

Servo aciona com uma frequencia de 2mS, se mantiver 50% do ciclo ativo ele para no meio 95% acionado vai para um lado, 5% acionado vai para o outro.

Programa a rotina e confira o sinal gerado com o Escope, se tiver tudo ok e não funcionar o servo tá com problema.

Abraços,
MArcos.
" A Teoria orienta e a Prática decide" ;-)
Avatar do usuário
brasilma
Dword
 
Mensagens: 3621
Registrado em: 11 Out 2006 15:39
Localização: Planeta Terra

Mensagempor __JEREK__ » 14 Fev 2007 20:43

oi Marcos, blz??

o programa que postei funciona, coloquei um switch case para fazer a escolha da frequencia de PWM e a largura de pulso.

quando seleciono uma frequencia ele vai até certo ponto e para, quando seleciono outra frequencia ele vai para outro ponto e para, blz...

mas como faço para o servo motor dár uma vota completa de 360°? é possível de fazer com esse servo de parabólica??

seria mais ou menos essa a mina dúvida.

valeu brasilma!!!
__JEREK__
Byte
 
Mensagens: 216
Registrado em: 11 Out 2006 17:53
Localização: BA

Mensagempor LUCK » 14 Fev 2007 22:29

Jerek, mantenha a freqüência fixa e varie apenas a largura do pulso...
Em geral a frequência é de 50 hz. Altere a largura de acordo com a figura abixo:

Imagem

Testei uma vez com servo de parabólica que tinha potenciômetro sem trava... ao aumentar a largura do pulso, a partir de um determinado valor ele ficava girando indefinidamente. quanto mais eu alterava a largura do pulso, mais rápido ficava.
Só há um problema, a pista do potenciômetro nao tem 360º, então, quando passava no ponto que não tinha pista, a rotação ficava meio iregular... Mas servo não foi feito pra ficar girando indefinidamente, pois desgasta muito a pista do potenciômetro.


Imagem

Alguns links:
http://fribotte.free.fr/bdtech/pic/pic_et_servo.html
http://www.seattlerobotics.org/guide/servohack.html
http://www.geocities.com/BourbonStreet/ ... asics.html
http://www.voidpointer.de/servoswitch/index_en.html
Avatar do usuário
LUCK
Byte
 
Mensagens: 109
Registrado em: 11 Out 2006 14:01

Mensagempor MARCANTONIO » 19 Fev 2007 06:31

Para deixar ele girando continuamente desligue o potenciômetro da placa e cuidadosamente solde um trimpot com o mesmo valor no lugar. O potenciômetro fica ainda fixado na caixa do servo para apoiar a engrenagem principal, mas quem fica encarregado do ajuste é o trimpot. Quando você fizer a variação na largura do pulso do sinal o servo vai ficar girando em um sentido e quando a variação for contrária ele girará também ao contrário. O trimpot serve para ajustar o ponto em que o servo fica parado ou girando em um sentido ou outro.

Veja os tutoriais abaixo:
http://www.seattlerobotics.org/guide/servos.html
http://www.seattlerobotics.org/guide/servohack.html
Avatar do usuário
MARCANTONIO
Bit
 
Mensagens: 49
Registrado em: 02 Jan 2007 18:26
Localização: São Paulo


Voltar para Mecatronica a Automação

Quem está online

Usuários navegando neste fórum: Nenhum usuário registrado e 1 visitante

x