Spanish Italian
17454 Users    

Brushless DC electric motor control by CPLD

  Download PDF version of the Article

The main area for application of brushless direct current motors (BLDC) is positioning. In this article I am going to describe a simple solution to operation with two phase sine/cosine BLDC.
The main idea is to generate sine and cosine by Pulse Weight Modulation (PWM) using configurable logic for example field programmable array (FPGA) or complex programmable logic device (CPLD).
The general structure of system shown in Pic. 1.

General_structure_blcd
Pic. 1.- General structure of system

To produce low cost prototyping solution was selected CPLD from Altera EPM3064A (EPM3128A).

Description of circuit diagram
Device has the following parts:

    - motor driver part;
    - signal and control part;
    - power supply for motor driver part;
    - galvanic isolated power supply for signal part;
    - signal isolator.

System was designed using classical H-bridges based on N-channel MOSFET transistors (IRF540N) with proper driver IR2110. The main idea was to generate sine wave modulated PWM signals on CPLD and transfer it via isolating integral circuits to drivers. There are two channels one sine other cosine. CPLD generates both signals using table method. Resulting waves are filtered partially of LC filter (see photo) and load windings of motor. The direction of running simply changes by multiplexing of sine and cosine PWM modulated signals in CPLD.

 

blcd

The system is simply controlled. It can be controlled manually and easily can be connected to any microcontroller. The carry signal is generated by generator IC MC74HC4060. More suitable frequency for drivers ICs is near 200 KHz, so was selected 4 MHz quartz resonator to provide 2500KHs carry signal.
Controls:

    - “On/Off” switch enables/disables outputs. When outputs disabled rotor of BLDC can be easily rotated and windings have floating potentials.
    - “Enable” switch enables run of motor or firmly stops it holding power on windings.
    - “Direct/Reverse” switch when closed “Reset” and ”Stop/Run” defines the direction of rotation.
    - “Speed” jumpers set the period of sine/cosine waves and divide speed of rotation of motor.

The system designed as is. It has very simple protection by R30 and R45 shunt resistors from over current. Moreover by connection ADC to them can be established current and rotation feedback signal.

blcd-circuit-diagram
Pic. 2 – Circuit diagram

In Download section - BLCD_CPLD.zip you'll find the schematic at a high resolution.

VHDL code description. VHDL code is provided in appendix A.
Configurable logic module has 5 inputs and 2 outputs and utilizes 25% of logic cells.
Inputs: 4 of them map switches state (except “On/Off” what directly connected to isolated repeater) and 1 takes input clock (PWMclk).

This clock internally divided and used to control multiplexors to select data from sine/cosine tables. Selected values from tables compared with PWM counting registers and finally form PWM signal with duty changed cycle. So carry signal is twice modulated – primary by PWM and secondary by table.

Forms of waves depend on entry in tables for MUXA and MUXB multiplexers. In current project used 12 point approximation of sine/cosine wave. The resulting form of signal can be controlled by oscilloscope probes at control points K1 and K2. On the Pic. 3 was shown waveform on motor windings. The modulated PWM carry frequency is filtered and have maximal amplitude near the virtual “zero” line. The number of points easily can be tuned to 8 point or even less to control stepper motors and to use more chipper CPLD. Current solution compiled for EPM3128A and fits EPM3064. With resolution of sine/cosine wave it can be ported even to EPM3032.

 

Waveform on motor windings
Pic. 3 - Waveform on motor windings 

Implementation
Project was implemented and tested with 50Watt BLDC of Russian produced. And provide stable work. Solution was tried to run 1 KWatts BLDC but time by time output transistors and drivers was crashed by high current at low speed turning of rotor (less them 10 rps.).
For implementation was selected prototype board with suitable number of drivers and h-bridges. In the photo was shown PCB for two axis control system. To reduce EMC disturbances motor supplied via simple low pass LC filter. It is optional system for low load up to 50 Watts. The cut of frequency of filer should be 100KHz or bellow.

