Ir ao conteúdo
  • Cadastre-se

Controle Motor Dc Com PIC (PWM) e Driver L298 (Ponte H)


Posts recomendados

Olá moçada tudo bem ?

Estou com alguns problemas aqui, estou desenvolvendo um projeto aqui na FACU para controlar um motor Dc com PIC e PWM, mas como não tenho muita experiência com eletrônica estou encontrando dificuldades. Minha dúvida é o seguinte : que variáveis terei que controlar no PIC (que sinais enviarei para o driver L298) para que o motor possa girar para os dois lados e tb parar .Em anexo tem um circuito simples de controle usando um PIC 18F452 e e o driver L298 , no circuito (que usa PWM ) ,três pinos são usados para o controle : RB0, RB1,RB2, mas não sei exatamnete o que esses três pinos estão enviando para o driver, tipo, qual pino envia o pwm? e os demais servem pra que? Sei que para controlar o motor, você tem que controlar o sentido da corrente, mas não estou conseguindo enxergar essas variáveis no PIC e como isso acontece, e qual a função de cada pino de controle do PIC. Isso deve ser até uma pergunta ***** , mas infelizmnte não estou conseguindo entender.

Desde já, agradeço a colaboração de todos, valeu galera !!!!

post-831556-13884959233039_thumb.gif

Link para o comentário
Compartilhar em outros sites

Bom, vamos lá:

O pino RB0 está indo no pino ENABLE do L298. Se você leu o datashhet do L298, vai lembrar que esse pino é responsável pela habilitação/desabilitação do chip. Se você colocar nível alto, 5V, o chip é ativado, nível baixo, 0V, o chip é desativado ou seja o motor para.

Os pinos RB1 e RB2 estão indo nos pinos INPUT 3 e INPUT 4. Mais uma vez, do datasheet, na página 6, na Figura 6:

K9e85.png

Interpretando a tabela acima:

Se você colocar nível alto no INPUT 3 e nível baixo no INPUT 4, o motor gira para um lado, se você colocar nível baixo no INPUT 3 e nivel alto no INPUT 4, o motor gira para o outro lado. Simples.

A unica coisa a ser feita no PIC é colcar as portas em nivel alto ou baixo.

Caso queira utilizar o PWM, você aplica PWM em um dos INPUTS e o outro você aterra. Depois você inverte e ele gira devagar ou rápido para o outro lado.

Qual compilador que você usa? Programa em C? Usa o proteus p simular?

Falou

Link para o comentário
Compartilhar em outros sites

Bom, vamos lá:

O pino RB0 está indo no pino ENABLE do L298. Se você leu o datashhet do L298, vai lembrar que esse pino é responsável pela habilitação/desabilitação do chip. Se você colocar nível alto, 5V, o chip é ativado, nível baixo, 0V, o chip é desativado ou seja o motor para.

Os pinos RB1 e RB2 estão indo nos pinos INPUT 3 e INPUT 4. Mais uma vez, do datasheet, na página 6, na Figura 6:

K9e85.png

Interpretando a tabela acima:

Se você colocar nível alto no INPUT 3 e nível baixo no INPUT 4, o motor gira para um lado, se você colocar nível baixo no INPUT 3 e nivel alto no INPUT 4, o motor gira para o outro lado. Simples.

A unica coisa a ser feita no PIC é colcar as portas em nivel alto ou baixo.

Caso queira utilizar o PWM, você aplica PWM em um dos INPUTS e o outro você aterra. Depois você inverte e ele gira devagar ou rápido para o outro lado.

Qual compilador que você usa? Programa em C? Usa o proteus p simular?

Falou

Ô Maheus beleza cara!!! você é o Matheus da engenharia Elétrica da UFSJ?

Eu sou o Aender, (lembra ? ) tb estudava Eng Elétrica aí, depois mudei para Computação na UFLA . Por ironia do destino, estou tendo que trabalhar com engenharia de novo rsrsr....

Bom, primeiramente muito obrigado pela ajuda, vejo que você está fera na engenharia rsrsr ...participa em vários tópicos aqui. Vamos lá ,para programar vou usar C , mais especificamente uma biblioteca do compilador mikroC que já tem as rotinas para PWM parcialmente prontas.Por último, vou simular no Proteus, e os controles serão feitos por botões Push-Button , tipo , um botão irá mover o motor em um sentido o outro botão para o outro sentido, isso é só para poder testar no Proteus, pois futuramente esse controle será feito via teclado do PC.Minha principal dúvida era sobre os sinai que eu deveria mandar para o L298 , partindo do PIC, tá complicado pois estou tendo que estudar tudo sozinho, aqui tem uma disciplina eletiva só de microcontroladores e sistemas embarcados , mas só vai sair semestre que vem .

