BLDC Motor Control Mega2560
BLDC Motor Control Mega2560
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 setup() {
// Configure pins 3, 4, 5 as outputs for low-side transistors
DDRE |= (1 << PE3) | (1 << PE5); // D3 (PE5), D5 (PE3)
DDRG |= (1 << PG5); // D4 (PG5)
PORTE &= ~((1 << PE3) | (1 << PE5)); // Set D3, D5 low
PORTG &= ~(1 << PG5); // Set D4 low
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 = (1 << PB7); // D11 high
PORTE &= ~((1 << PE5) | (1 << PE3)); // D3, D5 low
PORTG |= (1 << PG5); // D4 high
TCCR1A = 0; // Turn off PWM on D11
TCCR2A = 0x21; // Turn on PWM on D10 (OC2A)
}
void AH_CL() {
PORTB = (1 << PB6); // D10 high
PORTE &= ~((1 << PE5) | (1 << PE3)); // D3, D5 low
PORTG |= (1 << PG5); // D4 high
TCCR1A = 0; // Turn off PWM on D11
TCCR2A = 0x21; // Turn on PWM on D10 (OC2A)
}
void BH_CL() {
PORTB = (1 << PB6); // D10 high
PORTE &= ~(1 << PE3); // D5 low
PORTG &= ~(1 << PG5); // D4 low
PORTE |= (1 << PE5); // D3 high
TCCR2A = 0; // Turn off PWM on D10
TCCR1A = 0x81; // Turn on PWM on D11 (OC1A)
}
void BH_AL() {
PORTB = (1 << PB5); // D9 high
PORTE &= ~(1 << PE3); // D5 low
PORTG &= ~(1 << PG5); // D4 low
PORTE |= (1 << PE5); // D3 high
TCCR2A = 0; // Turn off PWM on D10
TCCR1A = 0x81; // Turn on PWM on D11 (OC1A)
}
void CH_AL() {
PORTB = (1 << PB5); // D9 high
PORTE &= ~(1 << PE5); // D3 low
PORTG &= ~(1 << PG5); // D4 low
PORTE |= (1 << PE3); // D5 high
TCCR2A = 0x81; // Turn on PWM on D9 (OC2B)
TCCR1A = 0; // Turn off PWM on D11
}
void CH_BL() {
PORTB = (1 << PB7); // D11 high
PORTE &= ~(1 << PE5); // D3 low
PORTG &= ~(1 << PG5); // D4 low
PORTE |= (1 << PE3); // D5 high
TCCR2A = 0x81; // Turn on PWM on D9 (OC2B)
TCCR1A = 0; // Turn off PWM on D11
}