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 ficafase = (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