Ir ao conteúdo
  • Cadastre-se

Controle Motor de Passo


Posts recomendados

Ola,

Estou com um projeto na faculdade de microcontroladores o qual eu tenho que controlar um motor de passo unipolar 200 passos atraves do microcontrolador AT89s52.

Preciso que o codigo do microcontrolador controle o motor sentido horario, anti-horario e velocidade. Comunicação via porta serial, alguem pode me ajudar !?

Desde já,

Obrigada

Link para o comentário
Compartilhar em outros sites

Karen,

Eu posso te ajudar nas informações de funcionamento do motor, chips que você vai utilizar, e como fazer o programa para cada o controle, eu fiz um programa em BASCOM que controla qualquer tipo de motor, seja unipolar, bipolar, 2 fases, 3 fases, etc.

Veja o que que você precisa , me informe qual a linguagem que você vai usar, ok ?

Paulo

Link para o comentário
Compartilhar em outros sites

Olha controlar a velocidade e sentido depente do tempo e a sequencia de acionamento das bobinas...

Montei um Fuso com uma velha maquina de xerox que usei um 16F676 por causa do AD ,usei uma rotina que toda hora era chamada pela main :

(no CCS)

#define C1     PIN_C1      // motor bobina 1
#define C2 PIN_C2 // motor bobina 2
#define C3 PIN_C3 // motor bobina 3
#define C4 PIN_C4 // motor bobina 4

void h_step_drive()
{


if(Passo<8)
Passo++;
else
Passo=1;

switch(Passo)
{
case 1 :
{
output_high(C1);
output_high(C2);
output_low(C3);
output_low(C4);
break;
}
case 2 :
{
output_low(C1);
output_high(C2);
output_low(C3);
output_low(C4);
break;
}
case 3 :
{
output_low(C1);
output_high(C2);
output_high(C3);
output_low(C4);
break;
}
case 4 :
{
output_low(C1);
output_low(C2);
output_high(C3);
output_low(C4);
break;
}
case 5 :
{
output_low(C1);
output_low(C2);
output_high(C3);
output_high(C4);
break;
}
case 6 :
{
output_low(C1);
output_low(C2);
output_low(C3);
output_high(C4);
break;
}
case 7 :
{
output_high(C1);
output_low(C2);
output_low(C3);
output_high(C4);
break;
}
case 8 :
{
output_high(C1);
output_low(C2);
output_low(C3);
output_low(C4);
break;
}

}
}


