Sie sind auf Seite 1von 8

2/24/12 Brushless DC (BLDC) motor with Arduino Part 2.

Circuit and Software


1/8 elabz.com/bldc-motor-with-arduino-circuit-and-software/
Home
Resources
CNC Files
Robotics Resources
This Site
Contact
Copyright and DMCA
Privacy Policy
Terms of Service
Forums
SEARCH
Brushless DC (BLDC) motor with Arduino Part 2.
Circuit and Software
Blu-Ray Teardown HP CT10L BD-ROM / DVD Rewriter
Brushless DC (BLDC) motor with Arduino. Part 3 The Stroboscope Project
Brushless DC (BLDC) motor with Arduino Part 2. Circuit and Software
November 14th, 2011 | Author: admin
In this post I will describe the hardware and the software part of a project involving the use of BLDC (Brushless DC) motor salvaged
from a broken XBox 360. This is a second installment in the series of posts related to Arduino and brushless DC motors. Please see the
first part for a bit of info on the theory behind the commutation sequence. Once you understand the commutation sequence for the
particular design of the BLDC motor, the circuit design for the BLDC driver becomes pretty clear. It is not much different from a bipolar
stepper driver in that we need the be able to both source and sink current at all ends of the windings, except of course in this case there
are only three ends whereas the bipolar stepper has four. The circuit diagram below is a concept that should work with any
microprocessor (or a specialized driver IC) that is able to produce the correct commutation sequence:
2/24/12 Brushless DC (BLDC) motor with Arduino Part 2. Circuit and Software
2/8 elabz.com/bldc-motor-with-arduino-circuit-and-software/
Connecting a BLDC motor to SN754410NE
driver IC and a microcontroller
Please note that this is a simplified circuit that only makes use of three MCU outputs. With three driver inputs it is possible to create only
two levels at the ends of the windings: LOW and HIGH. Using three different levels LOW, HIGH and OPEN could have enabled us
to disable one of the windings on each of the steps, which results in more torque and also enables rotational speed feedback via
measuring voltage induced on the disabled winding by the permanent magnet of the rotor. However, this circuit was designed for a rather
simple application where speed feedback is not required the load is so light that the motor is guaranteed to complete the steps given to
it and the rate that the controller sets up. If your application requires accurate speed control and your motor does not have Hall-effect
sensors (many BLDC motors do), then this simplified circuit is not suitable for your application. The flip side of the three-level BLDC
driver circuit is that it requires six MCU outputs.
Another similarity of this circuit with bipolar stepper drivers is that its based on the same quad half-H bridge IC SN754410 by Texas
Instruments (SN754410 datasheet: SN754410 Quadruple Half-H Driver IC).
Here is the Arduino Sketch for driving the BLDC with discrete steps: Arduino sketch for BLDC motors discrete steps
If you watched through the first part of the video above, you can see that the CD is constantly slipping on the spindle if the motor is
driven in such a way that the driver IC is given each of the 36 steps that comprise one complete 360 revolution, it responds to each
step very quickly and half the time just sits there at the step while the CD disk ontop is having a hard time catching up. The friction
between the spindle and the CD is just not enough to firmly hold the CD to the spindle and rotate synchronously. In the actual CD/DVD
drive there is a small disk spring with several concentric petals that pushes on the CD toward the spindle and helps to prevent the slips.
In our case we dont have such a spring and so we have to devise other ways of gently rotate the spindle so the CD on top of it does not
slip.
All these problems with jerkiness (Wikipedia says: Jerkiness, sometimes called obing somewhat ironic given that this will be a
stroboscope when were done) of the spindle are caused by driving it from the binary output (either HIGH or LOW) of the MCU.
Three phase motors like these are ideally driven with alternating currents and voltages creating a sinusoidal waveform, 120 apart on
each of the three ends of the windings. This requires a lot of effort in a digital world a DAC chip (Digital-to-Analog Convertor) and
plenty of computations. But there is an easier way to emulate the effect of alternating current in the binary world of microcontrollers:
pulse width modulation or PWM.
PWM is a technique of producing bursts of current at a preset voltage in a rapid succession of cycles of equal length called PWM period
which is the inverse of the PWM frequenc. The duration of the burst in each cycle, called PWM dut ccle, is defined by the PWM
value from 0 to 255 (as implemented in Arduino) where 0 means no burst at all, at 127 the burst continues for 50% of the time of the
PWM period and 255 means that the output is on HIGH during the entire length of the PWM period.
The PWM is still a digital output it has only two states 0 and 1 AKA LOW and HIGH. However, if we apply this output to a load
that has inertia of any kind, such as persistence-of-vision if we control LEDs or moment of rotational inertia if we control electrical
motors, the end result of PWM control resembles the effect of controlling the voltage across the load dimming the LEDs and
controlling the RPMs of the motor.
2/24/12 Brushless DC (BLDC) motor with Arduino Part 2. Circuit and Software
3/8 elabz.com/bldc-motor-with-arduino-circuit-and-software/
Driving a three-phase motor using Arduino PWM outputs - Timing Diagram
Most Arduino boards have 6 PWM-enabled outputs and Arduino Mega has 14. In our case 3 is enough. The PWM values (PWM duty
cycle) are taken from the diagram above. Please disregard the LED flashes for now they are specific to the project this digram was
prepared for. Also, note that this is NOT a sine voltage waveform digram even though it would have been appropriate describing a three
phase motor. It would be difficult to create it with Arduino and therefore what you see is a PWM timing digram PWM duty cycle as a
function of rotational angle.
Since our motor is a 9-cog, 12 magnetic poles BLDC, each of the PWM cycles (a change from 0 to 255 and back) on the diagram
represent 1/6th of one full 360 rotation ( please see the first part for a better illustration of why). The number of steps in which we
divide the full PWM cycle is rather arbitrary but after some experimentation I settled on 48. I started off with 12 but it did not make the
rotation smooth enough. 24 PWM steps were already workable and 48 PWM steps were the most smooth. We could divide it even
more but it would be too much of a hassle because I wanted to treat these values as a constant array so as to avoid making the Arduino
go through some serious (for an MCU) math calculations to create it. I just calculated the 48 values I needed in the OpenOffice.org
Spreadsheet (here is the spreadsheed for the sine function : Sine function spreadsheet in OpenOffice.org Spreadsheet format )
Please see the PWM duty cycle array definition on the highlighted lines in the Arduino sketch below. The rest of the sketch should be
pretty much self-explanatory. The windings are marked as A,B and C and they are connected to Arduinos digital PWM outputs
numbers 9,10 and 11 respectively. The Arduino looks up the PWM parameter from the pwmSin array always keeping windings 1/3 of
the cycle apart. Once the cycle duration variable, set by the motorDela constant and additionally corrected by a potentiometer value
potState, expires, the program moves one step forward by incrementing all of the windings positions and resetting the one that reached
48 back to 0.
1
2
3
4
5
6
7
8
9
10
11
12
/*
Driving a DVD drive spindle three-phase motor

This code was used for the stroboscope project

This example code is in the public domain. Based on several Arduino code samples

http://elabz.com/

*/

