Ponte H L298N – Controlando a velocidade de um motor DC com PWM
No último tutorial vimos como se faz para ligar um motor DC no Arduino com o auxílio de um módulo ponte H L298n, usando suas entradas para variar o sentido de giro. Mas na robótica, é comum termos que controlar, além do sentido, a velocidade do motor. Neste tutorial iremos ensinar, de forma simples e didática, como podemos controlar a velocidade de um motor DC usando o Driver motor com Ponte H L298n com Arduino.
[toc]
Como controlar a velocidade de um motor?
Um motor DC gira baseado em campos magnéticos gerados pela corrente que passa em suas bobinas. Para variar a velocidade do motor podemos alterar essa corrente que é diretamente proporcional a tensão sobre elas.
Dessa forma, com a mudança da tensão em cima do motor, teremos uma alteração de velocidade. mas como podemos fazer isso usando o Arduino e a Ponte H? A solução é simples e eficiente e se chama PWM.
O que é PWM?
PWM (Pulse Width Modulation – Modulação por Largura de Pulso) é uma técnica para obter resultados analógicos por meios digitais (Leia mais sobre Grandezas digitais e analógicas e PWM). Essa técnica consiste na geração de uma onda quadrada em uma frequência muito alta em que pode ser controlada a porcentagem do tempo em que a onda permanece em nível lógico alto. Esse tempo é chamado de Duty Cycle(Ciclo de trabalho) e sua alteração provoca mudança no valor médio da onda, indo desde 0V (0% de Duty Cycle) a 5V (100% de Duty Cycle) no caso do Arduino.
O duty cycle é a razão do tempo em que o sinal permanece na tensão máxima (5V no Arduino) sobre o tempo total de oscilação, como está ilustrado na figura abaixo:
Duty Cycle (%) = (x/x+y)*100% = (x/T)*100%
Vmédio = Vmáx*Duty Cycle(%)
O valor do Duty Cycle usado pelo Arduino é um inteiro armazenado em 8 bits, de forma que seu valor vai de 0 (0%) a 255 (100%).
Exemplo.: Para um sinal PWM de valor 200 temos:
Se 255 é 100%, 200 é aproximadamente 78,4%.
Como a tensão máx de saída do Arduino é 5V a tensão média do sinal PWM será:
Vmédio = Vmax*Duty Cycle(%)
Vmédio=5*78,4%
Vmédio=3,92V
Modulando a ponte H
No módulo Ponte H com CI L298N cada ponte H possui um pino que ativa ou não a ponte H. Caso tenha um sinal de 5V inserido nele, a ponte enta ligada, caso seja 0V a ponte esta desligada. Como temos 2 pontes H, temos o Enable A(Ativa A) e o Enable B (Ativa B).
Normalmente o Enable A e B fica em curto com um sinal de 5V da placa através de um jumper.
Se retiramos esse jumper e inserimos um sinal PWM nessa entrada, modularemos a tensão que é enviada para o motor no mesmo formato. Isso ocorre porque a ponte H só ira “funcionar” enquanto o sinal de Enable estive com 5V.
Sendo assim, a saída para o motor será um sinal PWM com um Duty Cycle igual ao do Enable e terá tensão média calculada pela seguinte formula.
Vmédio = Vmax(tensão PonteH)*Duty Cycle(%)
Com essa modulação, podemos variar a velocidade do motor através de PWM.
Mãos à obra – Controle de velocidade com Módulo Ponte H L298N – Arduino
Neste segundo exemplo, vamos verificar o controle de velocidade dos motores A e B.
Componentes necessários
Para este exemplo, utilizaremos:
- Placa Arduino UNO ou similar
- Módulo Ponte H L298N
- 2x Motores DC (pode ser feito com apenas 1)
- Fonte alimentação de 12V
Montando o projeto
Prossiga com a montagem conforme esquema abaixo(caso você use apenas um motor, basta desconsiderar o motor B:
Garanta que seu Arduino e a fonte externa estejam desligados durante a montagem.
Programando
Crie um programa (sketch) e salve com o nome de “exemplo1_Controle_velocidade”.
Agora vamos à implementação do programa. Dessa forma, dentro da IDE Arduino: escreva o seguinte código e ao final clique em Upload para que o programa seja transferido para seu Arduino.
/*Pinagem do arduino*/ //motor_A int IN1 = 2 ; int IN2 = 4 ; int velocidadeA = 3; //motor_B int IN3 = 6 ; int IN4 = 7 ; int velocidadeB = 5; //variavel auxiliar int velocidade = 0; //Inicializa Pinos void setup(){ pinMode(IN1,OUTPUT); pinMode(IN2,OUTPUT); pinMode(IN3,OUTPUT); pinMode(IN4,OUTPUT); pinMode(velocidadeA,OUTPUT); pinMode(velocidadeB,OUTPUT); } void loop(){ /*Exemplo de velocidades no motor A*/ //Sentido 2 digitalWrite(IN1,HIGH); digitalWrite(IN2,LOW); //Alta analogWrite(velocidadeA,230); //Intermediaria analogWrite(velocidadeA,150); //Baixa analogWrite(velocidadeA,80); /*Exemplo de variacao de velocidade no motor B*/ //Sentido 2 digitalWrite(IN3,HIGH); digitalWrite(IN4,LOW); //velocidade de 0 a 255 while (velocidade < 255){ analogWrite(velocidadeB,velocidade); velocidade = velocidade + 10; delay(50); } //velocidade de 255 a 0 while (velocidade > 0){ analogWrite(velocidadeB,velocidade); velocidade = velocidade - 10; delay(50); } }
Colocando para funcionar
Se tudo deu certo, teremos o motores fazendo os seguintes movimentos:
- Motor A gira em velocidade alta
- Motor A gira em velocidade intermediaria
- Motor A gira em velocidade baixa
- Motor B vai de parado para velocidade rápida gradativamente
- Motor B vai da velocidade rápida até totalmente parado gradativamente
Entendendo a fundo
Entendendo o Software
Primeiro definimos as pinos que estão conectados à ponte H para controle de cada motor.
//motor_A int IN1 = 2 ; int IN2 = 4 ; int velocidadeA = 3; //motor_B int IN3 = 6 ; int IN4 = 7 ; int velocidadeB = 5;
Veja que temos 3 pinos para cada motor. 2 para controle de sentido de giro e o terceiro para controle de velocidade.
Movimentando o motor
Para fazer o motor se movimentar, primeiro temos que informar para que direção ele deve girar:
//Motor_A //Sentido 2 digitalWrite(IN1,HIGH); digitalWrite(IN2,LOW);
Aqui vale lembrar da tabela de comandos apresentadas no tutorial Módulo Ponte H L298N – Controlando Motores com Arduino :
Para controlar o sentido, temos as seguintes combinações para o motor A(IN1 e IN2)
É importante ter em mente essas combinações:
//Sentido 1 digitalWrite(IN1,LOW); //0V digitalWrite(IN2,HIGH); //5V //Freia Motor digitalWrite(IN1,HIGH); //5V digitalWrite(IN2,HIGH); //5V //Sentido 2 digitalWrite(IN1,HIGH); //5V digitalWrite(IN2,LOW); //0V
Em seguida definimos a velocidade através de um sinal PWM no pino Enable A. Tal como explicado anteriormente.
//Motor_A //Velocidade Alta analogWrite(velocidadeA,230);
Quando não queremos controlar a velocidade, deixamos esse pinos com um jumper ligado ao 5V da placa. Assim garantimos que a ponte H trabalhe na velocidade máxima.
Como queremos controlar sua velociade, tiramos o Jumper e conectamos a uma porta PWM.
O comando para a saída PWM é:
analogWrite(pino_de_saida,PWM);
Onde PWM , que já foi explicado no inicio do tutorial, é um valor entre 0 à 255. Onde 0 simboliza que o ciclo de trabalho é de 0% (desligado o tempo todo) e 255 simboliza que o ciclo de trabalho é de 100% (ligado o todo).
Ou seja, podemos brincar com a velocidade variando esse valor de PWM.
No exemplo usado temos um pedaço de código onde variamos a velocidade dos motores de parado (PWM=0) até a velocidade mais rápida (PWM=255), subindo de 10 em 10 a velocidade.
//velocidade de 0 a 255 while (velocidadeB < 255){ analogWrite(velocidadeB,velocidade); velocidade = velocidade + 10; delay(50); }
Outra opção de Programa
Caso você queira fazer um código mais enxuto e modularizado, temos este exemplo de implementação um pouco avançado que usa funções. Em breve teremos um tutorial sobre o assunto.
#define MOTOR_A 1 #define MOTOR_B 2 #define HORARIO true #define ANTIHORARIO false //inicializa pinos void setup(){ for (int i = 2; i < 8; i++) pinMode(i,OUTPUT); } void loop(){ acionaMotor(MOTOR_A,HORARIO, 255); acionaMotor(MOTOR_B,ANTIHORARIO, 255); } //funcao para acionamento individual de cada motor void acionaMotor(int motor, boolean sentido, int velocidade){ if (motor == MOTOR_A){ digitalWrite(2,sentido); digitalWrite(4,!sentido); analogWrite(3,velocidade); } else if (motor == MOTOR_B){ digitalWrite(6,sentido); digitalWrite(7,!sentido); analogWrite(5,velocidade); } }
Fechamento
Esperamos que tenham gostado, deixe seu comentário com duvidas, sugestões ou com a foto ou vídeo de seu projeto!! Compartilhe à vontade.
Editado por Allan Mota e revisado por Ícaro Lobo
56 Comments
Deixe uma pergunta, sugestão ou elogio! Estamos ansiosos para ter ouvir!Cancelar resposta
Esse site utiliza o Akismet para reduzir spam. Aprenda como seus dados de comentários são processados.
Vc usou uma fonte 12v para alimentar, esses motores não operam em uma tensão de 3 a 6v? Pq não queimou? oq aconteceu?
Excelente .. Gostaria de acrescentar temporizador para ligar e desligar tambem estes motores .. sendo que quando um motor liga o outro desliga de acordo com o tempo definido..Pode ajudar e enviar o programa arduino adicional para fazer isso..?
Boa noite estou fazendo um TCC sobre um elevador e estou tendo muita dificuldade para controlar o motor estou com a Ponte H L298n para um motor de 24V 2A.
Sera que me ajudaria com a logica.
Vi um carinha usando os jumpers e controlando a velocidade direto nas portas da ponte h de direção, qual o mais eficiente
Estou fazendo uma bobinadeira, porém quero fazer uma rampa de subida, e outra de parada, mas para isso preciso controlar as rampas em conjunto com a a quantidade de voltas do motor.
digitalWrite(IN1,HIGH);
digitalWrite(IN2,LOW);
if(quantidade_girada == 0){
lcd.clear();
lcd.print(“Qtd Setada:”);
lcd.setCursor(11, 0);
lcd.print(enter);
int rampa = (enter * 75)/100;
while(quantidade_girada < enter){
if (velocidade 0){
analogWrite(velocidadeB,velocidade);
velocidade = velocidade – 3;
}
delay(50);
}
}
Segue uma parte do código, onde há o problema.
Caramba!!! Vocês explicam muito bem. Sou professora, e pude perceber a didática que usam para abordar os conteúdos. Simplesmente, didátiquíssimo. Rssss. Parabéns!!!!
Não é mais simples deixar o Enable A e B ligados. e dar a entrada pwm nos pinos IN1, IN2, IN3 e IN4 ?
Funcionou aqui.
Qual software foi utilizado para programar ? Desde já obrigado !!!
ótima explicação! Parabéns pelo material. Muito útil e fácil
Excelente postagem. Parabens.
Mas com essa ponte H, estou tendo problemas com motores DC de 12V.
O PWM informado nao está sendo proporcional na saida.
Ex: Se PWM 255 é 12V, se colocasse 127 deveria sair 6V, mas está saindo 8V.
Num grafico, a curva que deveria ser linear, está polinomial de 2o grau.
Alguma ideia? Sou de TI e nao de eletronica
Bom dia.
É possível utilizando essa ponte H e um motor DC de 9 volts com hélice fazer um esquema de estudo para PID simples?
A idéia seria colocar a hélice em uma extremidade de uma vareta que tem giro livre, o MPU6050 ficaria preso na vareta enquanto o PID controlaria a pontencia na saída PWM para a ponte H tentando zerar o angulo do giroscópio.
Olá Allan, muito boa sua explicação. Parabéns
Tenho uma dúvida estou montando um carrinho seguidor de linha com essa ponte e preciso alimentar pelo Arduíno com uma bateria de lítio, quando alimento externo funciona bem devagar quando ligo a bateria pelo Arduíno nada acontece.
Como posso fazer essa ligação?
Excelente explicação, muito didática !!!!!! Parabéns
Como faço pra usar essa montagem para o problema abaixo?
Uma esteira com 3 velocidades pré-definidas (baixa/média/alta), ele alterna entre as 3 velocidades de acordo com a velocidade de carregamento efetuado pelos operadores que é detectado por um sensor de presença. A esteira inicia com velocidade média e dependendo do tempo entre uma caixa e outra ele alterna entre as velocidades. As condições são:
-Tempo entre caixas menor que 5 segundos, selecionar BAIXA
-Tempo entre caixas entre 6 e 10 segundos, selecionar MÉDIA
-Tempo entre caixas maior que 11 segundos, selecionar ALTA
Excelente explicação, bem didática e com um bom conteúdo. A partir de agora estarei acompanhando o vidadesilicio. Abraço
Olá,
Estou tentando fazer o contro dos moteres através do nodemcu esp8266 com o l298n, mas não esta dando certo.
Se eu deixo a ponte no ENA no l298n (velocidade máxima) funciona, mas se utilizo o comando:
analogWrite (ENA, 80);
E ligo no ENA, nada acontece, consegue me ajudar ? ><
Olá Luana, Isso é normal, tem a ver com as propriedades físicas do motor. Quando você coloca um sinal PWM de 80 no enable você está colocando uma tensão de (80/256)*100% = 31,25% em cima do motor. Ou seja, se seu motor é de 12V, você está com uma tensão média de 3,75V nele. Para valores muito baixos de tensão, o motor não consegue ter Força (torque) suficiente para girar.
Você precisa verificar qual é o menor valor de PWM que você pode colocar no ENB para que o motor comece a girar. Você pode fazer isso experimentando vários valores.
Deixe-me saber se te ajudei. Abraço!
Muito bom o tutorial! só tenho uma duvida,por que precisa definir essa variável auxiliar?
Essa variável auxiliar é apenas para demonstrar a variação de velocidade do motor.
Muito, bom Allan. Voce poderia me dar uma ajuda com o BTN7970b? ele é bem parecido com o l298n, mas estou me batendo um pouco com os pinos, mesmo lendo o datasheet.
Parabéns, explicação clara e objetiva. Já recomendei aos meus alunos
Sensacional ! Você está de parabéns, muito obrigado pela apostila 3 com ponte h pois estou desenvolvendo automação para aeromodelismo, foi ótimo. mais uma vêz muito obrigado !
Olá, ótimo tutorial. Só tem um errro, nas condições do while: o comparador deve ser a variável “velocidade” e não “velocidadeB”, caso contrário jamais sairá do loop e a velocidade não será variada. Valeu! :)
Muito obrigado pela correção!
Olá Allan Mota estou com um projeto automodelo, o que você me recomendaria ?
preciso dar velocidade e força para automodelo , preciso utilizar um servo motor para fazer o giro lado E/D
Olá Eduardo!
Deu pra ver que vc manja do assunto!
Esse tipo de dispositivo (arduino) consegue de alguma forma controlar motores dc de 10, 20, 40 kw? Grato pela atenção!
Ei Tiago, isso era um erro do layout da página. Ele estava considerando o < ou > como parte do código html da página e fazendo essa doidera ai! hehehehe.
Daniel/Allan Mota, qual a magica para o compilador do arduino aceitar a sintaxe < (menor que) para while, conforme você postou no seu código? Minha versão de arduino é a 1.8.5 e não aceita essa sintaxe, alegando que < não foi declarada no escopo. Assim sendo o compilador ao invés de usar < aceitou < 250
to com esse erro ai na linha: for (int i = 2; i &1t; 8; i++)
Arduino: 1.8.3 (Windows 10), Placa:”Arduino/Genuino Mega or Mega 2560, ATmega2560 (Mega 2560)”
C:\Users\ander\Desktop\teste33\teste33.ino: In function ‘void setup()’:
teste33:7: error: unable to find numeric literal operator ‘operator””t’
for (int i = 2; i &1t; 8; i++)
^
teste33:7: error: expected ‘)’ before ‘;’ token
for (int i = 2; i &1t; 8; i++)
^
teste33:7: error: ‘i’ was not declared in this scope
for (int i = 2; i &1t; 8; i++)
^
exit status 1
unable to find numeric literal operator ‘operator””t’
Este relatório teria mais informações com
“Mostrar a saida detalhada durante a compilação”
opção pode ser ativada em “Arquivo -> Preferências”
Anderson, o certo é for (int i = 2; i < 8; i++) Tinha um bug na página que estava exibindo o código errado para os leitores. Já corrigi.
Para uma ponte-H que liga-desliga um relay, precisa de optoacoplador para proteger o Arduino contra surtos? Muito obrigado por compartilhar seus conhecimentos!
Eduardo, porque você controlaria um relé através de uma ponte H?
Boa tarde, Alan. Eu também achei estranho, mas meu professor disse que faz isso pois “a ponte-H L298N possui optoacoplador e com isso protege o Arduino da rede elétrica 127V”.
Apesar disso, não achei na internet informação de que essa ponte H (que é esse modelo) possui essa proteção.
Por isso perguntei se seria necessário o optoacoplador ou se a própria ponte-H já possui alguma proteção extra que o relay SSR não tem ou se precisa adicionar algo (um optoacoplador) para ter mais segurança. (Sou novo na área e não sei se isso realmente é necessário).
Meu único propósito é controlar a potência da lâmpada de forma tão suave e rápida quanto possível, se será com SSR, módulo Dimmer ou Triac+ZeroCross eu ainda estou pesquisando para ver qual mais viável economicamente e não desnecessariamente complicado.
Vlw!
Eu nunca vi essa aplicação da ponte H. O que eu faria para fazer esse controlador seria usar o Triac+ZeroCross. Gosto do tutorial do blog AutômatoBr: Controle PID de Potência em Corrente Alternada. Da um pesquisar da internet.
boa tarde, não estou entendendo a ilustraçao das suas ligações com suas definições na programação. De acordo com sua ilustração, o IN3 e IN4 estao nas portas 4 e 5 respectivamente, e na programaçao está me dizendo diferente
Olá Gabriel, conferi o esquema de ligação e estava faltando algumas conexões do Arduino UNO com o módulo ponte H L298n. Veja se agora você vai entender.
Boa noite Allan, estou terminando uma roda gigante 3d e coloquei um motor 5v 200RPM, preciso fazer um codigo que ao apertar o botao ela inicie lentamente e almente um pouco de uma 2 voltas e vai dimuindo lentamente ate parar.
Bom dia e obrigado pela resposta, Allan.
Andei pesquisando e parece ter informações conflitantes na internet.
Enquanto alguns sites indicam utilizar um módulo dimmer (que é composto por TRIAC B137 + 2 optoacopladores para proteger o Arduino das tensões elevadas + detector zero-cross), outros ensinam a usar TRIAC + optoac + ZeroCross como componentes separados, faz diferença?
Outros ainda falam de relay SSR, transistores MOSFET… Muita informação para uma mesma ideia e não encontro uma explicação diferenciando.
Pelo que entendi que é a mesma coisa que se refere o artigo AC Phase Control do playground.arduino.cc, o qual é análogo ao “PWM”, mas para AC em vez de DC, correto?
E minha principal dúvida: por que usar um TRIAC + ZeroCross em vez de um Relay SSR, ambos com o optoacoplador para proteção do Arduino? Na minha faculdade usam SSR + ponte-H (L298N) para acender uma lâmpada incandescente, não entendi porque não usar.
Ambos TRIAC e SSR operariam a 60Hz da rede elétrica por estarem associados ao detector ZeroCross, não?
Ambos permitem controlar a potência fazendo uma ideia análoga ao PWM através de controle de fase?
Não vejo qual a diferença entre eles pra poder escolher qual o mais adequado.
Vlw!
Eduardo, com certeza tem diversas forma de fazer isso. O que eu já fiz e tenho certeza que funciona é com detector de zero e triac. Quando fiz esse projeto me embasei nesse tutorial aqui: automatobr.blogspot.com.br/2013/05/controle-de-potencia-em-corrente.html
Ele é perfeito!
Bom dia, ótimo tutorial!
Quero enviar sinal PWM a equipamentos com maior potência (ex: lâmpada 40W, ventilador) e alimentação da tomada mesmo, 127V.
A potência máxima desse shield é 25W e operação 4-35V, certo? Não se aplica para isso, correto?
O que deveria buscar para essa utilidade?
Muito obrigado!
Eduardo, para controlar um equipamento com corrente alternada você vai precisar usar um circuito dimer e junto precisará de um circuito detector de zero. Isso é um assunto interessante, procure sobre controle de potência alternada com Arduino.
Em breve vamos fazer um tutorial sobre esse assunto também.
Alan, você acha que se ao invés do ci l298n, eu usar um l293b funcionaria da mesma maneira?
Acredito que sim Lucas, basta você colocar o pwm na porta Enable do CI L293B que é a pino 1 para o canal 1 e pino 9 para o canal 2. Se você puder falar se deu certo seria bacana para ajudar quem mais tiver essa dúvida.
Allan, acabei de finalizar e funcionou sim!! Muito bom seu artigo, me ajudou bastante!!
Que maravilhar!! =D
Ola Allan, para um projecto escolar estou pensando em desenvolver um painel solar que se movimenta com um motor, dependendo da informação fornecida pelas LDR, será possível controlar o motor com LDR e Arduino?
Obrigado
Olá Jorge, Sim você consegue. Você também vai precisar de uma ponte H como a desse tutorial. Procure na internet sobre o projeto do girassol com Arduino.
Para usar uma bomba (esguicho de agua de parabrisa) é o mesmo esquema? Obrigado!
Sim, Bombas costumam está acopladas a um motor elétrico. Você pode controla a velocidade de rotação do motor e dessa forma controlar a vazão.
É importante verificar se já não existe algum controlador embutido ao seu motor.
Deu mais ou menos certo, até que funcionou bem. Porém, percebi que a ponte H esquenta muito. Resolvi utilizar o MOSFET IRF540 (testei também o IRF3710) e ficou melhor. Acredito que seja pela amperagem, a ponte H L298N aguenta só 1A em cada canal, se não me engano.. e a bomba precisa de mais do que isso pra ter uma força mais interessante. Agradeço sua atenção!
Boa tarde Daniel:
Estou controlando um motor que movimenta um variador de tensão tipo toroide. Ele possui um fim de curso superior e outro inferior. Como faço para o arduino desligar no mínimo e permitir que gire no sentido contrario e vice-versa.
Obrigado,
Fernando M.
Cara, parabéns !!! Gostei muito da sua explanação ! Que haja mais pessoas como você no universo dos makers !
Abraços !
Meu Deus, que explicação maravilhosa!
To me matando para fazer isso. Ajudou demais.
Opa, que bom que gostou João!! =D Em breve vamos ensinar como fazer um robô móvel!
Gostaria de saber se é possível fazer este controle sem utilizar o Arduino uno, somente controlando a tensão com um potenciometro de fio ligado aos pinos de controle da velocidade na ponte H. É possível?
E se um motor vier a travar (uma colisão do carrinho por exemplo), como identificar através da variação de tensão do circuito?