Controlador de ângulo de antena parabólica usando ATmega16

Controlador de ângulo de antena parabólica usando ATmega16

Introdução A primeira coisa que precisamos entender é o que é servomecanismo? Servomecanismo significa gerar saída de erro como uma diferença entre o feedback de saída e a entrada de controle e reduz esse erro até que se torne zero – isso significa • quando o sistema atinge o estado desejado • quando o sistema produz a saída desejada É amplamente utilizado em 1. Aplicações industriais – correia plana, controle de movimento, posicionamento de carga, sistemas de controle de circuito fechado 2. Aplicações de defesa – posicionamento do cano da arma, rastreamento e monitoramento de alvos, sistemas de orientação de mísseis ou bombas inteligentes 3. Aplicações automotivas – veículos guiados automaticamente (AGV), veículos guiados não tripulados (UGV) 4. Aplicação aeronáutica – sistema fly by wire, veículo aéreo não tripulado (UAV) 5. Aplicações de reguladores de potência e tensão – regulador de tensão 6. Aplicação de satélite – rastreamento de satélite Podemos listar vários desses aplicativos. Vamos entender brevemente uma aplicação fascinante. Sistema de posição do cano da arma Este é um dos sistemas mais necessários para tanques, canhões antiaéreos, lançadores de mísseis de base terrestre ou obuses. Uma vez que o alvo esteja travado em todos esses sistemas, a arma deve sempre apontar para o alvo até que o projétil (bomba ou míssil) seja disparado. O alvo está em movimento (como um tanque ou avião), portanto, de acordo com sua posição de movimento, a arma também deve se mover automaticamente. O movimento do canhão depende da diferença gerada pela posição anterior e posição atual do alvo. E por fim, devido ao cálculo preciso, é disparada a bomba que sempre atinge o alvo. Eu discuti outra aplicação: Controle automático de ângulo (posição) bidimensional (2D) para antena parabólica. Posicionamento automático de antena parabólica A antena parabólica deve sempre apontar para um satélite no espaço para receber o sinal máximo. Um ligeiro desvio também pode reduzir a intensidade do sinal. A posição da antena é fixada definindo dois ângulos (1) ângulo de azimute (2) ângulo de elevação. Eles são definidos inserindo seus valores. Uma vez inseridos esses valores, a antena parabólica se move na direção horizontal e vertical usando 2 motorredutores CC, um para cada direção (ângulo). À medida que se move em qualquer direção, o desvio entre a posição desejada e a posição atual fornece um erro realimentado como entrada. A posição é detectada usando dois RVDTs (Transformador Diferencial Variável Rotativo), um para cada direção. A figura acima mostra um diagrama do sistema. O motor de azimute (motor AZ) e o motor de elevação (motor EL) são mostrados. Os sensores são fixados aos eixos da antena conforme a antena parabólica muda de posição, a saída analógica do sensor muda. Assim que a posição do sensor corresponder à posição inserida em termos de ângulo de azimute e ângulo de elevação, ambos os motores param de girar. Posteriormente, caso haja algum desvio na posição da antena por qualquer circunstância, ela atinge automaticamente a posição desejada por meio de motores. Se quisermos mudar a posição da antena (talvez para rastrear outro satélite), então mudamos o ângulo de azimute e o ângulo de elevação e, novamente, a antena se move para uma nova posição modificada. Esta é a descrição do sistema real. É composto por motores grandes e pesados ​​​​que podem suportar a carga, e o tamanho da antena parabólica giratória varia de 3 a 15 metros. O RVDT é escolhido (ou mesmo customizado) de acordo com o grau de rotação desejado da antena. Ele fornece saída de tensão analógica correspondente de acordo com as mudanças de posição da antena. Todo o sistema é calibrado com precisão para saída RVDT de acordo com a posição do ângulo da antena em ambas as dimensões. Por exemplo, considere que o RVDT tem uma faixa angular de -45o a +45o, e a saída analógica correspondente é de 0 a 5 V. Isso significa que para uma mudança de ângulo de 90o, a variação da mudança de tensão é de 5V. Portanto, para cada grau de mudança no ângulo, a tensão de saída muda em 5/90 = 0,055 = 55 mV (aprox.). Se este RVDT for usado em um sistema de tal forma que, à medida que a antena se move de 0o a 90o, ele fornece uma saída de 0 a 5 V, então cada mudança de grau na posição da antena é detectada como uma mudança de ± 55 mV na saída de tensão. O sistema de controle detecta essa tensão e gera sinais para acionar os motores. Os motores e o mecanismo de engrenagem correspondente também são projetados para girar a antena na faixa de 0o a 90o (ou 180o ou até mais) em incrementos de 1o em ambas as dimensões. Geralmente, a faixa do ângulo de elevação é de 0o a 90o, e a faixa do ângulo de azimute pode ser de 0o a 180o ou até mesmo 360o. É assim que o sistema real é projetado e funciona. Mas aqui discuti a demonstração de tal sistema. Modelo de demonstração: – A figura mostra a disposição do sistema. Existem dois motores. Ambos os motores são motorredutores DC de 12 V com velocidade de 10 RPM. O motor que gira o prato no plano horizontal é conhecido como motor de azimute, e outro motor o gira no plano vertical que é o motor de elevação. Dois sensores opto-interruptores são usados ​​para fornecer feedback da posição angular do motor. Ele usa uma roda de codificação que é fixada no eixo de cada motor. A roda de codificação possui furos (ranhuras) em 10o, 20o, 30o, da mesma forma. A disposição é feita de forma que à medida que o motor gira, a roda também gira; seus orifícios passam pela abertura do sensor e geram um pulso. Isso significa que o sensor gera um pulso a cada 10o de rotação do motor. A própria figura descreve como todo o arranjo é feito, mas deixe-me discuti-lo passo a passo. • Todo o sistema é montado sobre uma caixa de madeira que abriga o circuito e serve de base ou plataforma para todo o mecanismo. • O 1º motor DC (motor azimutal) é fixado dentro de uma caixa de madeira por meio de parafusos e cavilhas. A roda de codificação (roda azimutal) é fixada com seu eixo conforme mostrado • O sensor 1 MOC7811 (sensor de azimute) também é montado verticalmente usando um pequeno suporte de madeira na mesma plataforma de madeira de forma que os furos da roda de codificação de azimute passem pela abertura do sensor • Uma tira de metal em formato AU com cerca de 2 polegadas de largura é soldada diretamente ao eixo do motor DC. um lado do formato de U é bastante longo para os outros, como mostrado. • Esta tira é usada para montar o 2º motor DC e outro sensor. O 2º motor CC (motor de elevação) é montado na tira em U usando braçadeira de montagem e parafusos no lado mais curto, enquanto o sensor 2 (sensor de elevação) é fixado na extremidade do braço longo (lateral) • Um prato (feito de papelão e papel alumínio) é fixado diretamente no eixo deste motor 2. A 2ª roda de codificação (roda de elevação) também é fixada na extremidade do eixo do motor 2 conforme mostrado • Esta roda e sensor de elevação são novamente fixados de forma que os furos da roda passem pela abertura do sensor Aqui está o snap do modelo. Funcionamento do modelo de demonstração: – • Inicialmente, o ângulo de ambos os motores é ajustado em 0o na roda de codificação. Significa que a antena parabólica tem ângulo de azimute de 0o e ângulo de elevação de 0o • O ângulo de azimute pode ser definido de 0o a 350o em incrementos de 10o. O usuário pode definir o ângulo desejado usando botões • Em seguida, o usuário deve definir um ângulo de elevação. Pode ser ajustado de 0o a 70o no passo de 10o usando botões • Quando ambos os ângulos são definidos, o usuário pressiona outro botão para girar o prato • À medida que o botão é pressionado, o motor de azimute começa a girar para definir o ângulo de azimute. À medida que o motor gira, a roda de codificação também gira e seus orifícios passam pela abertura do sensor. O sensor gera pulsos que fornecem feedback sobre a posição angular do motor. O motor gira até que o ângulo definido e o ângulo de rotação real do motor se tornem iguais. Se o ângulo definido for maior que o ângulo real do motor, o motor gira no sentido horário e se o ângulo definido for menor, o motor gira no sentido anti-horário • O próximo motor de elevação começa a girar. Ele gira o prato e também a segunda roda de codificação. Novamente o motor gira até que o ângulo definido e o ângulo de rotação real do motor se tornem iguais. Ele também gira CW ou CCW conforme o ângulo definido é maior ou menor que o ângulo real • Assim, a antena parabólica atinge a posição angular desejada nos planos de azimute e elevação Hardware Conforme mostrado na figura, o circuito é construído utilizando sensores MOC7811, chip driver de motor L293D, LCD 20×4 e microcontrolador ATMega16. • Os circuitos dos sensores são construídos em torno do MOC7811. Ambos os circuitos do sensor são idênticos. O LED IR interno recebe alimentação de 5 V através de um resistor limitador de corrente de 33,0E, e o fototransistor é conectado em configuração de chave usando um resistor externo de 1K. A saída final do circuito do sensor é através do coletor do fototransistor • Ambas as saídas dos sensores estão conectadas aos pinos de interrupção externa PD2 e PD3 do ATMega16. • Os pinos PA0 a PA4 do PORTA são conectados ao terra através de rede de resistores (5 resistores de 1K). Cinco botões são conectados a esses pinos de forma que, quando o botão é pressionado, a lógica 1 é dada como entrada. O resto dos pinos do PORTA estão conectados com Vcc • PORTC aciona os pinos de dados D0 – D7 do LCD. Dois pinos de controle Rs e En ou LCD são conectados aos pinos PORTB PB4 e PB5, respectivamente. O pino RW do LCD está conectado ao terra para permitir a gravação • Pinos PORTB PB0 – PB3 acionam 2 motores DC através do chip L293D. Esses pinos são conectados à entrada do L293D, e dois motores são conectados às saídas do L293D • Um cristal de 16 MHz é conectado aos pinos de entrada do cristal do ATMega16. Dois capacitores de 22pf são conectados para polarização e estabilidade do cristal • Botão de reinicialização conectado conforme mostrado com o pino de entrada de reinicialização para fornecer uma reinicialização manual ao microcontrolador Operação: – • Inicialmente o LCD mostra o ângulo AZ definido e o ângulo EL definido como 0o. Ele também mostra o ângulo AZ e o ângulo EL atuais como 0o. • O usuário deve definir o ângulo AZ e o ângulo EL pressionando os botões de aumento/diminuição do ângulo AZ e os botões de aumento/diminuição do ângulo EL • Sempre que um botão é pressionado, o ângulo é alterado em 10o • Depois de definir os ângulos de rotação, o botão do prato é pressionado. Ambos os motores giram um por um até que os ângulos da antena parabólica correspondam ao ângulo de azimute e ângulo de elevação definidos Programas • O software é escrito em linguagem C • Compilado usando AVR Studio 4 • Testado usando AVR simulatro1 para dispositivo ATmega16 (disponível com AVR Studio 4)

