banner

Motor inteligente



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.








FAÇA O DOWNLOAD DOS ARQUIVOS

PDF

INO

OUTROS








Nenhum comentário:

Tecnologia do Blogger.