Um motor híbrido que considero
“inteligente”. É do Step Servo que vou falar hoje. Ele é um motor de passo com
encoder. Vou, então, te apresentar uma opção para motorização de equipamentos.
Vamos, ainda, discutir a ideia de posicionamento em malha fechada e ilustrar
através de uma montagem de exemplo a correção de posição efetuada pelo Step
Servo.
O que é o Step Servo?
O Step Servo ou “Easy Servo” é
a junção de conceitos extremamente uteis na grande maioria das aplicações de
motorização. Tudo isso em um único produto e com um custo mais baixo, se
comparado a servos de porte semelhante.
Os conceitos unidos no Step
Servo são:
A alta capacidade de controle
de deslocamento angular dos motores de passo.
A capacidade de um sistema em
malha fechada de minimizar um desvio. Comum nos servos.
Malha fechada no Step Servo
O diagrama de blocos de um
sistema com Step Servo é mostrado abaixo:
Conexões
As conexões utilizadas nos
Step Servos são as mesmas utilizadas na maioria dos drivers de motores de passo
comuns no mercado, com exceção da introdução das conexões do encoder:
Formas de conexão dos sinais de controle
Os sinais de controle podem
ser conectados basicamente de três formas diferentes, abrangendo assim as
aplicações mais comuns
Os kits que utilizamos
Para os exemplos, utilizamos
dois kits, formados por fonte de alimentação, Driver Hibrido e Step Servo:
O primeiro foi um driver
hibrido KTC-DR23EC, um Step Servo KTC-HT23-EC1000 e uma fonte de 48V e 7,3A.
O segundo foi um driver
hibrido KTC-DR34EC, um Step Servo KTC-KML093-EC1000 e uma fonte de 48V e 7,3A.
Realizando a montagem
Para os dois kits, as
indicações de montagem são muito claras e praticamente idênticas, o que confere
de fato o apelido de “Easy Driver”. Além disto, a documentação disponível
permite a realização da montagem com segurança e rapidez:
Para mais detalhes deixaremos
as folhas de dados para download ou acesse link:
Chaves de configuração (SW1 à SW6)
Os dois drivers possuem em sua
lateral um conjunto de chaves para configuração do comportamento do driver e de
como ele deve interpretar os sinais de entrada.
·
SW1: Determina se o sinal de entrada será
identificado na borda de subida ou de descida. Se ajustado para “off” borda de
subida, “on” para borda de descida.
·
SW2: Determina o sentido da rotação do motor ao
ligar o driver. “Off” para CCW (sentido anti-horário)e “on” para CW (sentido
horário).
·
As chaves SW3 à SW6, combinadas, determinam a
resolução que o driver aplicará ao motor
em micro passos por revolução, variando de 400 à 51200, de acordo com a tabela.
A saída de alarme
A saída de alarme muda de
estado quando o Driver detectar alguma irregularidade na execução do movimento
e pode ser utilizar para sinalizar ao Controlador que algo deu errado.
Além disto, podemos
identificar o motivo da falha através da contagem de acendimentos do LED
Vermelho Alarme disponível nos drivers. Segue o código de falhas.
Código fonte
Declarações Globais
const int ENA = 8; //Pino conectado ao ENA+ const int DIR = 9; //Pino conectado ao DIR+ const int PUL = 10; //Pino conectado ao PUL+ const int METADE_INTERVALO_MINIMO = 3; //Duração mínima do estado alto ou baixo do pulso boolean ena = false;//variável auxiliar para controle do ENA boolean dir = false;//variável auxiliar para controle do DIR boolean pul = false;//variável auxiliar para controle do PUL int intervalo = METADE_INTERVALO_MINIMO; //duração dos estados alto ou baixo de pulso String ComandoEntrada = ""; //variável para armazenar o comando enviado pela serial bool ComandoCompleto = false; //Variável que sinaliza que o comando foi completamente capturado pela serial
Setup
void setup() { pinMode(ENA, OUTPUT); //Pino ENA como saída pinMode(DIR, OUTPUT); //Pino DIR como saída pinMode(PUL, OUTPUT); //Pino PUL como saída digitalWrite(ENA, ena); //Define o estado inicial como LOW digitalWrite(DIR, dir); //Define o estado inicial como LOW digitalWrite(PUL, pul); //Define o estado inicial como LOW Serial.begin(115200); //define o baudrate para 115200 ComandoEntrada.reserve(200); //reserva um espaço de 200 bytes para ComandoEntrada }
Loop
void loop() { if (ComandoCompleto) { //Se o comando foi completamente capturado... interpretador(ComandoEntrada); //...envia o comando para o interpretador de comandos... ComandoEntrada = ""; // ...limpa a variável que recebe o comando .... ComandoCompleto = false; //reinicia a variável que sinaliza o comando completo } }
serialEvent()
void serialEvent() //Evento que é disparado ao receber dados pela serial { while (Serial.available()) //se há dados disponíveis... { char inChar = (char)Serial.read(); //...lê um caractere ... ComandoEntrada += inChar;//...concatena na variável Comando entrada... if (inChar == '\n')//...se um caractere de nova linha for recebido... { ComandoCompleto = true;//..sinaliza o recebimento completo } } }
interpretador()
void interpretador(String comando) //Interpretador de comandos { comando.toUpperCase(); //...converte o comando recebido para maísculas Serial.print("Recebido: " + comando);//Envia uma resposta que o comando foi recebido e qual if (comando.indexOf("ENA") > -1) // Avalia se o comando é "ENA" (habilita ou desabilita o driver) { ena = !ena; //inverte o estado da variável auxiliar "ena" digitalWrite(ENA, ena); //ajusta o Pino ENA para coincidir com o estado da variável auxiliar respectiva Serial.println("Executado: ENA=" + String(ena)); //Sinaliza que o comando ENA foi executado return; //retorna } if (comando.indexOf("DIR") > -1) //Avalia se o comando é "DIR" (inverte a direção do motor) { dir = !dir; //inverte o estado a variável auxiliar "dir" digitalWrite(DIR, dir); //ajusta o Pino DIR para coincidir com o estado da variável auxiliar respectiva Serial.println("Executado: DIR=" + String(dir)); //Sinaliza que o comando DIR foi executado return; } if (comando.indexOf("P") > -1)//Avalia se o comando é "P" (insere um número de pulsos) { comando.remove(0, 1); //Remove o "P" inicial do comando para que reste somente o número de pulsos long pulsos = comando.toInt(); //Converte o número de pulsos para inteiro long contador = 0; //cria uma variável para contagem de pulsos while (contador < pulsos) //avalia se a contagem atingiu o número de pulsos solicitados { digitalWrite(PUL, HIGH);// ajusta o pino PUL para alto delayMicroseconds(intervalo); //aguarda o intervalo entre mudanças digitalWrite(PUL, LOW);// ajusta o pino PUL para baixo delayMicroseconds(intervalo); //aguarda o intervalo entre mudanças contador++; //incrementa o contador } Serial.println("Executado: " + String(contador) + " passos."); //Sinaliza o fim dos pulsos return; //retorna } if (comando.indexOf("T") > -1) //verifica se o comando é "T" { comando.remove(0, 1); //Remove o "T" inicial do comando para que reste somente o intervalo intervalo = comando.toInt(); //converte o intervalo para inteiro if (intervalo < METADE_INTERVALO_MINIMO) { //verifica se o intervalo é menor que o mínimo.... intervalo = METADE_INTERVALO_MINIMO; //...se for menor, ajusta para o valor mínimo } Serial.println("Intervalo: " + String(intervalo) + "us");//sinaliza o novo valor do intevalo return;//retorna } else //se nenhum comando foi encontrado { Serial.println("Comando desconhecido."); //sinaliza um comando inválido } }
Visualizando os comandos no Terminal Serial
Utilizamos um Arduino UNO
neste exemplo porque a tensão mínima para acionar os pinos de sinais é de 3,5V.
Para usar um outro controlador com tensão de saída diferente, como um ESP cuja
tensão é de 3V3, devemos ajustar o valor do sinal.
2 Comentários
Excelente apresentação sobre motor inteligente com encoder, referenciado à Empresa Kalatec !!!
ResponderExcluirParabéns pela apresentação Fernando, eu já utilizo esses motores em algumas de minhas máquinas. Visualizações no Canal: "Arduino && máquinas",
Grande abraço !!!
Tenho uma dúvida referente a este hibrido, tenho motores de passo de 100kgf, posso usar o driver hibrido com encoder que ficará igual a este híbrido? pq o pessoal da kalatec fala que o motor tem mais velocidade e torque, agora gostaria de saber se isso e devido a ser malha fechada ou o motor tem alguma diferença ao motor de passo convencional.
ResponderExcluir