// constants won't change. They're used here to
2/24/12 Brushless DC (BLDC) motor with Arduino Part 2. Circuit and Software
4/8 elabz.com/bldc-motor-with-arduino-circuit-and-software/
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
// set pin numbers:
const int buttonPin = 8;// the number of the direction pushbutton pin
const int ledPin = 7; // the number of the status LED pin (not the flash LED)
const int potPin = 0; // pot controls the RPM speed
const int potPinFlash = 1; // pot controls the flash speed
const int motorPin1 =9;
const int motorPin2 =10;
const int motorPin3 =11;
const int flashPin =12;
const int motorDelay=5; // together with pot controls the RPM
const int flashDelay=2; // controls duration of flash
const int frames=12; // has to be divisible by 3 in this version
const int serialDelay = 2000; //debug only
long serialLast =0; //debug only
// Variables will change:
boolean ledState = 1alse; // the current state of the status LED output pin
int buttonState; // the current reading from the direction input pin
int potState; // the current reading from the RPM speed potentiometer
int potStateFlash; // the current reading from the flash rate potentiometer
int lastButtonState = L0W;
int debounceDelay = 50; // the debounce time; increase if the output flickers
boolean direct = true; // direction true=forward, false=backward

/*
int pwmSin[] = {127,110,94,78,64,50,37,26,17,10,4,1,0,1,4,10,17,26,37,50,64,78,94,110,127,144,160,176,191,204,217,228,237,244,250,253,254,253,250,244,237,228,217,204,191,176,160,144,127
}; // array of PWM duty values for 8-bit timer - sine function
*/

int pwmSin[]={511,444,379,315,256,200,150,106,68,39,17,4,0,4,17,39,68,106,150,200,256,315,379,444,511,578,643,707,767,822,872,916,954,983,1005,1018,1022,1018,1005,983,954,916,872,822,767,707,643,578,511
}; // array of PWM duty values for 10-bit timer - sine function

