Controle de velocidade de motor DC com PWM no Arduino UNO 4

Os sistemas embarcados estão cada vez mais presentes no nosso dia-a-dia. Basta olhar ao seu redor: há sistemas embarcados presentes em televisores, monitores, smartwatches, celulares, setup boxes, veículos, iluminação inteligente, etc. Enfim, os sistemas embarcados dominam, mesmo que silenciosamente, a maneira como a tecnologia evolui. Uma das tarefas dos sistemas embarcados é o controle de atuadores, dos quais um dos mais comuns são motores DC (cuja velocidade pode ser controlada com precisão pela grande maioria dos microcontroladores disponíveis no mercado). E é justamente disso que este post se trata: como fazer o controle da velocidade de motores DC com PWM.

Material necessário

Para reproduzir o projeto deste post, você precisará de:

PWM: resumo

O nome PWM é uma sigla que significa Pulse Width Modulation (Modulação em Largura de Pulso). O PWM trata-se de uma modulação digital / em sinal digital, ou seja, trabalha com somente dois níveis de sinal: on (ou ‘1’) e off (ou ‘0’). Em termos simples, o PWM controla quanto tempo um sinal digital fica em on em uma determinada janela de tempo fixa (chamada de período). Observe a figura abaixo, onde o tempo em on é representado por t1 e o período por t.

 

Figura 1 - sinal PWM

Eletricamente, é possível afirmar que o PWM faz com que a tensão média num dado período possa ser controlada. Quanto mais tempo o sinal fica em on no período, maior a tensão média do sinal neste mesmo período. A esta porção de tempo em que o sinal fica em on no referido período, é dado o nome de Duty Cycle. O Duty Cycle é comumente tratado na forma porcentagem, como uma fração do período total do sinal. Em termos matemáticos, este pode ser calculado como:

 

Figura 2 - fórmula para cálculo do Duty Cycle

A tensão média, em termos do Duty Cycle, pode ser representada conforme mostra a figura abaixo.

Figura 3 - tensão média em função do Duty Cycle

 

Logo, segue alguns exemplos de relação direta de Duty Cycle e tensão média:

  • Duty cycle de 0%: tensão média igual a 0V
  • Duty cycle de 50%: tensão média igual a metade da tensão do sinal lógico.
  • Duty cycle de 100%: tensão média igual a tensão do sinal lógico.

Além disso, em se tratando de atuadores DC (por exemplo, motores DC), é possível afirmar que o Duty Cycle é aplicável também à potência entregue (em relação à máxima possível), ou seja:

  • Duty cycle de 0%: 0% de potência entregue ao atuador
  • Duty cycle de 50%: 50% da potência máxima entregue ao atuador
  • Duty cycle de 100%: 100% da potência máxima entregue ao atuador

Para mais informações sobre o PWM, consulte este e este sites.

Relação entre velocidade de motor DC e PWM

No caso dos motores DC, a “velocidade de giro” (RPM) pode ser controlada variando-se sua tensão de alimentação. Além disso, o RPM é diretamente proporcional à tensão aplicada. Portanto, variando-se a tensão média de alimentação do motor, varia-se o RPM do mesmo.

Em resumo: o sinal de PWM, devidamente amplificado, pode ser usado para controlar o RPM de um motor DC!

Isso significa que:

  • Duty cycle de 0%: tensão média igual a 0V, logo o motor fica parado
  • Duty cycle de 50%: tensão média igual a 50% da tensão de alimentação do motor, logo este girará com RPM igual a metade de sua rotação máxima
  • Duty cycle de 100%: tensão média igual a tensão de alimentação do motor, logo este girará com RPM igual a sua rotação máxima.

Neste caso, como amplificador para acionar o motor DC, irá ser usado um driver de motor (com ponte H) feito com o circuito integrado L298N. Trata-se de um driver muito versátil e muito utilizado para acionamento de motores DC de 3 – 6V. Para maiores informações deste módulo, veja este nosso post.

PWM no Arduino

A programação do Arduino (incluindo o Arduino UNO, utilizado neste post) já possui uma função nativa para gerar um sinal PWM em alguns dos pinos (aqueles identificados com um símbolo/identificação ~). Isso torna muito mais fácil o desenvolvimento dos projetos que envolvem PWM, permitindo fácil utilização do mesmo com pouquíssimo custo em termos computacionais (uso de memória Flash, RAM e processamento) e escrita de códigos-fonte mais limpos e curtos. Tal função é chamada de analogWrite(), e recebe dois parâmetros, conforme abaixo:

analogWrite(PINO, VALOR_ANALOGICO);

Onde:

  • PINO: número do pino do Arduino o qual se deseja que o sinal PWM seja gerado.
    Conforme dito anteriormente, somente pinos com símbolo/identificação podem gerar sinais PWM.
  • VALOR_ANALOGICO: valor (de 0 a 255), proporcional ao Duty Cycle a ser gerado.
    Ou seja, para Duty Cycle de 100%, deve-se utilizar valor 255, já para Duty Cycle 20% deve-se utilizar o valor 51 e assim por diante.