Vamos ver se eu entendi então, vamos por partes rsrsr...

Bom, o enable deve estar sempre em nível alto então, caso eu queira alterar o sentido de rotação do motor (funcionaria como uma chave ) .Quanto ao PWM (que será o tipo de controle usado) você disse que seria necessário somente um IMPUT o outro eu poderia colocar no ground, e bastaria inverter , para mudar o sentido do motor; bastaria então, aplicar PWM no IMPUT 3 e colocar o IMPUT 4 no terra e para mudar o sentido ,colocar o IMPUT 3 no terra e aplicar PWM no IMPUT 4 ? Isso no proteus, seria então, três botões Push-Button que acionariam os sinai do PIC : Um para o enable e dois para o PWM (um para cada sentido do motor).É mais ou menos por aí ?

Muito obrigado cara, só com a postagem anterior já deu para clarear muito as idéias, abraço.

Link para o comentário
Compartilhar em outros sites

Fala garoto, claro q lembro de você.....

Bem, vamos lá:

Seguinte, sua lógica está correta sobre o funcionamento. Mas falta uns detalhes. você já estudou sobre o PWM? Um sinal de alta frequencia e que alteramos o ciclo de trabalho dele. Quanto mais alto for o ciclo de trabalho, mais potência entregamos ao motor.

Esse ciclo de trabalho é o tempo do PWM que fica ON dividido pelo período total.

Nesse caso, teremos que aumentar em mais 1 botão. Se você utilizar as interrupçoes do PIC fica fácil. Fica assim:

1 botão para incremento do ciclo do PWM e 1 botão para decremente do ciclo, sendo que o ciclo vai de 0 a 100%.

1 botão para troca de sentido do motor.

1 botão para o enable/disable...

SE você usasse o CCS eu poderia fazer um código de teste pra você. Não sei programar no MikroC.

Vou p faculdade agora e mais tarde monto o circuito de exemplo p você.

EDIT:

Fiz um exemplo. O código está simples e sem refinamento pois fiz ele rapidin aqui. Sei que é para outro compilador, mas serve para você ter uma ideia. Hospedei os arquivos para simulação. Só fazer o download lá em baixo:

Circuito:

XMj5S.jpg

Código:



#FUSES NOWDT //No Watch Dog Timer
#FUSES XT //Clock <=4Mhz
#FUSES PUT //Power Up Timer
#FUSES NOPROTECT //Code not protected from reading
#FUSES NOBROWNOUT //No brownout reset
#FUSES NOLVP //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O
#FUSES NOCPD //No EE protection

#use delay(clock=4000000)

#define botao_incremento PIN_D0
#define botao_decremento PIN_D1
#define botao_stop PIN_D2
#define botao_inverte PIN_D4

int8 ciclo_1, ciclo_2;
int1 modo=0, stop;

void main()
{
output_high(PIN_B0);
SETUP_CCP1(CCP_PWM);
SETUP_CCP2(CCP_PWM);
setup_timer_2(T2_DIV_BY_4,249,1);
set_pwm1_duty(0);
set_pwm2_duty(0);

while (TRUE)
{
if (stop == 1)
{
output_high (PIN_B0);
if (modo == 0)
{
if (input(botao_incremento))
{
ciclo_1 = ciclo_1 + 5;
do{}
while(input(botao_incremento));
}

if (input(botao_decremento))
{
ciclo_1 = ciclo_1 - 5;
do{}
while(input(botao_decremento));
}

set_pwm1_duty(ciclo_1);
set_pwm2_duty(0);
}

if (modo == 1)
{
if (input(botao_incremento))
{
ciclo_2 = ciclo_2 + 5;
do{}
while(input(botao_incremento));
}

if (input(botao_decremento))
{
ciclo_2 = ciclo_2 - 5;
do{}
while(input(botao_decremento));
}

set_pwm2_duty(ciclo_2);
set_pwm1_duty(0);
}

if (input(botao_inverte))
{
modo++;
do{}
while(input(botao_inverte));
}
}

if (stop == 0)
{
output_low (PIN_B0);
}

if (input(botao_stop))
{
stop++;
do{}
while(input(botao_stop));
}
}
}
#include <16F877A.h>

Link com os arquivos: http://www.4shared.com/file/sskt4SGf/PWM_L298.html

Falou

Link para o comentário
Compartilhar em outros sites

Fala garoto, claro q lembro de você.....

Bem, vamos lá:

