%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% Analysis of a Woofer Motor %% %% %% %% David Meeker %% %% dmeeker@ieee.org %% %% %% %% 15 May2009 %% %% %% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Introduction % % The purpose of this script is to automate the analysis of a woofer motor. % The notebook produces the static performance curves that designers often % desire during the development of a new transducer: the actuator's "BL" % (the amount of force produced on the voice coil per amp of coil current); % the coil's self-inductance, and a plot of the magnetic field in which the % coil is immersed. % % Because there are so many possible variations in speaker motor geometry, % the notebook does not create the speaker geometry within the notebook. Rather, % it reads an existing geometry info FEMM and analyses it at a number of different % coil locations. It is assumed that the speaker motor has been drawn with all % elements in the coil belonging to group number 1, so that the voice coil can % be easily selected and moved by the notebook. It is also assumed that the .fem % file describing the motor is located in the same directory as the notebook % (although the user could manually change the path to the .fem file). %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% Design - Specific Parameters %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Model Name ModelName = 'Woofer.fem'; % Maximum excursion + /- from the centered position: Xlim = 5; % Movement increments used during the analysis dX = 1; % Define the range over which to plot the flux density : Xcenter = 17.15; % vertical location of the center of the airgap Xspan = 10; % field plotted between Xcenter-Xspan and Xcenter+Xspan %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% Analysis Routines %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Open an instance of FEMM openfemm; % Analyze BL and incremental inductance at 1 mm steps between - Xlim and + Xlim opendocument(ModelName); mi_saveas('temp.fem'); mi_selectgroup(1); mi_movetranslate(0, -Xlim); mi_clearselected; bl = []; inductance = []; disp('%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%') disp('% Speaker Motor Analysis Script'); disp('%'); disp('% David Meeker'); disp('% dmeeker@ieee.org'); disp('% 15May2009'); disp('%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%'); disp(''); disp(sprintf('Disp(mm)\t\tBL(N/A)\t\tInductance(uH)')); for k=-Xlim:dX:Xlim, mi_modifycircprop('icoil',1,1); mi_analyze(1); mi_loadsolution(); mo_groupselectblock(1); fz = mo_blockintegral(12); bl = [bl; [k, fz]]; R = mo_getcircuitproperties('icoil')*[0;1;0]; fl1 = mo_getcircuitproperties('icoil')*[0;0;1]; mo_close; mi_modifycircprop('icoil', 1, 0); mi_analyze(1); mi_loadsolution; fl0 = mo_getcircuitproperties('icoil')*[0;0;1]; L = (fl1 - fl0)*10^6; inductance = [inductance; [k, L]]; disp(sprintf('%g\t\t%g\t\t%g',k, fz, L)); mi_selectgroup(1); mi_movetranslate(0, 1); end mi_close; % Evaluate flux density in the gap at the position of the coil opendocument(ModelName) mi_saveas('temp.fem'); mi_modifycircprop('icoil', 1, 0); mi_analyze(1); mi_loadsolution; fluxdensity = []; x=-Xspan; for x=-Xspan:(Xspan/100):Xspan b=mo_getb(16,Xcenter+x); fluxdensity=[fluxdensity;[x,abs(b(1))]]; end closefemm; delete('temp.fem'); delete('temp.ans'); %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% Plot Analysis Results %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% figure(1); plot(bl(:,1),bl(:,2)); xlabel('Displacement, mm'); ylabel('BL, N/A'); title('BL vs. Displacement'); figure(2); plot(inductance(:,1),inductance(:,2)); xlabel('Displacement, mm'); ylabel('Inductnace, uH'); title('Coil DC Self Inductance vs. Displacement'); figure(3); plot(fluxdensity(:,1),fluxdensity(:,2)); xlabel('Vertical distance from center of gap, mm'); ylabel('Flux density, T'); title('Air Gap Radial Flux Density vs. Position'); % DC Coil Resistance in Ohms: disp(sprintf('\nDC Coil Resistance = %g',R)); % Compute the nominal range of operation of the speaker. It is assumed that the % operating range is the range in which BL is within 10% of the maximum value of BL BLMax = max(bl(:,2)); BLMin = 0.9*BLMax; for k=2:length(bl) if (bl(k,2)>=BLMin) break; end end Xmin = bl(k-1,1)+(bl(k,1)-bl(k-1,1))*(BLMin-bl(k-1,2))/(bl(k,2)-bl(k-1,2)); kk=k; for k=kk:length(bl) if (bl(k,2)<=BLMin) break; end end Xmax = bl(k-1,1)+(bl(k,1)-bl(k-1,1))*(BLMin-bl(k-1,2))/(bl(k,2)-bl(k-1,2)); disp(sprintf('Xmin = %g',Xmin)); disp(sprintf('Xmax = %g',Xmax));