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

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 MakerHero
*/

#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. 

Referências

Faça seu comentário

Acesse sua conta e participe

44 Comentários

  1. Excelente projeto e apresentação muito didática! Muito grato! Minha pergunta é: posso manter o mesmo tipo de alimentação para trabalhar com dois motores, ou seja, apenas incluindo um segundo motor DC 3-6V com redução no esquema aqui proposto?

    1. Olá.

      O Driver de motor usado nesse projeto possui duas saídas de motor. Basta você colocar o outro motor na outra saída.

      Se os motores funcionarem em paralelo (acionados ao mesmo tempo) basta duplicar o sinal no comando do outro motor. No caso, o sinal do Arduino entra no MA e MB do driver.

      Att.
      Vitor Mattos.
      Suporte Técnico MakerHero.

      1. Obrigado! Minha dúvida especificamente é se a corrente será suficiente para suprir os dois motores mantendo o esquema acima ou se eu precisaria efetuar uma mudança na alimentação.

  2. Boa tarde! Teria algum Sketch que eu consiga controlar os motores via SERIAL MONITOR?? TIPO DE 0% A 100%?? conforme a porcentagem aumenta ou diminui altera a rotação dos motores no SERIAL MONITOR.

  3. Olá, bom dia. Adorei a matéria. Mas como eu poderia colocar em um display LCD (disponível no tinkercad) para mostrar a velocidade em tempo real desse motor? Como eu poderia fazer isso no código?Desde já obrigada.

    1. Olá!

      Obrigado!

      No caso você quer mostrar a velocidade de rotação real do motor ou em % do RPM total?

      Caso queira a rotação real, é preciso algum sensor para fazer a leitura da rotação.

      Aqui temos um exemplo de como utilizar o display LCD: https://www.makerhero.com/blog/controlando-um-lcd-16×2-com-arduino/

      Abraços!
      Vinícius – Equipe MakerHero

  4. Boa noite. Estou tentando achar uma solução para um problema e acho que o senhor poderia contribuir muito.
    Troquei o cambio do meu carro (opala) por um cambio que usa o sistema de pulsos para alimentar o velocímetro (Blazer).
    No entanto, meu velocímetro é mecânico e eu preciso desenvolver um sistema que converta determinada quantidade pulso/min e RPM em um motor DC 12v ou 6v, que será conectado diretamente ao velocímetro, fazendo as vezes do cabo de aço. Se o senhor ou outra pessoa puder me ajudar, eu agradeceria muito.
    André Márcio 88 99300 6873

  5. Olá, gostei bastante do artigo, estou interessado em saber se este módulo PWM serve para qualquer um dos motores do kit de motores que vcs estão vendendo, estou interessado em compra-los e testar todos eles com este módulo. Aguardo o retorno, obrigado! Outra coisa, eu sou de SP, quanto tempo levaria a entrega, considerando a situação?

    1. Julio

      Desde que os motores não ultrapassem o limite de 35V, funciona sim 🙂

      Abraços!
      Diogo – Equipe MakerHero

      1. Como fica pra ter o controle de rpm e reversão?

  6. Olá Pedro,

    Vc saberia me orientar como criar algum código PWM, mas com realimentação tipo PID, ou seja, eu monitoraria a rotação de um motor por ex. a 50 %, e mesmo com variação de carga até um certo nível, o sistema mantivesse a rotação constante?

  7. Olá , ótimo projeto de PWM. Gostaria de saber como seria o diagrama para usar este projeto com alimentação externa independente. Quero que o projeto funcione completamente independente da fonte lógica. Precisaria usar o GRND no segundo pino lógico? E o 5V da placa preciso utilizar no componente, se sim em que pino?

    1. Marcelo,

      Não entendi muito bem. Você quer alimentar o Arduino externamente ou o motor?

      Abraços!
      Diogo – Equipe MakerHero

  8. Olá Pedro, tem como controlar pwm de um motor dc sem usar esses Circuitos integrados ? Tenho muito pouco espaço e um ci l293d ainda è grande para meu projeto.

  9. Mandou bem, todos dizem para não ligar o MA e MB ao 5v para uso do PWM, mas voce mostrou que não é assim. Parabéns

    1. Paulo,

      Que bom que curtiu nosso conteúdo!

      Abraços!
      Diogo – Equipe MakerHero

  10. Bom dia,
    gostaria de fazer um controle de velocidade quando coloca um PINO A =1 começa a acelera PINO B =0 DESACELERA
    pinos A e B =0 não faz nada..

    1. Nerci,

      Você pode fazer condicionais para isso:

      if (PINOA == 1) {
      código para acelerar o motor
      }
      if (PINOB == 0) {
      código para desacelerar o motor
      }
      else {}

      Abraços!
      Diogo – Equipe MakerHero

  11. boa tarde, gostaria de saber se posso usar esse projeto em uma torre de radioamador para girar uma antena no sentido horário e anti-horário?

    1. Felipe,

      Desde que o motor seja forte o suficiente para girá-la, não tem problema algum 😉

      Abraços!
      Diogo – Equipe MakerHero

  12. Olá. Estou montando um projeto onde controlo um motor DC via bluetooth com o módulo HC05 e um Drive TB6612. Gostaria que o start do motor fosse gradativo (aumento de velocidade via PWM). Mas, minha cabecinha oca não consegue imaginar quais regras usar no código. Pq quando eu comandar “Rodar Direita” ele precisa ‘ler’ o estado atual para, ou desacelerar se estiver rodando para a esquerda, ou não fazer nada se já estiver rodando para a direita ou iniciar o pwm para rodar a direita caso esteja parado. Help!

    1. Valdir,

      Sugiro você criar um tópico no nosso fórum, lá é muito mais fácil de a gente se ajudar 🙂

      Abraços!
      Diogo – Equipe MakerHero

  13. gostaria de fazer um controle de velocidades , exemplo pino x =1 vai de 0 a 255..e pino x=0 vai de 255 a 0..

    1. Nerci,

      Você pode alterar o código para adicionar os motores ali. Fica bem parecido com o código do post 🙂
      Abraços!
      Diogo – Equipe MakerHero

      1. Boa noite tem como usar rotação inversa usando o PWM estou tentando mas não consigo.

        1. Julio,

          Não é possível fazer isso. Para inverter a rotação é necessária a utilização de algum circuito extra.

          Abraços!
          Diogo – Equipe MakerHero

          1. pra inverter a rotação não da pra usar duas saidas pwm, uma pra cada sentido.. ?

            Natã Ramos da silva junior
      2. muito obrigado
        forte abraço..

  14. Vlw!

    Estava procurando algo do tipo para controlar o cooler em um sistema de resfriamento q estou montando p exposição no curso!

    1. Emerson,

      Que bom que gostou 🙂

      Abraços!
      Diogo – Equipe MakerHero

  15. Boa tarde,

    Com essa placa (Ponte H L298n) + um Arduino Uno R3, eu consigo controlar uma eletroválvula (solenoide PWM), de 12 V com 4 A ?
    Ou quando eu habilitar a alimentação externa de 12 V ela vai desabilitar o controle PWM do arduino ?

    1. Bruno,

      Não é para ter relação alguma a alimentação externa com a execução do PWM.

      Abraços!
      Diogo – Equipe MakerHero

      1. Não entendi bem a sua resposta.
        Quer dizer que funcionaria, o solenoide com essa ponte H?

        1. Isso. O solenoide não influenciaria o PWM.

          Abraços!
          Diogo – Equipe MakerHero

  16. Ola, muito bacana o projeto, mas fiquei em dúvida na ligação 5v do Driver ponte H (ali não é saída de 5v), o correto não seria ligar no pino 6-35v?

    Thiago Arthur Luchi Ferreira
    1. Olá, Thiago,

      Ali é a alimentação do módulo. Como você está alimentando-o com 5V, é ali mesmo.

      Abraços!
      Diogo – Equipe MakerHero

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

    EDENILSON TEIXEIRA PASCHOA
  18. 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);
    }

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

  20. 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

    1. Bom dia, Paulo Dias! A ficaria necessidade é a mesma que a minha. Acredito que para o motor funcionar com 50% da rotação basta reduzir a variável “valor_pwm” para 128, então ficaria:

      for (valor_pwm = 0; valor_pwm < 128; valor_pwm++)

      Testa aí e depois me fala se deu certo!

    2. Exato! neste projeto tem que ser desabilitado (retirado jumper de MA ) para que se possa controlar a velocidade do motor. Caso contrario a velocidade fixará em 100% e neste projeto acima citado foi informado para colocar um jumper no ativa MA o que está errado, pois queremos controlar a velocidade e não deixa-lá fixada em 100%.

      Douglas Rodrigo Fialho dos Santos