O PWM é uma técnica muito utilizada para controle de velocidade de motores DC, mas ele traz alguns desafios:
Motores DC convencionais ficam ligados à fonte de energia "o tempo todo", ou quase... Para que o movimento continue, é necessário que a comutação seja alternada, o que faz com que pelo menos em período de tempo muito curto, o motor seja desligado.
Motores de pulso ou pulsados são motores que em parte do tempo trabalham ligados à fonte de energia e em outra parte, desligados. Esse período em que fica ligado é crítico para o consumo elétrico total. Se for ligado antes do ponto certo, vai consumir mais energia que o necessário. Se for desligado depois do ponto adequado, também. Esse "ponto certo" vai depender do design do motor. Nos testes que executei com alguns designs diferentes, esse tempo não precisa exceder 1/2 do ciclo total do pulso. Mais adiante isso vai ficar mais claro.
Quando encontramos esse ponto de pulso inicial, o motor consome menos energia e gira mais rápido. Esse pode ser chamado de ponto de ressonância.
Algumas características dos motores pulsados:
PWM significa Pulse Width Modulation, ou modulação por largura de pulso. É uma técnica usada para diferentes propósitos, mas o nosso interesse aqui é o controle de velocidade de motores DC.
O PWM basicamente pega um perído de tempo de um sinal (ciclo) e divide ele em períodos menores.
Ex.: dentro de 1 segundo de tempo temos 1000 milissegundos. Se quisermos que um sinal com esse período fique 50% do tempo ligado, basta aplicar um sinal PWM de 1KHz com 50% de ciclo de trabalho ou duty cycle.
1 Hertz (Hz) equivale à 1 ciclo por segundo.
A técnica proposta nesse artigo tem como base outra chamada bit banging. Essa técnica substitui pulsos gerados por hardware por pulsos gerados por software.
Esse circuito utiliza uma topologia push-pull e como controle de PWM é utilizado um microcontrolador AVR ATtiny85.
O circuito ainda conta com um sensor hall do tipo latch, sendo usado para detectar o ciclo de cada pólo magnético do rotor. Com esse tipo de sensor é possível chegar a um valor bem próximo de 50% de período para cada pólo. Como alternativa, podemos usar um sensor óptico com um disco de comutação apropriado.
O sensor hall deve ser posicionado exatamente onde se queira iniciar o pulso.
O código do programa de controle é bem simples. Optei por usar um formato que é compatível com qualquer microcontrolador AVR (Arduino Uno, Arduino Mini, Arduino Mega...).
O trecho abaixo mostra as configurações de pinos. Para utilizar um microcontrolador AVR compatível, basta alterar essa configuração:
/* Change pin values for Arduino */
#define PIN_PUSH 1
#define PIN_PULL 0
#define PIN_FREQUENCY A2
#define PIN_FEEDBACK 2
#define INTERRUPT_PORT 0
Mais adiante temos a configuração de parâmetros que depende das características do motor:
/* These values represent the delta frequency value for mapping. 200 = 0.2, 800 = 0.8 */
#define DELTA_MIN 200
#define DELTA_MAX 800 // don't use values greater than 1000
/* Change this value to match your motor poles number */
#define POLES 6
Os valores de delta são análogos ao duty cycle. Como mencionei acima, não é necessário um pulso ter mais do que 1/2 do tempo, ou seja ~50%. Esse valores podem variar conforme o design do motor. Na imagem 3, o máximo configurado no teste foi ~38%;
A função abaixo é executada a cada troca de borda da entrada do sensor hall, ou seja, quando passar de um pólo para outro:
void handleFeedbackInterrupt() {
// update current phase
setPhases();
// calculate new pulse width
unsigned long now = millis();
pulseWidthMillis = calcultePulseWidth(phaseStartMillis, now, frequencyDelta);
phaseStopMillis = phaseStartMillis;
phaseStartMillis = now;
// calculate new RPM
rpm = calculateRPM(pulseWidthMillis, POLES);
}
Ela atualiza valores de:
Por fim, temos o trecho que executa o delay calculado, simulando um período PWM. Quando o período termina, o sinal é desligado:
// Using frequency delta control
case STEP_FEEDBACK:
{
// Update feedback delta
frequencyDelta = calculateFrequencyDelta(PIN_FREQUENCY);
// Get timestamp
unsigned long now = millis();
// Performing delay
if (now <= phaseStartMillis + pulseWidthMillis) {
setOnOff(currentPhase, lastPhase, 1);
} else {
setOff(currentPhase);
}
break;
}
O programa pode ser simulado no Tinkercad.
Nessa simulação, o motor foi substituído por um gerador de frequência que fica alternando um sinal, como se fosse o rotor girando e gerando um sinal alto e baixo no sensor hall. Há também o controle do delta de frequência pelo potenciômetro.
Abaixo temos imagens do circuito em funcionamento.
O canal amarelo mostra o sinal PWM gerado pelo microcontrolador. O valor "-Duty" mostra a % do sinal que energiza a bobina.
O canal azul mostra o ângulo e a largura onde o pulso atua na bobina.
Nesta primeira imagem, o valor está no mínimo:
Na segunda, temos um valor intermediário:
E finalmente na terceira, em potência total:
Essa técnica apesar de muito simples, se mostrou uma opção interessante para controle de velocidade.
Embora a complexidade do programa seja pequena, só o fato de termos um microcontrolador é um ponto a mais de possível falha do sistema. Com esse recurso, porém, utilizamos somente um sensor.
Utilizando essa técnica é possível fazer com que a topologia de push-pull seja "self starting". No teste anterior dessa topologia, nem mesmo o uso de 2 sensores garantiu isso, pois a posição do rotor pode ficar em um ponto cego.
Exploraremos mais circuitos com microcontroladores em artigos futuros.
Em caso de dúvidas, sinta-se à vontade para me contatar.