Para mais detalhes da função analogWrite(), consulte o guia de referência oficial do Arduino.

Circuito esquemático

ATENÇÃO:
1) NÃO utilize a alimentação pela USB de programação. Você, obrigatoriamente, deve utilizar a Fonte DC Chaveada 9V/1A. Caso contrário, você corre sérios riscos de danificar o dispositivo que está alimentando o Arduino pela USB de programação (computador, por exemplo).
2) NÃO SE ESQUEÇA de colocar um jumper em ATIVA MA .

 

Figura 4 - Driver (com ponte H) L298N

O motor deve ser ligado como o esquema abaixo.

Figura 5 - circuito esquemático

Código-fonte

Abaixo segue o código fonte do projeto. Este irá acionar o motor em velocidade crescente (de 0% a 100% da rotação máxima) e depois de forma decrescente (de 100% a 0% da rotação máxima) de forma gradual, de modo que seja possível perceber o motor acelerando e desacelerando. Observe que neste projeto o motor gira apenas em sentido horário.

/*
Controle de velocidade de motor DC com PWM
Autores: Pedro Bertoleti e FilipeFlop
*/

#define PINO_PWM                      3    //pino do Arduino que terá a ligação para o driver de motor (ponte H) L298N)
#define TEMPO_NA_MESMA_VELOCIDADE     300  //tempo (ms) em que o motor ficara na mesma velocidade 
 
void setup()
{ 
    //configura como saída pino terá a ligação para o driver de motor (ponte H) L298N)
    pinMode(PINO_PWM, OUTPUT);
}
 
void loop()
{   
    int valor_pwm = 0;   //variavel que armazena o valor do PWM (0..255 -> 0%..100% da rotação do motor) 

    //Aumento de velocidade (0%..100%)
    for (valor_pwm = 0; valor_pwm < 256; valor_pwm++)
    {
        analogWrite(PINO_PWM, valor_pwm);
        delay(TEMPO_NA_MESMA_VELOCIDADE);
    }

    //Diminuição de velocidade (100%..0%)
    for (valor_pwm = 255; valor_pwm >= 0; valor_pwm--)
    {
        analogWrite(PINO_PWM, valor_pwm);
        delay(TEMPO_NA_MESMA_VELOCIDADE);
    }
}

 

Gostou deste post sobre como controlar a velocidade de um motor DC com PWM? Deixe seu comentário logo abaixo. Em caso de dúvidas, caso queira trocar uma ideia, ou até mesmo dividir seu projeto, acesse nosso Fórum!

Referências

Deixe uma resposta

O seu endereço de e-mail não será publicado. Campos obrigatórios são marcados com *

4 Comentários

  1. Não consegui entender, os pinos MA, pelo que eu li em livros, este pino Enable A e B, servem para controle de velocidade dos motores… Se colocamos os jumpers, os motores não podem ser controlados, e apenas rodarão na velocidade máxima.
    Eu consegui controlar a velocidade do motor, colocando o EA e EB em portas PMW do Arduino, assim… no código:
    AnalogWrite( Motor1, porta EA no PWM (Velocidade));

    Não entendi o porque deu certo em seu projeto, controlar a velocidade sem o EA e o EB, gostaria de ajuda amigo 🙂

    Agradeço

  2. Oi Pedro. Como faço para fixar a rotação do motor em um valor ? EX: 50%. Obg

  3. Boa noite, montei uma maquina com um nema 34 para rodar uma esteira mas preciso que tenha uma parada precisa, estou usando o arduino controlar, quero apenas que ele rode determinada distancia e pare, mas quando rodo o arduino ele esta dando um tranco na saída e outro na parada, sei que estou mandando o PWM muito seco. tenho pouca experiencia e nao consigo inserir o seu código fonte no meu projeto, pode me ajudar?

    //resolução em 800
    //suit 1 a 6, o 3 esta off

    //dir pino 12 arduino
    //pul pino 9 arduino
    //start stop pino 8 arduino

    int pul = 9;
    int dir = 12;
    int vel = 120;

    void setup() {
    pinMode(pul, OUTPUT);
    pinMode(dir, OUTPUT);
    pinMode(8, INPUT_PULLUP);
    }

    void loop() {
    int start = digitalRead(8);
    if (start == 0) {
    direction(1);
    steps(1000);
    delay(500);
    }

    direction(0);
    steps(1000);
    delay(500);
    }

    void steps(int x) {
    for (int i = 0 ; i < x; i++) {
    pulse();

    }

    }

    void direction(bool d) {
    digitalWrite(dir, d);
    }

    void pulse() {
    digitalWrite(pul, 1);
    delayMicroseconds(vel);
    digitalWrite(pul, 0);
    delayMicroseconds(vel);
    }

  4. Para um motor de alta potência, como eu faria para um Shield controlar um IGBT?

    EDENILSON TEIXEIRA PASCHOA
{"cart_token":"","hash":"","cart_data":""}