Appendix A
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
entity PWM is	-- SIN & COS generator 	
(PWM 8 bit 8 samples per period)			
generic	( 
Nbit   	: natural := 3; -- PWM resolution      
Ncases 	: natural := 2; -- max=8 samplses 
PhaseShift	: natural := 2  -- Pi/2 phase shift  	
);   
Port ( SOut, COut	: out STD_LOGIC;  			-- PWM outputs
dir		: in  STD_LOGIC;			-- direction	
Speed	: in  STD_LOGIC_VECTOR (1 downto 0);	-- rotation Speed 
PWMclk   	: in  STD_LOGIC;			-- PMWclock 
--   Muxclk	: in  STD_LOGIC;			-- data selector clock	
--   test     : out STD_LOGIC_VECTOR (2 downto 0);	 -- PWM counter   
PWMen 	: in  STD_LOGIC			-- enable/stop PWM
);
signal divider : STD_LOGIC_VECTOR ( 12 downto 0);				-- PWM counter
signal PWMcnt	: STD_LOGIC_VECTOR ( Nbit downto 0);				-- PWM counter
--	signal MuxCnt	: STD_LOGIC_VECTOR ( Ncases downto 0);			-- selector counter 
signal MuxA	: STD_LOGIC_VECTOR ( 3 downto 0):="0000"; 			-- data pointers 
signal MuxB	: STD_LOGIC_VECTOR ( 3 downto 0):="0011"; 			-- data pointers 
signal CosOut, SinOut,q : STD_LOGIC;  					
signal DtSin,DtCos	: STD_LOGIC_VECTOR (Nbit downto 0);				-- PWM reg values
end PWM;
architecture BHVa of PWM is
begin
process  (PWMclk,PWMen)				-- PWM counter 
begin 
if (PWMen='0')
then  divider <= "0000000000000" ; --- disable/stop PWM 
else 
if	(PWMclk'Event and PWMclk='1')
then divider <= divider +'1';
end if;
end if;
end process;
with Speed select 		--
q  <= 	divider(9)  when "11",
divider(8)  when "10",  -- 
--divider(7)  when "011",  -- 
divider(7)  when others; -- 
process  (q) -- SIN & COS data pointers selection  
begin
if (PWMen='0')
then MuxA <= "0000"; MuxB <= "0011";
else
if	(q'event and q='1')
then MuxA <= MuxA + 1;	
MuxB <= MuxB + 1;	 
--test (2 downto 0) <=MUXA (2 downto 0);
end if;
if	(MuxA= "1010")
then MuxA <="0000";
end if;
if	(MuxB= "1010")
then MuxA <="0000";
end if;
end if;
end process;
with  MuxA select 		-- for SIN data 8-input data multiplexer 	
DtSin  (Nbit downto 0) <= 
x"8" when "0000", -- 	@000 
x"C" when "0001", -- 	@030
x"E" when "0010", -- 	@060
x"F" when "0011", -- 	@090 = Pi/2  = max                    	
x"D" when "0100", -- 	@120
x"B" when "0101", -- 	@150
x"8" when "0110", -- 	@180 = Pi                   
x"5" when "0111", --  @210
x"2" when "1000", --  	@240
x"1" when "1001", --  	@270 =3/2*Pi= min 	
x"2" when "1010", --  @300 
x"4" when "1011", -- 	@330 
x"8" when others; --  @360 
with  MuxB select 		-- for COS data 8-input data multiplexer 	--
DtCos  (Nbit downto 0) <= 
x"8" when "0000", -- 	@000 
x"C" when "0001", -- 	@030
x"E" when "0010", -- 	@060
x"F" when "0011", -- 	@090 = Pi/2  = max                    	
x"D" when "0100", -- 	@120
x"B" when "0101", -- 	@150
x"8" when "0110", -- 	@180 = Pi                   
x"5" when "0111", --    @210
x"2" when "1000", --  	@240
x"1" when "1001", --   	@270 =3/2*Pi= min 	
x"2" when "1010", --    @300 
x"4" when "1011", -- 	@330 
x"8" when others; --    @360 
process  (PWMclk,PWMen)		 -- PWM counter 
begin 
if (PWMen='0')
then  PWMcnt <= "0000" ; --- disable/stop PWM 
else 
if	(PWMclk'Event and PWMclk='1')
then PWMcnt <= PWMcnt +'1';
end if;
end if;
end process;
process  (dtsin,PWMcnt)				-- SIN PWM comparator output  
begin 
if (dtsin > PWMcnt )
then SinOut <= '0' ;
else SinOut <= '1';
end if;
end process;
process  (dtcos,PWMcnt)				-- COS PWM comparator output  
begin 
if (dtcos > PWMcnt )
then CosOut <= '0' ;
else CosOut <= '1' ;
end if;
end process;
with  dir select 		-- for COS data 8-input data multiplexer 	
Cout <= CosOut when '0', -- 128	@000=0 
Sinout when others; 
with  dir select 		-- for COS data 8-input data multiplexer 	
Sout <= SinOut when '0', -- 128	@000=0 
CosOut when others; 
end BHVa;

In Download section - BLCD_CPLD.zip you'll find the schematic and BOM.

This is very interesting and

This is very interesting and fun... I want to try it soon... :)
It would be interesting if you could give us out the values of resistors, capacitors, etc used in the circuit.
Is the code open source? did you write it your self?

For those who are not familiar with BLDC motors, it would be interesting to point that brushless DC motors (BLDC) are synchronous electric motors which are powered by DC current and hav an electronically controlled commutation system, instead of a mechanical commutation system based on brushes.

DIY BLDC

I was author of this DIY project aarticle.
If you have questions do not hesistate to ask me.
My Skype and e-mail is the same yamukha@ukr.net

DIY BLDC

Similar implementation
http://www.allegromicro.com/en/Products/Part_Numbers/3986/index.asp

Post new comment

The content of this field is kept private and will not be shown publicly.
  • Allowed HTML tags: <a> <em> <strong> <cite> <code> <ul> <ol> <li> <dl> <dt> <dd>
  • Lines and paragraphs break automatically.

More information about formatting options

CAPTCHA
This question is for testing whether you are a human visitor and to prevent automated spam submissions.
2 + 1 =
Solve this simple math problem and enter the result. E.g. for 1+3, enter 4.

Who's new

  • fernand
  • Ligrock
  • paolo_0665
  • chanuei
  • JM
  • samsilva77
  • araghube
  • stoll
  • mt
  • orionkw

Who's online

There are currently 0 users and 49 guests online.