0% found this document useful (0 votes)
24 views4 pages

BLDC Motor Control Mega2560

This document provides a code implementation for sensorless brushless DC motor control using an Arduino Mega 2560. It includes setup for PWM control, motor commutation functions, and speed adjustment through input pins. The code is structured to handle motor operation and speed changes with defined duty cycles for PWM signals.

Uploaded by

quocbaoak12345
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as TXT, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
24 views4 pages

BLDC Motor Control Mega2560

This document provides a code implementation for sensorless brushless DC motor control using an Arduino Mega 2560. It includes setup for PWM control, motor commutation functions, and speed adjustment through input pins. The code is structured to handle motor operation and speed changes with defined duty cycles for PWM signals.

Uploaded by

quocbaoak12345
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as TXT, PDF, TXT or read online on Scribd
You are on page 1/ 4

/* Sensorless brushless DC (BLDC) motor control with Arduino Mega 2560 (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

byte bldc_step = 0, motor_speed;


unsigned int i;

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

// Configure pins 9, 10, 11 as outputs for high-side transistors


DDRB |= (1 << PB5) | (1 << PB6) | (1 << PB7); // D9 (PB5), D10 (PB6), D11 (PB7)
PORTB &= ~((1 << PB5) | (1 << PB6) | (1 << PB7)); // Set D9, D10, D11 low
initially

// Timer1 module setting: set clock source to clkI/O / 1 (no prescaling)


TCCR1A = 0;
TCCR1B = 0x01;
// Timer2 module setting: set clock source to clkI/O / 1 (no prescaling)
TCCR2A = 0;
TCCR2B = 0x01;

// Analog comparator setting


ACSR = 0x10; // Disable and clear analog comparator interrupt
pinMode(SPEED_UP, INPUT_PULLUP);
pinMode(SPEED_DOWN, INPUT_PULLUP);
}

// Analog comparator ISR


ISR(ANALOG_COMP_vect) {
// BEMF debounce
for(i = 0; i < 10; i++) {
if(bldc_step & 1) {
if(!(ACSR & 0x20)) i -= 1;
} else {
if((ACSR & 0x20)) i -= 1;
}
}
bldc_move();
bldc_step++;
bldc_step %= 6;
}

void bldc_move() { // BLDC motor commutation function


switch(bldc_step) {
case 0:
AH_BL();
BEMF_C_RISING();
break;
case 1:
AH_CL();
BEMF_B_FALLING();
break;
case 2:
BH_CL();
BEMF_A_RISING();
break;
case 3:
BH_AL();
BEMF_C_FALLING();
break;
case 4:
CH_AL();
BEMF_B_RISING();
break;
case 5:
CH_BL();
BEMF_A_FALLING();
break;
}
}

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
}

void SET_PWM_DUTY(byte duty) {


if(duty < PWM_MIN_DUTY)
duty = PWM_MIN_DUTY;
if(duty > PWM_MAX_DUTY)
duty = PWM_MAX_DUTY;
OCR1A = duty; // Set pin 11 PWM duty cycle (Timer1)
OCR2A = duty; // Set pin 10 PWM duty cycle (Timer2)
OCR2B = duty; // Set pin 9 PWM duty cycle (Timer2)
}

You might also like