Seguinte, sua lógica está correta sobre o funcionamento. Mas falta uns detalhes. você já estudou sobre o PWM? Um sinal de alta frequencia e que alteramos o ciclo de trabalho dele. Quanto mais alto for o ciclo de trabalho, mais potência entregamos ao motor.

Esse ciclo de trabalho é o tempo do PWM que fica ON dividido pelo período total.

Nesse caso, teremos que aumentar em mais 1 botão. Se você utilizar as interrupçoes do PIC fica fácil. Fica assim:

1 botão para incremento do ciclo do PWM e 1 botão para decremente do ciclo, sendo que o ciclo vai de 0 a 100%.

1 botão para troca de sentido do motor.

1 botão para o enable/disable...

SE você usasse o CCS eu poderia fazer um código de teste pra você. Não sei programar no MikroC.

Vou p faculdade agora e mais tarde monto o circuito de exemplo p você.

Falou

Cara, muito bom mesmo ,testei tudo e funcionou direitinho , inclusive no proteus 7.7 que o pessoal disse que estava dando erro ao simular PWM.

Vou adaptar o código para o mikroC ; ele tem as rotinas quase prontas : Pwm_Init , Pwm_Change_Duty ,Pwm_Start , Pwm_Stop , isso torna o código mais simples de entender e de implementar , depois posto aqui para servir de exemplo para a galera .

Bom, se não for pedir muito, e como você já está fera na engenharia, gostaria de aproveitar mais um pouco rsrsr, queria saber se é possível setar o Duty cycle para um determinado valor. Exemplo :

Esse circuito vai servir para controlar um dos motores de um braço robótico, (no total são 4 ) então como a velocidade vai ser baixa e o torque é que é o mais importante , eu poderia setar o duty cycle em um valor X ,para os dois sentido de cada motor;

mais especificamente, uma vez que o botão enable estivesse ativado , se eu quiser mudar o sentido de rotação do motor é só manter pressionado o botão especifico (não ia ter botão stop) , quando eu parar de pressionar o botão ,o motor para; da mesma forma, se eu quiser mudar para o outro sentido , basta pressionar o outro botão e soltar ,caso queira parar . Resumindo :

Botão Ativa enable > ativa o driver L298

Botão sentido horário > Ativa motor no sentido horário

Botão sentido Anti-horário > Ativa motor sentido anti-horário

Será que dá para fazer isso ? ou eu estou viajando . Não precisa esquentar a cabeça em programar pois eu vou quebrar a cabeça com o código aqui, era só para dizer +- se da para fazer , pois essa seria a lógica do controle do braço via teclado, só que eu teria que testar da mesma forma no proteus.

Matheus, muito obrigado , com o que você já me passou da para fazer bastante coisa , se não fosse isso estaria perdido, pois meu professor orientador é daqueles que só sabem falar " você está no Caminho certo " e mais nada kkk..

Valeu rapaz !!!

Link para o comentário
Compartilhar em outros sites

Opa, bom que tenha gostado do resultado.

Do jeito que você quer, funciona sim perfeitamente. Podemos utilizar apenas 2 botões:

você deve estipular um valor para o duty_cicle. Nesse exemplo que passo agora ele recebe 125 ou 50%.

Se apertar o botão de ENABLE, ele ativa o chip, o motor começa a girar para um lado na velocidade programada. Se apertar de novo, ele pára o chip.

O outro botão, inverte a rotação para o outro lado na velocidade desejada.

Dessa forma o código pode se tornar bem mais simples utilizando as interrupções.

Circuito:

UrB8c.png

Código:

#include <16F877A.h>

#FUSES NOWDT //No Watch Dog Timer
#FUSES XT //Clock <=4Mhz
#FUSES PUT //Power Up Timer
#FUSES NOPROTECT //Code not protected from reading
#FUSES NOBROWNOUT //No brownout reset
#FUSES NOLVP //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O
#FUSES NOCPD //No EE protection

#use delay(clock=4000000)

#define botao_stop PIN_D2
#define botao_inverte PIN_D4

int1 modo=0, stop;

void main()
{
output_high(PIN_B0);
SETUP_CCP1(CCP_PWM);
SETUP_CCP2(CCP_PWM);
setup_timer_2(T2_DIV_BY_4,249,1);
set_pwm1_duty(0);
set_pwm2_duty(0);

while (TRUE)
{
if (stop == 1)
{
output_high (PIN_B0);
if (modo == 0)
{
set_pwm1_duty(125);
set_pwm2_duty(0);
}

if (modo == 1)
{
set_pwm2_duty(125);
set_pwm1_duty(0);
}

if (input(botao_inverte))
{
modo++;
do{}
while(input(botao_inverte));
}
}

if (stop == 0)
{
output_low (PIN_B0);
}

if (input(botao_stop))
{
stop++;
do{}
while(input(botao_stop));
}
}
}