void main()
{

...
...
...
...

//LOOP:
for(;
{

delay_ms(4); // motor mais rápido
OU
delay_ms(35); //motor mais lento

h_step_drive();

}

}

Para mudar o sentido da rotação você inverte o sentido de acionamento das bobinas

C1 - C2 - C3 -C4 para C4 -C3 - C2 -C1

É algo bem mais simples... mais não terá muito dificuldade de colocar um rotina que faz a mudança de velocidade e sentido do motor via RS232

Também aconselho usar o TIMER0 para o motor e a main para a rs232

Espero te dado um luz

Outra coisa usei Tip41 para acionar o motor (no caso core de 6v)

Link para o comentário
Compartilhar em outros sites

  • 7 meses depois...

Ola Pessoal,

Eu sei que o tópico é muito antigo mas para não abrir outro e como tem a ver com o assunto, peço desculpas antecipadamente...

Vamos ver se consigo ajuda.

Estou tentando fazer um projeto de painel de instrumentos RPM para um carro antiguinho que tenho e nesse projeto vou usar um motor de passo com 4 fios como nos paineis modernos. Esse motor foi tirado de um painel moderno quebrado.

Gostaria de saber se alguem tem alguma coisa de esquema e programas em Linguagem "C" para PIC ? Vou usar o PIC 12F629.

Eu tenho já até um programinha e circuito que uma pessoa se propos a ajudar a começar a fazer, mas é para Motores de 6 fios e o motor que tenho é de 4.

Se por acaso alguem puder me ajudar.

Agradeço e muito.

Abraços

Formigoni

Link para o comentário
Compartilhar em outros sites

Esses motores bipolares que vem em clusters automotivos possuem uma resistencia de bobina elevadissima! da pra conectar diretamente aos pinos do microcontrolador (que por na tureza ja e uma ponte H) com isso cada lado da bobina vai em um I/O do PIC, ai basta acionar cada uma de forma sequencial, ou seja gerar os pulsos seguintes a cada 90 graus, para inverter o sentido basta inverter a sequencia de geração de pulsos.

Fiz testes de acionamento direto com micros da Freescale, e com PIC das referecias 16F877A e 18F452 e funcionou bem legal...com o 629 voce so conseguira acionar um motor ja que ele tem poucos I/O.

Duvidas estamos ai.

Abs

Link para o comentário
Compartilhar em outros sites

Esses motores bipolares que vem em clusters automotivos possuem uma resistencia de bobina elevadissima! da pra conectar diretamente aos pinos do microcontrolador (que por na tureza ja e uma ponte H) com isso cada lado da bobina vai em um I/O do PIC, ai basta acionar cada uma de forma sequencial, ou seja gerar os pulsos seguintes a cada 90 graus, para inverter o sentido basta inverter a sequencia de geração de pulsos.

Fiz testes de acionamento direto com micros da Freescale, e com PIC das referecias 16F877A e 18F452 e funcionou bem legal...com o 629 voce so conseguira acionar um motor ja que ele tem poucos I/O.

Duvidas estamos ai.

Abs

Ola Felipe,

você sabe me dizer se realmente não teria problema ligar direto nos pinos I/O do PIC sem possibilidade de queima de algum componente??

Outra dúvida ??

Como faço para identificar os polos desse tipo de motor para saber como fazer a sequencia ??

Tipo:

Passo 1 (pin_a0) - Polo ??

Passo 2 (pin_a1) - Polo ??

Passo 3 (pin_a4) - Polo ??

Passo 4 (pin_a5) - Polo ??

Segue abaixo o esquema que tinha para controlar motor de passo de 6 fios mas pra mim não dá pois vou usar motor de passo 4 fios.

Obrigado

Abraços

Formigoni

post-705917-13884965982367_thumb.jpg

Link para o comentário
Compartilhar em outros sites

Motores de 4 fios, bipolares são um pouco mais simples.

Veja, cada dois polos representam uma bobina, ou seja com um multimetro va medindo os pares usando a escala de resistencia (preferência a de 2K), o par de fios que der um valor de resistencia entre 80 e 200Ohms é uma bobina, separe os pares.

Assim, para cada par irao dois sinais A e B, em uma bobina irão A em um fio e /A em outro fio (dois sinais defasados em 180 graus) o mesmo ocorre no B para outra bobina e /B no outro fio da mesma bobina(180 graus) e a defasagem entre os sinais quadrados A e B deve ser de 90 graus...com pulsos de 10ms( para painel de instrumentos tive bons resultados com esse valor).

Quanto aos pinos do MCU, pode ligar sim, mas nao esqueça o capacitor de 100n em paralelo com cada bobina para proteger o micro. E veja se a resistencia da bobina esta entre 100 e 200 Ohms...e não teras problemas.

Boa sorte.

Duvidas, estamos ai

Link para o comentário
Compartilhar em outros sites

Motores de 4 fios, bipolares são um pouco mais simples.

Veja, cada dois polos representam uma bobina, ou seja com um multimetro va medindo os pares usando a escala de resistencia (preferência a de 2K), o par de fios que der um valor de resistencia entre 80 e 200Ohms é uma bobina, separe os pares.

Assim, para cada par irao dois sinais A e B, em uma bobina irão A em um fio e /A em outro fio (dois sinais defasados em 180 graus) o mesmo ocorre no B para outra bobina e /B no outro fio da mesma bobina(180 graus) e a defasagem entre os sinais quadrados A e B deve ser de 90 graus...com pulsos de 10ms( para painel de instrumentos tive bons resultados com esse valor).

Quanto aos pinos do MCU, pode ligar sim, mas nao esqueça o capacitor de 100n em paralelo com cada bobina para proteger o micro. E veja se a resistencia da bobina esta entre 100 e 200 Ohms...e não teras problemas.

Boa sorte.

Duvidas, estamos ai

Felipe,

Se não for abuso da minha parte... Sou bem cru nessa parte de PIC e programação em C.

Pelo jeito você já fez alguma coisa com relação a painel de instrumentos... você teria algum esquema e programa em "C" para me passar ou mostrar que de para eu usar em meu projeto ??

Muito obrigado,

Abraços

Formigoni

Link para o comentário
Compartilhar em outros sites

Formigoni, fiz algo sim, mas utilizando micros ARM, a base do código é a mesma, voce teria apenas que reescrever a parte dos registradores.

Ligue no PIC por exemplo Bobina1 A e /A em RB0 e RB1 e Bobina 2 B e /B em RB2 e RB3

Eu utilizo por base o seguinte algoritmo:



- Configurar a interrupcao do timer0 para 10ms;

- Escolher um port e usar um nibble, no caso escolherei de RB0 a RB3;

- RB0 a RB3 --> Saidas;

- Carregar em PORTB ou LATB(se for PIC18) inicial 0x01;

Aqui termina a inicialização. Agora proceda assim na interrupcao

- Limpe o flag de interrupcao


- Rotacione o valor de portb, para esquerda (ou direta dependendo do sentido de rotação)

- Veja se o mesmo chegou 0x08, se sim reinicie o PORTB escrevendo 0x01;

- Repita enquanto quiser girar o motor.


Abs.

Link para o comentário
Compartilhar em outros sites

Obrigado Felipe,

Vou testar anoite e amanha posto o resultado...

Achei estranho de ligar os polos do motor no I/O do Pic porque a pessoa que estava me ajudando anteriormente tinha me dito que para fazer a sequencia de passos de um motor de passo de 4 fios dependia de fazer 2 pontes H, por isso minha dúvida.

Eu simulei no Proteus com esse esquema que postei por ultimo e com o HEX que tinha aqui feito para motor de 6 fios e parece que funcionou, só não sei se na pratica vai ser assim e com amplitude de graus que preciso movimenta-lo 270º.

O programa será que pode ser o mesmo para movimentar um motor de 4 ou de 6 fios ??

Outra dúvida.. Esse capacitor que você falou para eu ligar em paralelo nas bobinas do motor, que tipo tem que ser ?? Poliéster, Eletrolítico, ... ??

Vamos tentando..

Obrigado,

Abraços

Formigoni

Link para o comentário
Compartilhar em outros sites

Formigoni, a pessoa está certa.

Porém a estrutura interna de um pino de I/O de um microcontrolador, ja possui internamente dois push-pull que se combinado em dois I/Os vira uma ponte H com nenhum HW externo, porém so consegue acionar cargas de ate 20mA (com o PIC) e como o motor de cluster drena em torno de 18mA da pra pendurar ele tranquilo no PIC.

Quanto ao programa eu acredito que sim pois a sequencia de acionamento vai a ser a mesma no fim das contas.

Boa sorte ai, e qualquer duvida va perguntando.

Abs

Link para o comentário
Compartilhar em outros sites

Ola Pessoal,

Felipe, fiz o teste ontem com o esquema que postei ontem...

Dando umas mexidas na montagem (matriz de contato) que fiz desse esquema ultimo que te passei e com o mesmo programa HEX que tinha aqui feito para motor de 6 fios e PIC12F629 coloquei para testar o motor de 4 fios e até que o motor girou mas lógico que sem nenhum parametro para ver se está certo...

Fiz um videozinho para você ver... Tenho aqui um protótipo com 555 para simular o sinal de RPM... Percebe-se que realmente quando mudo os potenciômetro do RPM devagar no stim o ponteiro se movimenta mas fica dando tranquinhos, provavelmente pelo motivo do software não ter o esquema do micro-passo e ficar sem precisão... acho eu...

Eu precisaria saber como fazer para quando iniciar o sistema ele ir para a posição inicial que necessito (ex: 0 RPM) , isso é feito no software não é ?? Pois toda vez que desligo e sistema e reinicio ele vai para o fim de curso do motor.

Teve uma outra pessoa que me indicou o PIC 12F1840 por ter 32Mhz, seria melhor para poder fazer o ponteiro ter mais precisão fazendo um micro-passo pelo software. Será que é isso mesmo ??

Segue o link do video.

Obrigado

Abraços

Formigoni

Link para o comentário
Compartilhar em outros sites

Formigoni, excelente trabalho.

Os trancos, são provenientes da falta do micropasso, da pra fazer por software.

Leia bem o primeiro algoritmo que te passei, ele simula de forma bem interessante um micropasso e nao da trancos no motor.

Mas o caminho é esse...existem métodos mais complexos para geração de micropassos...

Veja essa app note:

http://www.ti.com/general/docs/lit/getliterature.tsp?baseLiteratureNumber=slva416

Duvidas, va perguntando.

Abs.

Link para o comentário
Compartilhar em outros sites

Formigoni, excelente trabalho.

Os trancos, são provenientes da falta do micropasso, da pra fazer por software.

Leia bem o primeiro algoritmo que te passei, ele simula de forma bem interessante um micropasso e nao da trancos no motor.

Mas o caminho é esse...existem métodos mais complexos para geração de micropassos...

Veja essa app note:

http://www.ti.com/general/docs/lit/getliterature.tsp?baseLiteratureNumber=slva416

Duvidas, va perguntando.

Abs.

Felipe,

Obrigado...

Abaixo segue a programação que estou usando e usei para fazer a simulação, não entendi muito como incluir o algorítimo que você me falou...

Será que tens como me ajudar como fazer ??



#include "main.h"

/*
Motor de 4 cilindros...
Motor de passo para o ponteiro


*/

#define passo1 pin_a0
#define passo2 pin_a1
#define passo3 pin_a4
#define passo4 pin_a5


unsigned int16 ponto_desejado;
unsigned int16 ponto_atual;
unsigned int8 passo;


unsigned int8 pulse[4];
unsigned int8 old_pulse;
unsigned int8 counter_pulse;
unsigned int16 media;

unsigned int8 freq;
unsigned int8 rpm; //Rpm X100

short int calculado;



void motor (void){
if(passo == 8)
passo = 0;
else if(passo == 255)
passo = 7;
output_low(passo1);
output_low(passo2);
output_low(passo3);
output_low(passo4);

switch(passo){
case 0:
output_high(passo1);
break;
case 1:
output_high(passo1);
output_high(passo2);
break;
case 2:
output_high(passo2);
break;
case 3:
output_high(passo2);
output_high(passo3);
break;
case 4:
output_high(passo3);
break;
case 5:
output_high(passo3);
output_high(passo4);
break;
case 6:
output_high(passo4);
break;
case 7:
output_high(passo4);
output_high(passo1);
break;
}
}




aumenta_passo();





#int_RTCC
void RTCC_isr(void) //externo
{

}

#int_TIMER1 //131ms
void TIMER1_isr(void) //tempo de resposta 1/2 segundos
{
pulse[counter_pulse] = get_rtcc();
set_rtcc (0);

media = pulse[0] + pulse[1];
media = media + pulse[2];
media = media + pulse[3];
media = media + old_pulse; // valor antigo vale o triplo
media = media + old_pulse;
media = media + pulse[counter_pulse]; // valor atual vale o quadruplo
media = media + pulse[counter_pulse];
media = media + pulse[counter_pulse];
old_pulse = pulse[counter_pulse]; //grava o valor atual para valer o dobro depois

counter_pulse ++;
if(counter_pulse >= 4)
counter_pulse = 0;

//media é... 8 capturas sendo a ultima mais significativa...

calculado = true;


}



void main()
{

setup_timer_0(RTCC_EXT_L_TO_H|RTCC_DIV_1);
setup_timer_1(T1_INTERNAL|T1_DIV_BY_2);
setup_comparator(NC_NC);
setup_vref(FALSE);
enable_interrupts(INT_RTCC);
enable_interrupts(INT_TIMER1);
enable_interrupts(GLOBAL);

ponto_atual = 144;

// TODO: USER CODE!!
while(true){

if(calculado){
//printf("media %lu",media);
calculado = false;
//rpm = media /3.9;
//printf(" RPM ",rpm);
ponto_desejado = media / 1.23;
//printf("posicao %lu \n\r",ponto_ponteiro);
}

//unsigned int16 ponto_desejado;
//unsigned int16 ponto_atual;
//unsigned int8 passo;

//reduz posição
if(ponto_atual > ponto_desejado){
passo--;
motor();
ponto_atual --;
}
//aumenta posição
else if(ponto_atual < ponto_desejado){
passo++;
motor();
ponto_atual ++;
}
else{
output_low(passo1);
output_low(passo2);
output_low(passo3);
output_low(passo4);
}
delay_ms(5);


//painel de 0 a 9000RPM
// angulo de 260º

}
}

Obrigado,

Abraços

Formigoni

Link para o comentário
Compartilhar em outros sites

Vamos la, pensei em algo assim:





#define MAX_STEP 0x08 //constante interna para uso
#define MOTOR PORTD //por exemplo motor em RD0 a RD3

//declarei como global para facilitar as coisas
static unsigned char g_ucCurrStep = 0; //valor corrente do step

void interrupt(void) //sua rotina de interrupçao o melhor resultado e quando ela ocorre a cada 10ms
{


static unsigned char s_ucStep = 0x01; //variavel de step
unsigned char ucTemp = 0; //auxiliar

//limpa flag de interrupcao:
INTCON &= ~(1<<T0IF); //nao lembro os nomes dos bits é bom corrigir


//avanca o motor em 1 step:

ucTemp = MOTOR; //le o estado anterior do PORT

ucTemp &= 0xF0; //mascara os 4 bits nao usado

ucTemp |= s_ucStep; //coloca valor do passo atual em Temp

MOTOR = ucTemp; //passa o valor para o PORTD e aciona a bobina sem interferir nos pinos do PORTD que nao sao usados

//avanca step para proxima interrupcao:

s_ucStep <<= 1; //rotaciona o bit para a proxima bobina

if(s_ucStep > MAX_STEP) s_ucStep = 0x01; //checa se ja gerou pulso na ultima bobina, se sim volta para a primeira

g_ucCurrStep++; //avanca step corrente

TIMER0 = Recarga; //voce deve calcular para cada 1ms
}

//e aqui a rotina para avanço dos steps

void stepGo(unsigned char ucStepDesired)
{

//habilita interrupção do timer 0
INTCON |= (1<<T0IE);

while(ucStepDesired < ucCurrStep); //fica travado ate que o Step desejado seja no minimo igual ao corrente

//desliga interrupcao do timer 0
INTCON &= ~(1<<T0IE);
}


Esse codigo é so pra ida, falta fazer a parte da volta bem como criar os flags de direção e precisa modificar conforme o compilador apesar de ser compativel com o C18 e o MikroC pois sao ANSI...

Duvidas, pergunte.

Abs

Link para o comentário
Compartilhar em outros sites

  • 2 semanas depois...

Ola Felipe,

Deixa eu te perguntar uma coisa ...

você conseguiu uma boa precisão em intrumentos (RPM) com algum PIC de fácil acesso aqui no Brasil ?? Pois aquele PIC que a outra pessoa me indicou não tem aqui no Brasil e ai teria que importar um desses (fora o $$$). Estava querendo algum PIC que fosse fácil de se comprar mesmo que ele tenha que ter alguns pinos a mais...

Obrigado,

Abraços

Formigoni

Link para o comentário
Compartilhar em outros sites

  • 5 anos depois...
  • Membro VIP

Pesquise/estude/descubra quantos º ele dá por passo e faça uso de uma matemática simples pra saber quantos passos tem que dar. Só que isso soa óbvio d+ então vou um pouco além: você deve colocar uma referência algo como 0º ou posição zero ou "home" ou algo do gênero. Uma chave ótica ou reed switch te ajudam nisso.

E ainda mais além: você deve usar algo inteligente como algum microcontrolador mesmo que seja o famigerado arduíno.

Acho que a resposta foi longa d+ pro tamanho e qualidade da sua pergunta, mas a ideia foi somar...

Link para o comentário
Compartilhar em outros sites

21 horas atrás, Isadora Ferraz disse:

E ainda mais além: você deve usar algo inteligente como algum microcontrolador mesmo que seja o famigerado arduíno.

 

Uau, quanto descrédito para a maior plataforma de aprendizagem atualmente utilizada no mundo .......

 

Pense no lado bom : usando um simples Arduíno Uno ele vai encontrar dezenas ou centenas de exemplos de programa feitos para controlar um motor de passo.... deixe de ser puxa-saco dos Pics 😁 !!!

 

Paulo

 

 

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

  • mês depois...

Bom aproveitando o topico sobre motores de passo, sou iniciante com o arduino e estou tentando montar um programa em que eu consiga controlar uma roleta com um pulso de botão e sensor sendo que a roleta tem parafusos no seu exterior para sinalizar para que a roleta pare de girar e só continue a girar com o acionamento de um botão.

eu consegui realizar essa parte, agora quero eliminar o botão e fazer com que a roleta volte a girar com um sinal via serial, como por exemplo apertando a tecla G mas não tenho conhecimento de uma forma que faça funcionar

aqui o exemplo do meu programa que contem relês acionados via serial:

 

byte HOR[4] = {0x09,0x03,0x06,0x0C};   // Matriz dos bytes das Fases do Motor - sentido Horário Full Step

const int RelePin1 = 5; // pino ao qual o Módulo Relé está conectado
const int RelePin2 = 3; // pino ao qual o Módulo Relé está conectado
int incomingByte;      // variavel para ler dados recebidos pela serial
int atraso_fase = 2 ;   // Intervalo de tempo entre as fases em milisegundos - min 2 para Full Step 
int intervalo = 0 ;   // Intervalo de tempo entre os movimentos do motor em ms
const int pinoSinal = 7;
int pinobotao_h = 2; 
byte byteRead;

void Motor_HOR()   // Movimento no sentido horário 
{
  for(int i = 0; i < 1; i++)   // incrementa o contador i de 0 a 511 - uma volta
 
   for(int j = 0; j < 4; j++)   // incrementa o contador j de 0 a 3 
   {
   PORTB = HOR[j];   // Carrega bytes da Matriz HOR na Porta B 
   delay (atraso_fase);   // Atraso de tempo entre as fases em milisegundos
   }
}
 

void setup() 
{
  DDRB = 0x0F;   // Configura Portas D08,D09,D10 e D11 como saída 
  PORTB = 0x00;   // Reset dos bits da Porta B (D08 a D15)
  pinMode(pinoSinal, INPUT); 
  pinMode(pinobotao_h, INPUT); 
  Serial.begin(9600); // inicializa a comunicação serial em 9600bps
  pinMode(RelePin1, OUTPUT); // seta o pino como saída 
  pinMode(RelePin2, OUTPUT); // seta o pino como saída
  digitalWrite(RelePin1,HIGH);
  digitalWrite(RelePin2, HIGH);
}

void loop() {
  if ((digitalRead(pinobotao_h)) > 0 || (digitalRead(pinoSinal) > 0))
{
{
 Motor_HOR();   // Gira motor no sentido Horário 
 delay (intervalo);   // Atraso em milisegundos 
}
}
  if(Serial.available() > 0)
  {
    // verifica se tem algum dado na serial
    incomingByte = Serial.read();  //lê o primeiro dado do buffer da serial
   
  
    if (incomingByte == 'D') {     //se for A
      digitalWrite(RelePin1, HIGH); //aciona o pino
    } 

    if (incomingByte == 'A') {     //se for D
      digitalWrite(RelePin1, LOW);  //desativa o pino
    }
     if (incomingByte == 'F') {     //se for S
      digitalWrite(RelePin2, HIGH); //aciona o pino
    } 

    if (incomingByte == 'S') {     //se for F
      digitalWrite(RelePin2, LOW);  //desativa o pino
    }
     
}
}

Link para o comentário
Compartilhar em outros sites

Crie uma conta ou entre para comentar

Você precisa ser um usuário para fazer um comentário

Criar uma conta

Crie uma nova conta em nossa comunidade. É fácil!

Crie uma nova conta

Entrar

Já tem uma conta? Faça o login.

Entrar agora

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

Ebook grátis: Aprenda a ler resistores e capacitores!

EBOOK GRÁTIS!

CLIQUE AQUI E BAIXE AGORA MESMO!