Quantcast
Channel: MakerHero
Viewing all articles
Browse latest Browse all 416

Vídeo: Controle de Servo Motor Por Interrupção

$
0
0

Vídeo: Controle de Servo Motor Por Interrupção

Em nosso último tutorial demonstramos como efetuar o controle de um servo motor sem a utilização da clássica biblioteca servo.h. No projeto, utilizamos as funções de delay disponíveis na IDE do Arduino. Também mencionamos que era a forma mais simples mas não a melhor forma de se controlar um servo. Hoje você aprenderá a controlar um servo motor 9G por interrupção, que será muito mais eficiente.

As interrupções tornam possível o uso de um processador para execução de diversas tarefas. Em seu computador, toda vez que movimenta o mouse, utiliza um periférico USB, dá entradas no teclado, você está gerando interrupções por exemplo. Caso o processamento das tarefas fosse realizado por polling (laços de programa que prendem o processador a uma única tarefa), a execução de várias tarefas seria inviável. Vale salientar que nenhum processador é capaz de executar duas tarefas ao mesmo tempo. Nos microcontroladores isto não é diferente, pois os mesmos também são processadores.

Conectando o Servo Motor ao Arduino

O hardware do projeto de hoje é bem simples. Conecte um servo motor na pino digital 4 do Arduino e um potenciômetro linear de 50k no pino analógico 0 (Figura 2). Um detalhe importante é que o presente projeto funcionará apenas para Arduinos que utilizem o microcontrolador Atmega328P, tais como o NANO, UNO e DUEMILANOVE. O Arduino Mega não funcionará nesta aplicação, pois utiliza o MCU Atmega2560.

Figura 2 – Hardware do projeto

No software, configuramos os registradores do Atmega328P para trabalharem com o Timer2. O Timer2 consiste em um registrador utilizado para contagem e temporização. Através dos registradores especiais TCCR2A, TCCR2B, TCNT2 e TIMSK2 configuramos a operação do timer no modo normal, com prescaler 1:1024, inicializando o conteúdo do Timer2 em zero e habilitando a interrupção do Timer2, respectivamente.

Em suma, o Timer2 vai contar cada ciclo de máquina do processador até chegar ao valor limite (255 decimal). Quando houver a transição de 255 para 0 (reinício da contagem), ocorre o estouro (overflow) do Timer. Esse estouro vai gerar uma interrupção no processador, desviando o código para a função ISR(TIMER2_OVF_vect). O algoritmo presente nesta função de interrupção é destinado à criação do PWM, referente ao diagrama de tempos dos servo motores.

Programa controle de servo motor por interrupção

O código completo está explícito no Box 1 e totalmente comentado.

/*
   Aula 68 - Controle de Servo Motor por Interrupção (Timer Overflow)
     
   Autor: Eng. Wagner Rambo
*/


// --- Mapeamento de Hardware ---
#define servo1  4     // Servo 1 conectado no pino digital 4
#define pot    A0     // Potenciômetro de controle no pino A0


// --- Variáveis Globais ---
unsigned char duty = 0x00;    //Variável para alterar o duty cycle
int adc = 0x00;               //Armazena leitura analógica


// --- Rotina de Interrupção ---
ISR(TIMER2_OVF_vect)
{
     
    if(digitalRead(servo1))               //Saída servo1 em high?
    {                                     //Sim...
         TCNT2 = duty;                    //Timer2 recebe valor atual do duty
         digitalWrite(servo1, LOW);       //Saída do servo1 em low
    } //end if servo1
    else                                  //Senão...
    {
          TCNT2 = 255 - duty;             //Timer2 recebe valor máximo menos valor do duty
          digitalWrite(servo1, HIGH);     //Saída do servo1 em high

    } //end else
    
} //end interrupt


// --- Configurações Iniciais ---
void setup()
{
     pinMode(servo1,OUTPUT); //saída para o servo1
     pinMode(pot, INPUT);    //entrada para o potenciômetro
     
     TCCR2A = 0x00;   //Timer operando em modo normal
     TCCR2B = 0x07;   //Prescaler 1:1024
     TCNT2  = 0;      //Conteúdo do Timer2 inicia em zero
     TIMSK2 = 0x01;   //Habilita interrupção do Timer2
     
     digitalWrite(servo1, LOW);
     
     duty = 16;       //Inicia duty no valor mínimo para o servo
 
} //end setup
 

// --- Loop Infinito ---
void loop()
{
   //Aguarda Interrupção...
   
   adc = (analogRead(pot))/64;  //adc recebe a leitura ad do potenciômetro
   
   duty = adc + 16;             //valor do duty atual mais shift de 16 (cálculos explícitos abaixo)
    
   

 
} //end loop


/*
    Ciclo de máquina = 1/Fosc = 1/16E6 = 62,5ns = 62,5E-9s
   
    Estouro = (256 - TCNT2) x prescaler x ciclo de máquina
            = (256 -     0) x   1024    x    62,5E-9      
            = 16.384ms 


    Regra de 3
    
    256     n
    
    16ms    1ms

*/

Para download completo dos arquivos sobre este post de controle de servo motor por interrupção, utilize este link.

Gostou ? Ajude-nos a melhorar o blog atribuindo uma nota a este tutorial (estrelas no final do artigo), comente e visite nossa loja FILIPEFLOP!

Site: Blog FILIPEFLOP


Viewing all articles
Browse latest Browse all 416