Arquivos: http://www.4shared.com/file/3ZszGjIp/PWM_L298_versao_2.html

Nao deixe de ler esse tópico: http://forum.clubedohardware.com.br/motor-pwm-pic/857314

Dúvidas? Pergunte!

Falou

Link para o comentário
Compartilhar em outros sites

Opa, bom que tenha gostado do resultado.

Do jeito que você quer, funciona sim perfeitamente. Podemos utilizar apenas 2 botões:

você deve estipular um valor para o duty_cicle. Nesse exemplo que passo agora ele recebe 125 ou 50%.

Se apertar o botão de ENABLE, ele ativa o chip, o motor começa a girar para um lado na velocidade programada. Se apertar de novo, ele pára o chip.

O outro botão, inverte a rotação para o outro lado na velocidade desejada.

Dessa forma o código pode se tornar bem mais simples utilizando as interrupções.

Circuito:

UrB8c.png

Arquivos: http://www.4shared.com/file/3ZszGjIp/PWM_L298_versao_2.html

Nao deixe de ler esse tópico: http://forum.clubedohardware.com.br/motor-pwm-pic/857314

Dúvidas? Pergunte!

Falou

Cara , mais uma vez, obrigado!!!

Esse código também funcionou beleza, agora vou adaptar para o mikroC e depois posto aqui, o resultado.

Valeu mesmo , abração !!!

Link para o comentário
Compartilhar em outros sites

