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);
- }
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);
- }
Nenhum comentário:
Postar um comentário