Full Step
Na operação Full Step, com um motor bipolar, acionamos sempre as duas bobinas do motor, de forma que uma esteja empurrando e a outra puxando. Isto resulta em maior torque e uma operação mais suave. A figura abaixo mostra a tensão aplicada nas bobinas.
Para implementar isto, utilizei um variável (que chamei de fase) que varia ciclicamente de 0 a 3. Para dar um passo basta posicionar as entradas das pontes H conforme o valor atual de fase:
void Passo () { switch (fase) { case 0: // + - digitalWrite (L293_INP1, HIGH); digitalWrite (L293_INP2, LOW); digitalWrite (L293_INP3, LOW); digitalWrite (L293_INP4, HIGH); break; case 1: // + + digitalWrite (L293_INP1, HIGH); digitalWrite (L293_INP2, LOW); digitalWrite (L293_INP3, HIGH); digitalWrite (L293_INP4, LOW); break; case 2: // - + digitalWrite (L293_INP1, LOW); digitalWrite (L293_INP2, HIGH); digitalWrite (L293_INP3, HIGH); digitalWrite (L293_INP4, LOW); break; case 3: // - - digitalWrite (L293_INP1, LOW); digitalWrite (L293_INP2, HIGH); digitalWrite (L293_INP3, LOW); digitalWrite (L293_INP4, HIGH); break; } delay (DELAY); }Para andar para frente ou para trás basta incrementar ou decrementar fase, em módulo 4. Para não precisar de divisão, pode ser usando um AND. O incremento fica
fase = (fase + 1) & 3;
O decremento poderia ser feito de outras formas, mas preferi aproveitar algumas propriedades da aritmética modular e usar
fase = (fase + 3) & 3;
Se quiser, experimente a fórmula com fase variando de 0 a 3 e confirme que o resultado varia, respectivamente, de 3 a 0.
Sensor de Fim de Curso
Minha tentativa inicial foi usar botões simples para detectar quando o carro chega nos extremos. Entretanto, o motor não teve força suficiente para acioná-los. Passei então a usar reed relays acionados por um imã:
Um lado dos sensores é ligado direto a terra e o outro a uma entrada digital. Acionando os resistores de "pullup" internos ao ATmega, o sinal será alto quando o sensor nâo estiver acionado (chave aberta). Quando o sensor é acionado o sinal passa a ser lido em nível baixo.
Calibração
Resolvi não deixar fixo no software qual sensor indica qual extremo e quantos passos existem entre eles. A rotina de calibração obtêm automaticamente estas informações.
void Calibra () { digitalWrite (L293_ENA1, HIGH); digitalWrite (L293_ENA2, HIGH); // Afasta dos sensores fase = 0; if (digitalRead(FC1) == LOW) { for (int i = 0; i < 20; i++) { fase = (fase+1) & 3; Passo (); } if (digitalRead(FC1) == LOW) { for (int i = 0; i < 20; i++) { fase = (fase+3) & 3; Passo (); } } } if (digitalRead(FC2) == LOW) { for (int i = 0; i < 20; i++) { fase = (fase+1) & 3; Passo (); } if (digitalRead(FC2) == LOW) { for (int i = 0; i < 20; i++) { fase = (fase+3) & 3; Passo (); } } } // Procura o mÃnimo for (int limite = 10000; limite > 0; limite--) { fase = (fase+3) & 3; Passo(); if (digitalRead(FC1) == LOW) { fcMin = FC1; fcMax = FC2; break; } if (digitalRead(FC2) == LOW) { fcMin = FC2; fcMax = FC1; break; } } // Procura o maximo posMax = 0; for (int limite = 10000; limite > 0; limite--) { posMax++; fase = (fase+1) & 3; Passo(); if (digitalRead(fcMax) == LOW) break; } posAtual = posMax; digitalWrite (L293_ENA1, LOW); digitalWrite (L293_ENA2, LOW); }O código completo pode ser baixado dos arquivos do blog (está no arquivo L293D_Passo3.zip). O vídeo abaixo mostra o teste em funcionamento:
Nenhum comentário:
Postar um comentário