int increment;
int flashIncrement = 0;
int currentFlash=0;
int currentStepA=0;
int currentStepB=16;
int currentStepC=32;
// the following variables are long's because the time, measured in miliseconds,
// will quickly become a bigger number than can be stored in an int.
long lastDebounceTime = 0; // the last time the output pin was toggled
long motorDelayActual = 0; // the actual delay, based on pot value and motor delay set above
long flashDelayActual = 0;
long flashDelayPerCycle = 0;
long lastMotorDelayTime = 0;
long flashTime = 0; // how long has flash been ON
long flashTimeOFF = 0; // how long has flash been OFF

void setup() {

TCCR1B = TCCR1B & 0b11111000 | 0x01; // set PWM frequency @ 31250 Hz for Pins 9 and 10
TCCR2B = TCCR2B & 0b11111000 | 0x01; // set PWM frequency @ 31250 Hz for Pins 11 and 3 (3 not used)
// ICR1 = 255 ; // 8 bit resolution
ICR1 = 1023 ; // 10 bit resolution

pinMode(buttonPin, 1N01);
pinMode(potPin, 1N01);
pinMode(potPinFlash, 1N01);
pinMode(ledPin, 00101);
pinMode(motorPin1, 00101);
pinMode(motorPin2, 00101);
pinMode(motorPin3, 00101);
pinMode(flashPin, 00101);
digitalWrite(flashPin, L0W);
}

void loop() {
// read the state of the switch into a local variable:
int reading = digitalkead(buttonPin);

// check to see if you just pressed the button
// (i.e. the input went from LOW to HIGH), and you've waited
2/24/12 Brushless DC (BLDC) motor with Arduino Part 2. Circuit and Software
5/8 elabz.com/bldc-motor-with-arduino-circuit-and-software/
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
// long enough since the last press to ignore any noise:

// If the switch changed, due to noise or pressing:
i1 (reading != lastButtonState) {
// reset the debouncing timer
lastDebounceTime = millis();
}

i1 ((millis() - lastDebounceTime) debounceDelay) {
// whatever the reading is at, it's been there for longer
// than the debounce delay, so take it as the actual current state:
buttonState = reading;
direct = !direct;
ledState = !ledState;
lastButtonState = reading;
}

// set the LED using the state of the button:
digitalWrite(ledPin, ledState);

// save the reading. Next time through the loop,
// it'll be the lastButtonState:

potStateFlash = analogkead(potPinFlash);
potState = analogkead(potPin);
motorDelayActual = potState * motorDelay / 100;
// flashDelayActual = flashDelay+potStateFlash/200; // if we were controlling it with a POT
flashDelayActual = flashDelay;
move();

}

