function fm476(varargin) if nargin==1 % Switchyard for the calback for the analoginput % samples acquired function saf(varargin{1}) return end % initialize and reset daqreset clear all close all % Create Analoginput object gui.ai=analoginput('winsound'); addchannel(gui.ai,1); gui.ai.samplerate=22050; gui.ai.samplespertrigger=inf; % Update display every 1/10 seconds gui.ai.samplesacquiredfcn='fm476(1);'; gui.ai.samplesacquiredfcncount=gui.ai.samplerate/10; % Create Graphical User interface gui.fig=figure('tag','gfig','deletefcn','fm476(2)'); subplot(4,1,1) gui.p0=plot(NaN,NaN,'tag','gplot0'); subplot(4,2,3) gui.p1=plot(nan,nan,'tag','gplot1'); set(get(gui.p1,'parent'),'ylim',[-11 11],'xlim',[0,gui.ai.samplesacquiredfcncount]) subplot(4,2,5) gui.p2=plot(nan,nan,'tag','gplot2'); set(get(gui.p2,'parent'),'ylim',[-11 11],'xlim',[0,gui.ai.samplesacquiredfcncount]) subplot(4,2,7) gui.p3=plot(nan,nan,'tag','gplot3'); set(get(gui.p3,'parent'),'ylim',[-9 9],'xlim',[0,gui.ai.samplesacquiredfcncount]) % Generate filters for our three defined bands using butterworth high order % band pass filters. [gui.bx,gui.ax]=butter(6,[400/11025 3200/11025]); [gui.by,gui.ay]=butter(7,[3100/11025 5700/11025]); [gui.bz,gui.az]=butter(7,[5700/11025 8200/11025]); % Display the filters on the appropriate axes [hx wx]=freqz(gui.bx,gui.ax,100); [hy wy]=freqz(gui.by,gui.ay,100); [hz wz]=freqz(gui.bz,gui.az,100); subplot(4,2,4) gui.p4=plot(NaN,NaN,'tag','gplot4'); hold on plot(wx*gui.ai.samplerate/(pi*2),abs(hx)*500,'r') set(gca,'ylim',[0 1500],'xlim',[0 gui.ai.samplerate/2]) subplot(4,2,6) gui.p5=plot(NaN,NaN,'tag','gplot5'); hold on plot(wy*gui.ai.samplerate/(pi*2),abs(hy)*500,'r') set(gca,'ylim',[0 1500],'xlim',[0 gui.ai.samplerate/2]) subplot(4,2,8) gui.p6=plot(NaN,NaN,'tag','gplot6'); hold on plot(wz*gui.ai.samplerate/(pi*2),abs(hz)*500,'r') set(gca,'ylim',[0 1500],'xlim',[0 gui.ai.samplerate/2]) % Initialization for 3D orientation of the device [gui.b gui.a]=butter(5,30/11025,'low'); gui.gx=0; gui.gy=0; gui.gz=0; gui.predat=zeros(1000,1); set(get(gui.fig,'children'),'units','pixels') set(gui.fig,'position',get(gui.fig,'position').*[1 1 1 2]) % Create 3D axis for displaying the decoded orientation axes('position',[0.1 0.55 0.8 0.42]) gui.orient=plot3([0 0],[0 0],[0,-1],'-','linewidth',2); patch([-1 -1 1 1],[-1 1 1 -1],[-1 -1 -1 -1],'r') set(gca,'xtick',[],'ytick',[],'ztick',[]); box on set(gca,'xlim',[-1 1],'ylim',[-1 1],'zlim',[-1,1]) gui.check=uicontrol('style','checkbox'); set(gui.fig,'DoubleBuffer','on'); set(gui.fig,'userdata',gui) set(get(gui.fig,'children'),'units','normalized') start(gui.ai); function saf(n) % In the future, it's going to be necessary to buffer around the region % we wish to analyze. Keep 3 frames and analyze the central frame. gui=get(gcf,'userdata'); if n==1 dat=getdata(gui.ai,gui.ai.samplesacquiredfcncount); dat=[gui.predat;dat]; set(gui.p0,'ydata',abs(fft(dat)),'xdata',(1:length(dat))*(gui.ai.samplerate/length(dat))) set(get(gui.p0,'parent'),'ylim',[0 1500],'xlim',[1 gui.ai.samplerate/2]) %Band Pass the raw data to isolate the channels (7th order butterworth %band pass filters datx=filter(gui.bx,gui.ax,dat); daty=filter(gui.by,gui.ay,dat); datz=filter(gui.bz,gui.az,dat); %limiting may help remove beat frequency noise if get(gui.check,'value') daty(daty>=0)=1; daty(daty<0)=-1; daty=filter(gui.by,gui.ay,daty); datz(datz>=0)=1; datz(datz<0)=-1; datz=filter(gui.bz,gui.az,datz); end set(gui.p4,'ydata',abs(fft(datx)),'xdata',(1:length(datx))*(gui.ai.samplerate/length(dat))) set(gui.p5,'ydata',abs(fft(daty)),'xdata',(1:length(daty))*(gui.ai.samplerate/length(dat))) set(gui.p6,'ydata',abs(fft(datz)),'xdata',(1:length(datz))*(gui.ai.samplerate/length(dat))) %FM Demodulation of the 3 channels demodx=fmdemod(datx,625,22050,2500); demody=fmdemod(daty,3125,22050,2500); demodz=fmdemod(datz,5625,22050,2500); %Filter out remaining noise from the AM component of the signal demodx=filter(gui.b,gui.a,demodx); demody=filter(gui.b,gui.a,demody); demodz=filter(gui.b,gui.a,demodz); if gui.gx==0 gui.gx=mean(demodx(end-1000:end)); gui.gy=mean(demody(end-1000:end)); gui.gz=mean(demodz(end-1000:end)); gui.predat=dat(end-1000:end); set(gui.fig,'userdata',gui) drawnow return end demodx=demodx(1001:end); demody=demody(1001:end); demodz=demodz(1001:end); % 0 = 0V for x,y,z % 1 = 3.263V for x,y,z % Aref=3.263; Vz=5.28; %Plot the demodulated acceleration levels. Scale them assuming inital %acceleration is 1g in the z direction and that the values correspond %to increments determined by the data sheet. % Update graphics accordingly set(gui.p1,'xdata',1:length(demodx),'ydata',(demodx-gui.gx)*Aref/.120) set(gui.p2,'xdata',1:length(demody),'ydata',(demody-gui.gy)*Aref/.120) set(gui.p3,'xdata',1:length(demodz),'ydata',((demodz-gui.gz)*Aref)/.250+1) xaccel=sprintf('%1.1f',round(mean(get(gui.p1,'ydata'))*10)/10); yaccel=sprintf('%1.1f',round(mean(get(gui.p2,'ydata'))*10)/10); zaccel=sprintf('%1.1f',round(mean(get(gui.p3,'ydata'))*10)/10); set(gcf,'name',['Ax=',xaccel,'g Ay=',yaccel,'g Az=',zaccel,'g'],'numbertitle','off') xdat=[0 -mean(get(gui.p1,'ydata'))]; ydat=[0 mean(get(gui.p2,'ydata'))]; zdat=[0 -mean(get(gui.p3,'ydata'))]; oldx=get(gui.orient,'xdata'); oldy=get(gui.orient,'ydata'); oldz=get(gui.orient,'zdata'); if length(oldx)>15 oldx=oldx(1:15); oldy=oldy(1:15); oldz=oldz(1:15); end scale=max(abs([ydat,zdat,xdat])); set(gui.orient,'xdata',[0 xdat/scale oldx(3:end)] ,'ydata',[0 ydat/scale oldy(3:end)],'zdata',[0 zdat/scale oldz(3:end)]) gui.predat=dat(end-1000:end); set(gui.fig,'userdata',gui) drawnow elseif n==2 daqreset close all end