Pelo que eu entendi, frenagem rápida seria com os 2 pinos em alta (ao ler me lembreu do comportamento do motor de passo, a energização fica brigando pra ver qual sentido de giro ganha e elas empatam. Os 2 em baixa é frenagem normal don't care, don't care.

É possível. Eu não analisei o CI em si, somente a tabela que dizia que se D=E (nao lembro as letras) teria frenagem rápida. Por isso conclui que em ambos os casos (alto e baixo), mas é bem coerente sua teoria.

Link para o comentário
Compartilhar em outros sites

É possível. Eu não analisei o CI em si, somente a tabela que dizia que se D=E (nao lembro as letras) teria frenagem rápida. Por isso conclui que em ambos os casos (alto e baixo), mas é bem coerente sua teoria.

Conferi agora e voce está certo. Eu li também só a tabela mas vi lá algo como V = H, e C = D frenagem rápida e logo abaixo C = X e D = X, don't care. Aí supuz que era se o nível for alto e ambos forem iguais. Mas na verdade não era V e sim Ven, ou enable. E aí obviamente se o enable não estiver ligado, pouco importa as outras entradas.

Link para o comentário
Compartilhar em outros sites

Marsil, os pinos de enable só servem para ativar/desativar o chip. Nivel alto/baixo nesse caso.

EDIT:

Estive olhando o bloco interno do chip:

NUOhI.png

Reparem nos pinos de Enable 1 e de IN 1 e In2.

Eles vão para uma porta lógica.

Estive pensando sobre a pergunta do colega e me parece que posso sim aplicar PWM ao ENABLE.

A diferença que notei é que se aplicarmos o pwm no enable, o motor não pára de imadiato quando o PWM está em nível baixo. Fica uma espécie de roda livre. Ao contrário de aplicarmos PWM em um dos IN. Digo, se aterrarmos o IN2 e aplicarmos PWM ao IN1. Uma hora os dois serão 0 pela natureza do sinal PWM. Isso funciona como freio.

o que vocês acham?

Falou

Link para o comentário
Compartilhar em outros sites

Eu testei os dois modos: PWM nas entradas (IN1 ou IN2) e a outra em GND e também o PWM no ENA e as entradas em 5V ou GND. As duas funcionam normalmente, a princípio sem perda no desempenho do motor (não medi a velocidade nem torque mas a olho nu não houve modificações). Então acho que as duas maneiras são válidas, só tem que ver se realmente não há modificações grandes, já que a meu ver quando usando o PWM nas entradas haveria momentos em que o L298 funcionaria como freio e então mudaria o desempenho do motor, o que não ocorreria usando o PWM no enable. Mas como já disse, testando não vi diferença nos dois modos.

  • Curtir 1
Link para o comentário
Compartilhar em outros sites

  • 3 anos depois...

opa tudo bem ?

então estava lendo esse topico, pois estou com um problema mais ou menos parecido com esse, tenho que fazer controle de um motor dc usando pwm do pic, tipo controlar velocidade e sentido do motor ligar e desligar. tenho que utilizar o pic 18f4520 e o compilador mikroc, achei esse topico porém não estou conseguindo desenvolver não tenho muita pratica com programação e acho que estou errando em alguma logica, primeiro estava tentando fazer o motor ligar e desligar e iinverter seu sentido para depois fazer a parte de velocidade, porém não estou conseguindo. se alguem puder dar um help ficarei grato.

unsigned char ciclo_1, ciclo_2;unsigned char sentido=0 , stop    ;void Config()  {  trisd = 255;                          // configura todos os ports do trisc como entrada  trisb = 0;                          // configura todos os ports do trisb como saida  trisc = 0;                          // configura todos os ports do trisc como saida  portd = 0;  portc = 0;  portb = 0;  PWM1_Init(5000);                    // Initialize PWM1 module at 5KHz  PWM1_Start();  PWM2_Init(5000);                    // Initialize PWM2 module at 5KHz  PWM2_Start();  }void main(){  Config();   {      if (stop == 1)      {         portb.f0 = 1;         if (sentido == 0)          {             PWM1_Set_Duty(125);             PWM2_Set_Duty(0);          };         if (sentido == 1)          {             PWM2_Set_Duty(125);             PWM1_Set_Duty(0);          };                   if (botao_inverte =1)         {            sentido ++ ;            do{}            while(botao_inverte =1);         }       }      if (stop == 0)      portb.f0 =0;      if (botao_stop =1)       {            stop++;            do{}            while(botao_stop =1);       }   }}

post-723594-0-19013600-1400204825_thumb.

Link para o comentário
Compartilhar em outros sites

Tem um erro nos dois últimos "IFs" e "WHILEs":
 
"if (botao_inverte =1)" isso é sempre verdadeiro, tem que ser:
"if (botao_inverte == 1)" note os dois sinais de igual
 
o mesmo pro while
"while(botao_inverte =1)"
tem que ser:
"while(botao_inverte == 1)"
 
e o mesmo para o if e para o while do botao_stop.
Mas ainda assim não vai funcionar porque "botao_inverte" e "botao_stop" não estão declarados e não estão ligados a nenhuma porta do micro.
Você tem que fazer algo do tipo:
"botao_inverte = portb.f0;"
e aí prosseguir com o código.

O ideal é junto com o "while( botao_qualquerumdosdois )" colocar um delay para fazer o "debouncing" do botão (esse termo é importante, dê uma procurada no google).

Link para o comentário
Compartilhar em outros sites

entendi obrigado @Marsil

arrumei os ifs e whiles, porém mesmo assim tem algo na logica que não esta funcionando pois ainda não consigo fazer que a variavel "sentido" mude de valor  com o apertar do push button, acho que estou usando o comando errado ou errando a ordem da logica.

 

#define botao_incremento Portd.f0#define botao_decremento Portd.f1#define botao_stop       Portd.f2#define botao_inverte    Portd.f4unsigned char ciclo_1, ciclo_2;unsigned char sentido , stop    ;void Config()  {  sentido =0;  trisd = 255;                          // configura todos os ports do trisc como entrada  trisb = 0;                          // configura todos os ports do trisb como saida  trisc = 0;                          // configura todos os ports do trisc como saida  portd = 0;  portc = 0;  portb = 0;  PWM1_Init(5000);                    // Initialize PWM1 module at 5KHz  PWM2_Init(5000);                    // Initialize PWM2 module at 5KHz  }void main(){  Config();  PWM1_Start();  PWM2_Start();   {      if (stop == 1)       {         portb.f0 = 1;         if (sentido == 0)          {             PWM1_Set_Duty(125);             PWM2_Set_Duty(0);          };         if (sentido == 1)          {             PWM2_Set_Duty(125);             PWM1_Set_Duty(0);          };         if (botao_inverte ==1)         {            sentido=0;            do{            sentido++;            portc=~portc;            }            while(botao_inverte ==1);            delay_ms(10);         }                                   // Endless loop                                    if (stop == 0)      portb.f0 =0;     }      if (botao_stop ==1)       {            stop++;            do{portb.f0=0;}            while(botao_stop ==1);       }   }}
Link para o comentário
Compartilhar em outros sites

  • 2 anos depois...

Amigos perdão por reabrir o tópico de vocês mas estou numa situação meio que embaraçosa e gostaria da ajuda de vocês se possível. Tenho uma esteira aqui que trabalha com motor de 5hp. Fato é que não tenho encontrado placas que me possam fazer utilizar novamente o equipamento por um preço razoável. Na verdade as placas que tenho achado vão no máximo a 4 hp isto já trabalhando no pico. Como a engenharia de quem fabrica não recomendou o seu uso no motor de 5 hp, alguem poderia ajudar para que eu possa criar uma fonte ajustável até 90 volts DC? A titulo de informação aviso que possuo em mãos alguns Igbts novos que mandei buscar mas que não pude usar. Agradeço toda a ajuda. Forte abraço a todos.

Link para o comentário
Compartilhar em outros sites

  • 10 meses depois...
Em 04/19/2011 às 09:39, aender disse:

Olá moçada tudo bem ?

Estou com alguns problemas aqui, estou desenvolvendo um projeto aqui na FACU para controlar um motor Dc com PIC e PWM, mas como não tenho muita experiência com eletrônica estou encontrando dificuldades. Minha dúvida é o seguinte : que variáveis terei que controlar no PIC (que sinais enviarei para o driver L298) para que o motor possa girar para os dois lados e tb parar .Em anexo tem um circuito simples de controle usando um PIC 18F452 e e o driver L298 , no circuito (que usa PWM ) ,três pinos são usados para o controle : RB0, RB1,RB2, mas não sei exatamnete o que esses três pinos estão enviando para o driver, tipo, qual pino envia o pwm? e os demais servem pra que? Sei que para controlar o motor, você tem que controlar o sentido da corrente, mas não estou conseguindo enxergar essas variáveis no PIC e como isso acontece, e qual a função de cada pino de controle do PIC. Isso deve ser até uma pergunta ***** , mas infelizmnte não estou conseguindo entender.

Desde já, agradeço a colaboração de todos, valeu galera !!!!

post-831556-13884959233039_thumb.gif

Você. Nem postou o resultaso final se você conseguiu, poste para os membros do Clube do Hardware vou

Link para o comentário
Compartilhar em outros sites

Em 14/07/2017 às 19:51, andre ivo vieira disse:

Você. Nem postou o resultaso final se você conseguiu, poste para os membros do Clube do Hardware vou

beleza amigo ?

O resultado final foi a montagem de um circuito que controla 4 motores via PWM, o circuito poderia ser usado para um braço robótico por exemplo.Criei o circuito no Proteus e ficou assim :

 

circuito_braço_robotico.jpg

O programa foi feito no compilador CCS pois o mikroC não possui biblioteca para manipulação do PIC que eu usei, 18F4331 .

O código fonte  foi esse :


#include<18F4331.h>
#fuses  NOWDT, NOPROTECT, NOBROWNOUT, PUT, NOLVP
#use delay(clock=80000000)

#define POWER_PWM_PERIOD 1999  // 1 KHz pwm freq with 8 MHz osc.


//=======Funções para gerar PWM nos Motores e Controlar o Sentido DOS ===============
//........................Motor1......................................
void Motor1_Sentido1 ()
{
   set_power_pwm0_duty((int16)((POWER_PWM_PERIOD *4) * .60));  //Valor do Dutycicle  60%   
   output_high (pin_c0);  //Coloca Pino c0 em nível lógico alto
   output_low  (pin_c1);  //Coloca Pino c1 em nível lógico baixo
}
void Motor1_Sentido2 ()
{
   set_power_pwm0_duty((int16)((POWER_PWM_PERIOD *4) * .60)); // 60%
   output_low  (pin_c0);  //Coloca Pino c0 em nível lógico baixo
   output_high (pin_c1);  //Coloca Pino c1 em nível lógico alto
}

//........................Motor2......................................
void Motor2_Sentido1 ()
{
   set_power_pwm2_duty((int16)((POWER_PWM_PERIOD *4) * .40)); // 40%
   output_high (pin_c2);  //Coloca Pino c2 em nível lógico alto
   output_low  (pin_c3);  //Coloca Pino c3 em nível lógico baixo
}
void Motor2_Sentido2 ()
{
   set_power_pwm2_duty((int16)((POWER_PWM_PERIOD *4) * .40)); // 40%
   output_low  (pin_c2);  //Coloca Pino c2 em nível lógico baixo
   output_high (pin_c3);  //Coloca Pino c3 em nível lógico alto
}

//........................Motor3......................................
void Motor3_Sentido1 ()
{
   set_power_pwm4_duty((int16)((POWER_PWM_PERIOD *4) * .40)); // 40%
   output_high (pin_d0);  //Coloca Pino d0 em nível lógico alto
   output_low  (pin_d1);  //Coloca Pino c1 em nível lógico baixo
}

void Motor3_Sentido2 ()
{
   set_power_pwm4_duty((int16)((POWER_PWM_PERIOD *4) * .40)); // 40%
   output_low  (pin_d0);  //Coloca Pino d0 em nível lógico alto
   output_high (pin_d1);  //Coloca Pino c1 em nível lógico baixo
}


//........................Motor4......................................
void Motor4_Sentido1 ()
{
   set_power_pwm6_duty((int16)((POWER_PWM_PERIOD *4) * .40)); // 40%
   output_high (pin_d2);  //Coloca Pino d2 em nível lógico alto
   output_low  (pin_d3);  //Coloca Pino d3 em nível lógico baixo
}

void Motor4_Sentido2 ()
{
   set_power_pwm6_duty((int16)((POWER_PWM_PERIOD *4) * .40)); // 40%
   output_low   (pin_d2);  //Coloca Pino d2 em nível lógico alto
   output_high  (pin_d3);  //Coloca Pino d3 em nível lógico baixo
}

void parar_motor()
{
   output_high  (pin_c0);
   output_high  (pin_c1);
}

//====================Fim das funcoes de controle dos motores===================

//======================Programa Principal======================================
void main()
{


// ConfigurA  4 Power PWM Canais ordinários.
setup_power_pwm_pins(PWM_ODD_ON, PWM_ODD_ON, PWM_ODD_ON, PWM_ODD_ON);

// Mode = Free Run
// Postscale = 1   (1-16) Timebase output postscaler
// TimeBase = 0   (0-65355) Initial value of PWM Timebase
// Period = 2000  (0-4095) Max value of PWM TimeBase
// Compare = 0     (Timebase value for special event trigger)
// Compare Postscale = 1 (Postscaler for Compare value)
// Dead Time

setup_power_pwm(PWM_FREE_RUN, 1, 0, POWER_PWM_PERIOD, 0, 1,0);
      
      //Executa uma Rotina Estabelecida: sequencia de movimento dos motores
      while (TRUE)
      {
              delay_ms(50); //Aguarda 300 Milisegundos
              Motor1_Sentido1();
              Motor2_Sentido1();
              Motor3_Sentido1();
              Motor4_sentido1();
              delay_ms(100); //Motor gira nesse sentido por 100 Milisegundos
              parar_motor(); //Parar o motor por 500 Milisegundos
              delay_ms(200);
              Motor1_Sentido2();
              delay_ms(500);
      }      

} //Fim do Programa Principal

 

 

  • Curtir 1
Link para o comentário
Compartilhar em outros sites

Em 17/07/2017 às 09:39, aender disse:

beleza amigo ?

O resultado final foi a montagem de um circuito que controla 4 motores via PWM, o circuito poderia ser usado para um braço robótico por exemplo.Criei o circuito no Proteus e ficou assim :

 

circuito_braço_robotico.jpg

O programa foi feito no compilador CCS pois o mikroC não possui biblioteca para manipulação do PIC que eu usei, 18F4331 .

O código fonte  foi esse :


#include<18F4331.h>
#fuses  NOWDT, NOPROTECT, NOBROWNOUT, PUT, NOLVP
#use delay(clock=80000000)

#define POWER_PWM_PERIOD 1999  // 1 KHz pwm freq with 8 MHz osc.


//=======Funções para gerar PWM nos Motores e Controlar o Sentido DOS ===============
//........................Motor1......................................
void Motor1_Sentido1 ()
{
   set_power_pwm0_duty((int16)((POWER_PWM_PERIOD *4) * .60));  //Valor do Dutycicle  60%   
   output_high (pin_c0);  //Coloca Pino c0 em nível lógico alto
   output_low  (pin_c1);  //Coloca Pino c1 em nível lógico baixo
}
void Motor1_Sentido2 ()
{
   set_power_pwm0_duty((int16)((POWER_PWM_PERIOD *4) * .60)); // 60%
   output_low  (pin_c0);  //Coloca Pino c0 em nível lógico baixo
   output_high (pin_c1);  //Coloca Pino c1 em nível lógico alto
}

//........................Motor2......................................
void Motor2_Sentido1 ()
{
   set_power_pwm2_duty((int16)((POWER_PWM_PERIOD *4) * .40)); // 40%
   output_high (pin_c2);  //Coloca Pino c2 em nível lógico alto
   output_low  (pin_c3);  //Coloca Pino c3 em nível lógico baixo
}
void Motor2_Sentido2 ()
{
   set_power_pwm2_duty((int16)((POWER_PWM_PERIOD *4) * .40)); // 40%
   output_low  (pin_c2);  //Coloca Pino c2 em nível lógico baixo
   output_high (pin_c3);  //Coloca Pino c3 em nível lógico alto
}

//........................Motor3......................................
void Motor3_Sentido1 ()
{
   set_power_pwm4_duty((int16)((POWER_PWM_PERIOD *4) * .40)); // 40%
   output_high (pin_d0);  //Coloca Pino d0 em nível lógico alto
   output_low  (pin_d1);  //Coloca Pino c1 em nível lógico baixo
}

void Motor3_Sentido2 ()
{
   set_power_pwm4_duty((int16)((POWER_PWM_PERIOD *4) * .40)); // 40%
   output_low  (pin_d0);  //Coloca Pino d0 em nível lógico alto
   output_high (pin_d1);  //Coloca Pino c1 em nível lógico baixo
}


//........................Motor4......................................
void Motor4_Sentido1 ()
{
   set_power_pwm6_duty((int16)((POWER_PWM_PERIOD *4) * .40)); // 40%
   output_high (pin_d2);  //Coloca Pino d2 em nível lógico alto
   output_low  (pin_d3);  //Coloca Pino d3 em nível lógico baixo
}

void Motor4_Sentido2 ()
{
   set_power_pwm6_duty((int16)((POWER_PWM_PERIOD *4) * .40)); // 40%
   output_low   (pin_d2);  //Coloca Pino d2 em nível lógico alto
   output_high  (pin_d3);  //Coloca Pino d3 em nível lógico baixo
}

void parar_motor()
{
   output_high  (pin_c0);
   output_high  (pin_c1);
}

//====================Fim das funcoes de controle dos motores===================

//======================Programa Principal======================================
void main()
{


// ConfigurA  4 Power PWM Canais ordinários.
setup_power_pwm_pins(PWM_ODD_ON, PWM_ODD_ON, PWM_ODD_ON, PWM_ODD_ON);

// Mode = Free Run
// Postscale = 1   (1-16) Timebase output postscaler
// TimeBase = 0   (0-65355) Initial value of PWM Timebase
// Period = 2000  (0-4095) Max value of PWM TimeBase
// Compare = 0     (Timebase value for special event trigger)
// Compare Postscale = 1 (Postscaler for Compare value)
// Dead Time

setup_power_pwm(PWM_FREE_RUN, 1, 0, POWER_PWM_PERIOD, 0, 1,0);
      
      //Executa uma Rotina Estabelecida: sequencia de movimento dos motores
      while (TRUE)
      {
              delay_ms(50); //Aguarda 300 Milisegundos
              Motor1_Sentido1();
              Motor2_Sentido1();
              Motor3_Sentido1();
              Motor4_sentido1();
              delay_ms(100); //Motor gira nesse sentido por 100 Milisegundos
              parar_motor(); //Parar o motor por 500 Milisegundos
              delay_ms(200);
              Motor1_Sentido2();
              delay_ms(500);
      }      

} //Fim do Programa Principal

 

 

 

parabéns, ficou incrível o seu projeto 

Link para o comentário
Compartilhar em outros sites

Em 22/07/2017 às 10:50, andre ivo vieira disse:

 

parabéns, ficou incrível o seu projeto 

Obrigado brother, deu um pouco de trabalho mas ficou super massa. Simulei o projeto no Proteus e funcionou perfeito, falta agora só fazer o circuito , mas como na simulação foi ok, não vou ter grandes problemas.

 

Gostaria de aproveitar o comentário e agradecer a todos os  amigos que postaram nesse tópico, cada um ajudando com algum tipo de informação.

Valeu galera do Clube do Hardware, show de bola.

Link para o comentário
Compartilhar em outros sites

  • 4 semanas depois...

olá, boa tarde, não sei se aqui é o local correto para fazer esta pergunta, mas vamos lá, estou querendo fazer o controle de dois motoras dc, para que eles sirvam de locomoção para um robô, ate ai tudo bem fazer isso com um arduino e uma placa l298n é fácil, porém preciso fazer isso com um radio controle de 6 canais, minha duvida é como fazer a ligação do receptor com a ponte h para que eu possa mover o robô para frente e para traz com o controle, já que no controle eu uso canais diferentes para isso, me ajudem por favor

Link para o comentário
Compartilhar em outros sites

Visitante
Este tópico está impedido de receber novas respostas.

Sobre o Clube do Hardware

No ar desde 1996, o Clube do Hardware é uma das maiores, mais antigas e mais respeitadas comunidades sobre tecnologia do Brasil. Leia mais

Direitos autorais

Não permitimos a cópia ou reprodução do conteúdo do nosso site, fórum, newsletters e redes sociais, mesmo citando-se a fonte. Leia mais

×
×
  • Criar novo...