Escolar Documentos
Profissional Documentos
Cultura Documentos
Como funciona:
Quando o motor BLDC gira, cada enrolamento (3 enrolamentos) gera BEMF oposto à tensão
principal. Os 3 sinais BEMF gerados estão 120° fora de fase, o que é o mesmo que os sinais do
sensor de efeito hall. A figura abaixo mostra a relação entre os sinais de efeito hall e os sinais
BEMF:
Conforme mostrado na figura acima, os sinais BEMF não são sincronizados com os sinais do sensor
de efeito hall (deslocamento de fase de 30°). Em cada sequência de energização, dois enrolamentos
são energizados (um ligado ao positivo e outro ao negativo) e o terceiro enrolamento é deixado
aberto (flutuante). O enrolamento flutuante é usado para detectar o cruzamento de zero, portanto, a
combinação de todos os 3 pontos de cruzamento de zero é usada para gerar a sequência de
energização. No total temos 6 eventos:
Passagem por zero Fase A: de alto para baixo e de baixo para alta
Passagem por zero Fase B: de alta para baixa e de baixa para alta
Passagem por zero Fase C: de alta para baixa e de baixa para alta
Hardware Necessário:
placa Arduino UNO
Motor CC sem escova (BLDC)
6 x mosfet tipo N 06N03LA (ou equivalente) – folha de dados
3 x IC de driver de porta IR2104S (IR2104) – folha de dados
6 resistores de 33k ohms
3 resistores de 10k ohms
6 x resistor de 100 ohms
3 x diodo IN4148
3 capacitores de 10uF
3 capacitores de 2,2uF
2 x botão
fonte 12V
Protoboard
Fios de jumper
As linhas SD dos três IR2104S são conectadas aos pinos 11, 10 e 9 respectivamente para fase A,
fase B e fase C. O Arduino UNO pode gerar sinais PWM naqueles pinos onde apenas os mosfets do
lado alto são PWMed.
Como mencionado acima, os pinos 9, 10 e 11 do Arduino podem gerar sinais PWM onde os pinos 9
e 10 estão relacionados com o módulo Timer1 (OC1A e OC1B) e o pino 11 está relacionado com o
módulo Timer2 (OC2A). Ambos os módulos Timer são configurados para gerar um sinal PWM
com uma frequência de cerca de 31KHz e uma resolução de 8 bits. Os ciclos de trabalho dos sinais
PWM são atualizados quando um botão é pressionado (acelerar ou desacelerar) escrevendo em seus
registradores (OCR1A, OCR1B e OCR2A).
O comparador analógico compara a entrada positiva AIN0 (pino 6 do Arduino) com a entrada
negativa que pode ser AIN1 (pino 7), ADC2 (pino A2) ou ADC3 (pino A3). Quando a tensão do
pino positivo é maior que a tensão do pino negativo, a saída do comparador analógico ACO é
definida, e quando a tensão do pino positivo é menor que a tensão do pino negativo, o ACO é limpo.
Neste projeto eu usei a interrupção do comparador analógico e usei sua interrupção na subida
(transição de baixo para alto) e interrupção na queda (transição de alto para baixo), isso faz com que
os eventos de cruzamento de zero interrompam o microcontrolador.
Para entender completamente o código, leia o datasheet do ATmega328!
Codigo abaixo:
/* Sensorless brushless DC (BLDC) motor control with Arduino UNO (Arduino DIY ESC).
* This is a free software with NO WARRANTY.
* https://simple-circuit.com/
*/
#define SPEED_UP A0
#define SPEED_DOWN A1
#define PWM_MAX_DUTY 255
#define PWM_MIN_DUTY 50
#define PWM_START_DUTY 100
void loop() {
SET_PWM_DUTY(PWM_START_DUTY); // Setup starting PWM with duty cycle =
PWM_START_DUTY
i = 5000;
// Motor start
while(i > 100) {
delayMicroseconds(i);
bldc_move();
bldc_step++;
bldc_step %= 6;
i = i - 20;
}
motor_speed = PWM_START_DUTY;
ACSR |= 0x08; // Enable analog comparator interrupt
while(1) {
while(!(digitalRead(SPEED_UP)) && motor_speed < PWM_MAX_DUTY){
motor_speed++;
SET_PWM_DUTY(motor_speed);
delay(100);
}
while(!(digitalRead(SPEED_DOWN)) && motor_speed > PWM_MIN_DUTY){
motor_speed--;
SET_PWM_DUTY(motor_speed);
delay(100);
}
}
}
void BEMF_A_RISING(){
ADCSRB = (0 << ACME); // Select AIN1 as comparator negative input
ACSR |= 0x03; // Set interrupt on rising edge
}
void BEMF_A_FALLING(){
ADCSRB = (0 << ACME); // Select AIN1 as comparator negative input
ACSR &= ~0x01; // Set interrupt on falling edge
}
void BEMF_B_RISING(){
ADCSRA = (0 << ADEN); // Disable the ADC module
ADCSRB = (1 << ACME);
ADMUX = 2; // Select analog channel 2 as comparator negative input
ACSR |= 0x03;
}
void BEMF_B_FALLING(){
ADCSRA = (0 << ADEN); // Disable the ADC module
ADCSRB = (1 << ACME);
ADMUX = 2; // Select analog channel 2 as comparator negative input
ACSR &= ~0x01;
}
void BEMF_C_RISING(){
ADCSRA = (0 << ADEN); // Disable the ADC module
ADCSRB = (1 << ACME);
ADMUX = 3; // Select analog channel 3 as comparator negative input
ACSR |= 0x03;
}
void BEMF_C_FALLING(){
ADCSRA = (0 << ADEN); // Disable the ADC module
ADCSRB = (1 << ACME);
ADMUX = 3; // Select analog channel 3 as comparator negative input
ACSR &= ~0x01;
}
void AH_BL(){
PORTB = 0x04;
PORTD &= ~0x18;
PORTD |= 0x20;
TCCR1A = 0; // Turn pin 11 (OC2A) PWM ON (pin 9 & pin 10 OFF)
TCCR2A = 0x81; //
}
void AH_CL(){
PORTB = 0x02;
PORTD &= ~0x18;
PORTD |= 0x20;
TCCR1A = 0; // Turn pin 11 (OC2A) PWM ON (pin 9 & pin 10 OFF)
TCCR2A = 0x81; //
}
void BH_CL(){
PORTB = 0x02;
PORTD &= ~0x28;
PORTD |= 0x10;
TCCR2A = 0; // Turn pin 10 (OC1B) PWM ON (pin 9 & pin 11 OFF)
TCCR1A = 0x21; //
}
void BH_AL(){
PORTB = 0x08;
PORTD &= ~0x28;
PORTD |= 0x10;
TCCR2A = 0; // Turn pin 10 (OC1B) PWM ON (pin 9 & pin 11 OFF)
TCCR1A = 0x21; //
}
void CH_AL(){
PORTB = 0x08;
PORTD &= ~0x30;
PORTD |= 0x08;
TCCR2A = 0; // Turn pin 9 (OC1A) PWM ON (pin 10 & pin 11 OFF)
TCCR1A = 0x81; //
}
void CH_BL(){
PORTB = 0x04;
PORTD &= ~0x30;
PORTD |= 0x08;
TCCR2A = 0; // Turn pin 9 (OC1A) PWM ON (pin 10 & pin 11 OFF)
TCCR1A = 0x81; //
}