void move()
{
i1((millis() - flashTime) flashDelayActual)
{
digitalWrite(flashPin, H16H);

}

i1((millis() - lastMotorDelayTime) motorDelayActual)
{ // delay time passed, move one step

i1 (direct==true)
{
increment = 1;
} else {
increment = -1;
}
currentStepA = currentStepA + increment;
i1(currentStepA 47) currentStepA = 0;
i1(currentStepA<0) currentStepA =47;

currentStepB = currentStepB + increment;
i1(currentStepB 47) currentStepB = 0;
i1(currentStepB<0) currentStepB =47;

currentStepC = currentStepC + increment;
i1(currentStepC 47) currentStepC = 0;
i1(currentStepC<0) currentStepC =47;

lastMotorDelayTime = millis();
//flashDelayPerCycle = flashDelayPerCycle + flashDelayPerCycle;
currentFlash = currentFlash + 1;
i1(currentFlash24)
{

digitalWrite(flashPin, L0W);
currentFlash=0;
flashTime = millis();
flashDelayActual = millis();
2/24/12 Brushless DC (BLDC) motor with Arduino Part 2. Circuit and Software
6/8 elabz.com/bldc-motor-with-arduino-circuit-and-software/
Here is the zip file with the Arduino sketch that you can download: Arduino Sketch for controlling 3-phase brushless DC (BLDC) motor
This is becoming a rather long post, so Ill save practical issues with implementation of the stroboscope project for another post. If you
have any question about controlling brushless DC motors in general, please post your question by starting a thread in our Motor Control
Forum.
Posted in Arduino, Motor Control | Tags: arduino, BLDC, brushless DC
3 Responses to Brushless DC (BLDC) motor with Arduino Part 2. Circuit and Software
DIY Stroboscope using a Three Phase DC Motor - Hacked Gadgets - DIY Tech Blog:
November 17, 2011 at 10:10 pm
[...] have seen some Stroboscopes in operation before, for this DIY Stroboscope that uses a Three Phase DC Motor which
eLabs put together I think the actual stroboscope is the simpler part of the build. Since the [...]
Reply
Candelo:
December 2, 2011 at 12:22 pm
Hi, How increase the speed, I try increase the frequency but doesnt work.
please help me.
thank you.
Reply
admin:
December 2, 2011 at 1:20 pm
It sort of depends on what RPMs you are looking for. Normally, you would adjust this line in the code
const int motorDela=5;
- the lower the delay the quicker the wave of changing PWM values goes around the circle and the quicker the motors
turns.
However, these motors cannot go from 0 to full speed in no time. You have to speed them up gradually it can be
relatively quick but it cannot be instant because the rotor is relatively large compared to the torque of the motor and if
you try to rev it up too quick, the inertia of the rotor will just make it skip the steps and it will mess everything up itll just
stop if the speed with which the windings are commutated is too fast.
if you lower the motorDelay constant and then start slow and gradually speed it up with the RPM potentiometer (talking
about the complete circuit here) , you should be able to make it spin really fast.
You can also adjust the Arduino sketch to insert a speeding-up sequence at the beginning. It will require some tweaking
though, youll have to find the rate of acceleration that works with your particular motor.
Thank you for stopping by!
Reply
155
156
157
158
159
160
161
162
163
164

}

}

analogWrite(motorPin1, pwmSin[currentStepA]);
analogWrite(motorPin2, pwmSin[currentStepB]);
analogWrite(motorPin3, pwmSin[currentStepC]);

}
2/24/12 Brushless DC (BLDC) motor with Arduino Part 2. Circuit and Software
7/8 elabz.com/bldc-motor-with-arduino-circuit-and-software/
Leave a Reply
Or use the Forums ! If your comment is a question, please consider posting it to a matching section of our Electronics
Forums. The forums allow for a more natural conversation flow, especially if multiple replies are required. Additionally,
you'll be able to style your writing (bold font, italics etc.) and post images which can help with a good answer.
Name (required)
Mail (will not be published) (required)
Website
Sbmi Commen
Notify me of followup comments via e-mail. You can also subscribe without commenting.
Latest Forum Topics
List of Seagate firmware terminal commands
Reciprocating Laser Cutter - real world feedback anyone?
Embedding YouTube videos in forum posts
Categories
Arduino (11)
CNC (6)
Displays (2)
Electronics Repairs (3)
Laser Cutting (10)
Lasers (5)
Motor Control (6)
Product Reviews (3)
Programming (3)
Robots (3)
Teardowns (3)
Uncategorized (5)
Blogroll
CNC and Metalworking Forum
Electronics Hobby Forum
Tools
Coming soon ...
Resources
Stepper Control Tutorials Free Web Tutorials from Galil, the Leader in Stepper Motor Control. www.GaliLmc.com
DC Motor Controllers Up to 2x150A. Advanced features USB, Serial, Analog or RC Interface www.roboteq.com
Torque & Press one System Extend, Retract, and Rotate Measure Torque, Force, & Position www.promessinc.com
2/24/12 Brushless DC (BLDC) motor with Arduino Part 2. Circuit and Software
8/8 elabz.com/bldc-motor-with-arduino-circuit-and-software/
CNC Files
Robotics Resources
Recent Comments
admin: Well, not me, at least not as yet. Ive pretty much replaced all lights with their CFL conterparts but...
Normand: If any of you would like to get rid of their sockets (the base), the lights and the elctric cords I would be...
admin: Im by no means an expert in Seagate firmware terminal commands but I did put together a short list of...
salim: to all experts please say few words about terminal command TX and T8, where/how to use these commands, PLEASE...
neil: Thank You Perfect
Related Posts
Upgrading a DVD spindle three phase BLDC motor
Brushless DC (BLDC) motor with Arduino. Part 3 The Stroboscope Project
Driving a three-phase brushless DC motor with Arduino Part 1. Theory
Blu-Ray Teardown HP CT10L BD-ROM / DVD Rewriter
Arduino Code Tidbits #1 Declaring an Array with Pin Values
Meta
Log in
Contact Us | Terms of Service | Privacy Policy
Copyright 2011 Elabz.com Electronics Blog. All Rights Reserved.

Das könnte Ihnen auch gefallen