Código-fonte do projeto

###

//Program to

Here is the complete program with necessary comments. 

#include 

#include 

#include 

#include 

unsigned int set_az_angle=0, set_el_angle=0,dish_az_angle=0,dish_el_angle=0, rotate_reverse_flag=0,up_down_flag=0;

/////////////////   function to send data to be displayed on LCD /////////////////////

void lcd_senddata(unsigned char data)

 {

_delay_ms(2);

PORTB=(1< // get the length of string

for(i=0;i // write every char one by one

s++; 

}

}

//////////////  function to initialize LCD  //////////////////////////////////////////

void lcd_init 

  {

    lcd_sendcmd(0x3E); // 8 bits per char

lcd_sendcmd(0x0E); // screen on and cursor ON

lcd_sendcmd(0x01); // clear LCD memory and home cursor

lcd_sendcmd(0x84); // go to column 4 of line 1

lcd_printstr("Dish antenna"); // display message

lcd_sendcmd(0xC4); // go to column 4 of line 2

lcd_printstr("angle control"); 

  }

//////////////////  function to display angle value on LCD ///////////////////////////

void display_value(unsigned int angle)

  {

   unsigned int t1,a;

unsigned char asci(3);

unsigned int t;

t = angle;

if(t>=100)

    {

   a=2;

   while(t>=10)

   {  

    t1=t%10;

    asci(a)=t1+0x30;

    t=t/10;

    a--;

   }

   asci(0)=t+0x30;

    }

  else

    {

   t1=t%10;

             asci(2)=t1+0x30;

             t=t/10; 

             asci(1)=t+0x30;

             asci(0)=0x20;

          }

     lcd_senddata(asci(0));

     lcd_senddata(asci(1));

     lcd_senddata(asci(2));

     lcd_senddata(0xDF);

  }

/////////////////////// function to increment azimuth angle value ////////////////////

void inc_az_angle 

  {

      if(set_az_angle<360) 

             set_az_angle+=10; // increment set angle by 10o till its not 360o

      lcd_sendcmd(0x8D);

      display_value(set_az_angle);        

  }

/////////////////////// function to decrement azimuth angle value ////////////////////

void dec_az_angle 

  {

      if(set_az_angle>0) 

            set_az_angle-=10;   // decrement set angle by 10o till its not 0o

      lcd_sendcmd(0x8D);

      display_value(set_az_angle);    // display it on LCD 

  } 

/////////////////////// function to increment elevation angle value //////////////////

void inc_el_angle 

  {

     if(set_el_angle<70) set_el_angle+=10;

     lcd_sendcmd(0xCD);

     display_value(set_el_angle); 

  }

/////////////////////// function to decrement elevation angle value //////////////////

void dec_el_angle 

  {

      if(set_el_angle>0) set_el_angle-=10;

      lcd_sendcmd(0xCD);

      display_value(set_el_angle); 

  }     

//////////////// function to rotate dish /////////////////////////////////////

void rotate_dish 

  {

      if(set_az_angle>dish_az_angle) // new set az angle is larger

                   rotate_reverse_flag=0; // rotate dish CW

      else // otherwise 

            rotate_reverse_flag=1; // rotate dish CCW

      if(set_el_angle>dish_el_angle)                  // if new set el angle is larger

                       up_down_flag=0;                // move dish up

      else  // otherwise

              up_down_flag=1;  // move dish down

      if(rotate_reverse_flag==0)

         {

            //////// rotate CW dish till set az angle and dish az angle are not same

            while(set_az_angle!=dish_az_angle) PORTB = 0x01;

            PORTB = 0x00;                             // stop when same

         }

      else

         {

            // rotate CCW dish till set az angle and dish az angle are not same

            while(set_az_angle!=dish_az_angle) PORTB = 0x02;

            PORTB = 0x00;                            // stop when same

         } 

     if(up_down_flag==0)

         {

            // move dish up till set el angle and dish el angle are not same

            while(set_el_angle!=dish_el_angle) PORTB = 0x04;

            PORTB = 0x00;                               // stop when same

          }

     else

          {

             // move dish down till sent el angle and dish el angle are not same 

            while(set_el_angle!=dish_el_angle) PORTB = 0x08;

            PORTB = 0x00;                                // stop when same

          } 

    }       

int main(void)

{

    DDRC=0xFF; // initializes ports as

    DDRD=0xC3; // input or output

    DDRB=0xFF;

    DDRA=0x00;

    PORTC=0x00; 

    PORTB=0x00;

    MCUCR = (1< 

    GICR=(1< // enable external interrupts 

    sei ; // enable global interrupts

    lcd_init ; // initialize LCD

    _delay_ms(2000); // wait for 2 sec

    lcd_sendcmd(0x01); // clear LCD

    lcd_printstr("Set AZ angle:"); // display angle values

    display_value(set_az_angle);

    lcd_sendcmd(0xC0);

    lcd_printstr("Set EL angle:");

    display_value(set_el_angle);

    lcd_sendcmd(0x94);

    lcd_printstr("Dish EL angle:");

    display_value(set_el_angle);

    lcd_sendcmd(0xD4);

    lcd_printstr("Dish EL angle:");

    display_value(set_el_angle);

loop:while(PINA==0xE0);                 // loop until no switch is pressed 

    switch(PINA)

      {

         case 0xE1:                     // when switch 1 is pressed

            inc_az_angle ;             // increment az angle

            _delay_ms(200);             // delay for key debounce 

            break;

         case 0xE2:                     // same as above

             dec_az_angle ;

             _delay_ms(200); 

             break;

         case 0xE4:

            inc_el_angle ;

            _delay_ms(200); 

            break;

         case 0xE8:

            dec_el_angle ;

            _delay_ms(200); 

            break;

         case 0xF0:

            rotate_dish ; 

            break;   

       }      

goto loop;

}

///////////////// external interrupt 0 service routine //////////////////////////////

ISR(INT0_vect)

  {

    if(rotate_reverse_flag==1) // if dish is rotating reverse

      {

        if(dish_az_angle>0) dish_az_angle-=10;       // decrement angle value by 10

      }

    else                                            // otherwise

      {

        if(dish_az_angle<360) dish_az_angle+=10;   // increment angle value by 10

      } 

   lcd_sendcmd(0xA2);

   display_value(dish_az_angle);                   // display angle value on LCD 

  }

///////////////// external interrupt 1 service routine //////////////////////////////

ISR(INT1_vect)

  {

    if(up_down_flag==1) // if dish is moving down

      {

         if(dish_el_angle>0) dish_el_angle-=10; // decrement angle value by 10

      }

    else                                             // otherwise 

      {

         if(dish_el_angle<70) dish_el_angle+=10;     // increment it by 10

      } 

    lcd_sendcmd(0xE2);

    display_value(dish_el_angle);                    // display it on LCD                  

  } 

###

Diagramas de circuito

circuito principal

Vídeo do projeto

Tillbaka till bloggen

Lämna en kommentar

Kommentarer måste godkännas innan publicering.