康复手上位机系统
目录
1串口通信
%%主函数:注释说明和窗口初始化
function varargout = serial_communication2(varargin)
gui_Singleton = 1;
gui_State = struct('gui_Name', mfilename, ...
'gui_Singleton', gui_Singleton, ...
'gui_OpeningFcn', @serial_communication2_OpeningFcn, ...
'gui_OutputFcn', @serial_communication2_OutputFcn, ...
'gui_LayoutFcn', [] , ...
'gui_Callback', []);
if nargin && ischar(varargin)
gui_State.gui_Callback = str2func(varargin);
end
if nargout
[varargout] = gui_mainfcn(gui_State, varargin);
else
gui_mainfcn(gui_State, varargin);
end
%%子函数OpeningFcn打开窗口时的初始化程序
function serial_communication2_OpeningFcn(hObject, eventdata, handles, varargin)
handles.output = hObject;
warning('off');
javaFrame = get(hObject, 'JavaFrame');
javaFrame.setFigureIcon(javax.swing.ImageIcon('mll.png'));
%% 初始化参数
hasData = false; %表征串口是否接收到数据
isShow = false; %表征是否正在进行数显示,即是否正在执行函数dataDisp
isStopDisp = false; %表征是否按下了【停止显示】按钮
isHexDisp = false; %表征是否勾选了【十六进制显示】
isHexSend = false; %表征是否勾选了【十六进制发送】
numRec = 0; %接收字符计数
numSend = 0; %发送字符计数
strRec = ''; %已接收的字符串
%% 将上述参数作为应用数据,存入窗口对象内
setappdata(hObject, 'hasData', hasData);
setappdata(hObject, 'strRec', strRec);
setappdata(hObject, 'numRec', numRec);
setappdata(hObject, 'numSend', numSend);
setappdata(hObject, 'isShow', isShow);
setappdata(hObject, 'isStopDisp', isStopDisp);
setappdata(hObject, 'isHexDisp', isHexDisp);
setappdata(hObject, 'isHexSend', isHexSend);
guidata(hObject, handles);
%%OutputFcn函数是窗口的输出子函数
function varargout = serial_communication2_OutputFcn(hObject, eventdata, handles)
varargout = handles.output;
%%串口回调函数
function com_Callback(hObject,~, handles)
%%在com对象产生过程中执行的回调函数
function com_CreateFcn(hObject, eventdata, handles)
if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
set(hObject,'BackgroundColor','white');
end
%%波特率回调函数
function rate_Callback(hObject, eventdata, handles)
function rate_CreateFcn(hObject, eventdata, handles)
if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
set(hObject,'BackgroundColor','white');
end
%%校验位回调函数
function jiaoyan_Callback(hObject, eventdata, handles)
function jiaoyan_CreateFcn(hObject, eventdata, handles)
if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
set(hObject,'BackgroundColor','white');
end
%%数据位回调函数
function data_bits_Callback(hObject, eventdata, handles)
function data_bits_CreateFcn(hObject, eventdata, handles)
if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
set(hObject,'BackgroundColor','white');
end
%%停止位回调函数
function stop_bits_Callback(hObject, eventdata, handles)
function stop_bits_CreateFcn(hObject, eventdata, handles)
if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
set(hObject,'BackgroundColor','white');
end
%% (1) 【打开/关闭串口】按钮的回调函数
%% 打开串口,并初始化相关参数
function start_serial_Callback(hObject, eventdata, handles)
%% 若按下【打开串口】按钮,打开串口
if get(hObject, 'value')
com_n = sprintf('com%d', get(handles.com, 'value')); %% 获取串口的端口名
rates = [300 600 1200 2400 4800 9600 19200 38400 43000 56000 57600 115200];
baud_rate = rates(get(handles.rate, 'value')); %% 获取波特率
%% 获取校验位设置
switch get(handles.jiaoyan, 'value')
case 1
jiaoyan = 'none';
case 2
jiaoyan = 'odd';
case 3
jiaoyan = 'even';
end
data_bits = 5 + get(handles.data_bits, 'value'); %% 获取数据位个数
stop_bits = get(handles.stop_bits, 'value'); %% 获取停止位个数
%% 创建串口对象
scom = serial(com_n);
scom
%% 配置串口属性,指定其回调函数 配置串口属性,指定其回调函数
set(scom, 'BaudRate', baud_rate, 'Parity', jiaoyan, 'DataBits',... %BytesAvailableFcnCount:字节计数
data_bits, 'StopBits', stop_bits, 'BytesAvailableFcnCount', 10,... %BytesAvailableFcn:字节计数回调函数
'BytesAvailableFcnMode', 'byte', 'BytesAvailableFcn', ,...%BytesAvailableFcnMode:字节模式,一般byte
'TimerPeriod', 0.05, 'TimerFcn', ); %TimerFcn:定时回调函数,TimerPeriod:定时周期,串口数据通信
%% 将串口对象的句柄作为用户数据,存入窗口对象
set(handles.figure1, 'UserData', scom);
%% 尝试打开串口
try %执行过程中如果出错,执行catch下的语句
fopen(scom); %打开串口
catch % 若串口打开失败,提示“串口不可获得!”
msgbox('串口不可获得,未连接外设!');
set(hObject, 'value', 0); %弹起本按钮
return;
end
%% 打开串口后,允许串口发送数据,清空接收显示区,点亮串口状态指示灯
%% 并更改本按钮文本为“关闭串口”
set(handles.period_send, 'Enable', 'on'); %启用【自动发送】按钮
set(handles.manual_send, 'Enable', 'on'); %启用【手动发送】按钮
set(handles.xianshi, 'string', ''); %清空接收显示区
% set(handles.activex1, 'value', 1); %点亮串口状态指示灯
set(hObject, 'String', '关闭串口'); %设置本按钮文本为“关闭串口”
else %若关闭串口
%% 停止并删除定时器
t = timerfind; %查找定时器
if ~isempty(t)
stop(t);
delete(t);
end
%% 停止并删除串口对象
scoms = instrfind; %在内存查找串口对象
stopasync(scoms); %停止异步读写
fclose(scoms);
delete(scoms);
%% 禁用【自动发送】和【手动发送】按钮,熄灭串口状态指示灯
set(handles.period_send, 'Enable', 'off', 'value', 0); %禁用【自动发送】按钮
set(handles.manual_send, 'Enable', 'off'); %禁用【手动发送】按钮
set(hObject, 'value', 0); %弹起本按钮
set(hObject, 'String', '打开串口'); %设置本按钮文本为“关闭串口”
% set(handles.activex1, 'value', 0); %熄灭串口状态指示灯
end
%%(2) 串口数据显示,串口的TimerFcn回调函数
function dataDisp(obj, event, handles)
%% 获取参数
hasData = getappdata(handles.figure1, 'hasData'); %串口是否收到数据
strRec = getappdata(handles.figure1, 'strRec'); %串口接收的字符串,定时显示该数据
numRec = getappdata(handles.figure1, 'numRec'); %串口接收到的数据个数
%% 若串口没有接收到数据,先尝试接收串口数据
if ~hasData
bytes(obj, event, handles);
end
%% 若串口有数据,显示串口数据
if hasData
%% 给数据显示模块加互斥锁
%% 在执行显示数据模块时,不接受串口数据,即不执行BytesAvailableFcn回调函数
setappdata(handles.figure1, 'isShow', true);
%% 若要显示的字符串长度超过10000,清空显示区
if length(strRec) > 10000
strRec = '';
setappdata(handles.figure1, 'strRec', strRec);
end
%% 显示数据
set(handles.xianshi, 'string', strRec);
%% 更新接收计数
set(handles.rec,'string', numRec);
%% 更新hasData标志,表明串口数据已经显示
setappdata(handles.figure1, 'hasData', false);
%% 给数据显示模块解锁
setappdata(handles.figure1, 'isShow', false);
end
%% (3) 串口接收数据,串口的BytesAvailableFcn回调函数(字节计数回调函数)
function bytes(obj, ~, handles)
%% 获取参数
strRec = getappdata(handles.figure1, 'strRec'); %获取串口要显示的数据
numRec = getappdata(handles.figure1, 'numRec'); %获取串口已接收数据的个数
isStopDisp = getappdata(handles.figure1, 'isStopDisp'); %是否按下了【停止显示】按钮
isHexDisp = getappdata(handles.figure1, 'isHexDisp'); %是否十六进制显示
isShow = getappdata(handles.figure1, 'isShow'); %是否正在执行显示数据操作
%% 若正在执行数据显示操作,暂不接收串口数据
if isShow
return;
end
%% 获取串口可获取的数据个数
n = get(obj, 'BytesAvailable');
%% 若串口有数据,接收所有数据
if n
%% 更新hasData参数,表明串口有数据需要显示
setappdata(handles.figure1, 'hasData', true);
%% 读取串口数据
a = fread(obj, n, 'uchar'); %从obj中读出n个数据,8位无符号读出
%% 若没有停止显示,将接收到的数据解算出来,准备显示
if ~isStopDisp
%% 根据进制显示的状态,解析数据为要显示的字符串
if ~isHexDisp
c = char(a');
else
strHex = dec2hex(a')';
strHex2 = [strHex; blanks(size(a, 1))];
c = strHex2(:)';
end
%% 更新已接收的数据个数
numRec = numRec + size(a, 1); %size(a,1)返回矩阵 a 的行数
%% 更新要显示的字符串
strRec = [strRec c];
end
%% 更新参数
setappdata(handles.figure1, 'numRec', numRec); %更新已接收的数据个数
setappdata(handles.figure1, 'strRec', strRec); %更新要显示的字符串
end
%% (4)清空要显示的字符串
function qingkong_Callback(hObject, eventdata, handles)
setappdata(handles.figure1, 'strRec', '');
set(handles.xianshi, 'String', '');%% 清空显示
%% (5)根据【停止显示】按钮的状态,更新isStopDisp参数
function stop_disp_Callback(hObject, eventdata, handles)
if get(hObject, 'Value')
isStopDisp = true;
else
isStopDisp = false;
end
setappdata(handles.figure1, 'isStopDisp', isStopDisp);
%function radiobutton1_Callback(hObject, eventdata, handles)
%function radiobutton2_Callback(hObject, eventdata, handles)
%function togglebutton4_Callback(hObject, eventdata, handles)
%%(6) 根据【十六进制显示】复选框的状态,更新isHexDisp参数
function hex_disp_Callback(hObject, eventdata, handles)
if get(hObject, 'Value')
isHexDisp = true;
else
isHexDisp = false;
end
setappdata(handles.figure1, 'isHexDisp', isHexDisp);
%% (7)手动发送回调函数
function manual_send_Callback(hObject, eventdata, handles)
scom = get(handles.figure1, 'UserData');
numSend = getappdata(handles.figure1, 'numSend');
val = get(handles.sends, 'UserData');
numSend = numSend + length(val);
set(handles.trans, 'string', num2str(numSend));
setappdata(handles.figure1, 'numSend', numSend);
%% 若要发送的数据不为空,发送数据
if ~isempty(val)
%% 设置倒计数的初值
n = 1000;
while n
%% 获取串口的传输状态,若串口没有正在写数据,写入数据
str = get(scom, 'TransferStatus');
if ~(strcmp(str, 'write') || strcmp(str, 'read&write')) %strcmp比较两个字符串是否相等
fwrite(scom, val, 'uint8', 'async'); %数据写入串口
val
break;
end
n = n - 1; %倒计数
end
end
%% (8)清空发送区
function clear_send_Callback(hObject, eventdata, handles)
set(handles.sends, 'string', '')
set(handles.sends, 'UserData', []); %% 更新要发送的数据
%function checkbox2_Callback(hObject, eventdata, handles)
%% (9) 【自动发送】按钮的Callback回调函数
function period_send_Callback(hObject, eventdata, handles)
%% 若按下【自动发送】按钮,启动定时器;否则,停止并删除定时器
if get(hObject, 'value')
t1 = 0.001 * str2double(get(handles.period1, 'string'));%获取定时器周期
t = timer('ExecutionMode','fixedrate', 'Period', t1, 'TimerFcn',...
); %创建定时器
set(handles.period1, 'Enable', 'off'); %禁用设置定时器周期的Edit Text对象
set(handles.sends, 'Enable', 'inactive'); %禁用数据发送编辑区
start(t); %启动定时器
else
set(handles.period1, 'Enable', 'on'); %启用设置定时器周期的Edit Text对象
set(handles.sends, 'Enable', 'on'); %启用数据发送编辑区
t = timerfind; %查找定时器
stop(t); %停止定时器
delete(t); %删除定时器
end
%% (10)设置发送周期文本框
function period1_Callback(hObject, eventdata, handles)
function period1_CreateFcn(hObject, eventdata, handles)
if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
set(hObject,'BackgroundColor','white');
end
%% (11)计数清零,并更新参数numRec和numSend
function clear_count_Callback(hObject, eventdata, handles)
set([handles.rec, handles.trans], 'string', '0')
setappdata(handles.figure1, 'numRec', 0);
setappdata(handles.figure1, 'numSend', 0);
%% (12)设置是否允许复制接收数据显示区内的数据
function copy_data_Callback(hObject, eventdata, handles)
if get(hObject,'value')
set(handles.xianshi, 'enable', 'on');
else
set(handles.xianshi, 'enable', 'inactive');
end
%% (13)关闭窗口时,检查定时器和串口是否已关闭 ,若没有关闭,则先关闭
function figure1_CloseRequestFcn(hObject, eventdata, handles)
t = timerfind; %% 查找定时器
%% 若存在定时器对象,停止并关闭
if ~isempty(t)
stop(t); %若定时器没有停止,则停止定时器
delete(t);
end
scoms = instrfind; %% 查找串口对象
%% 尝试停止、关闭删除串口对象
try
stopasync(scoms);
fclose(scoms);
delete(scoms);
end
delete(hObject); %% 关闭窗口
%% (14)根据【十六进制发送】复选框的状态,更新isHexSend参数
function hex_send_Callback(hObject, eventdata, handles)
if get(hObject,'value')
isHexSend = true;
else
isHexSend = false;
end
setappdata(handles.figure1, 'isHexSend', isHexSend);
%% 更新要发送的数据
sends_Callback(handles.sends, eventdata, handles);
%% (15) 数据发送编辑区的Callback回调函数,更新要发送的数据
function sends_Callback(hObject, eventdata, handles)
%% 获取数据发送编辑区的字符串
str = get(hObject, 'string');
%% 获取参数isHexSend的值
isHexSend = getappdata(handles.figure1, 'isHexSend');
if ~isHexSend %若为ASCII值形式发送,直接将字符串转化为对应的数值
val = double(str);
else %若为十六进制发送,获取要发送的数据
n = find(str == ' '); %查找空格,返回所有空格的位置
n =[0 n length(str)+1]; %空格的索引值 n行向量
%% 每两个相邻空格之间的字符串为数值的十六进制形式,将其转化为数值
for i = 1 : length(n)-1
temp = str(n(i)+1 : n(i+1)-1); %获得每段数据的长度,为数据转换为十进制做准备
if ~rem(length(temp), 2)
b = reshape(temp, 2, [])'; %将每段十六进制字符串转化为单元数组
else
break;
end
end
val = hex2dec(b)'; %将十六进制字符串转化为十进制数,等待写入串口
end
%% 更新要显示的数据
set(hObject, 'UserData', val);
2患者信息记录
3患者主被动康复
4游戏
4.1打地鼠
function varargout = gamedishu(varargin)
gui_Singleton = 1;
gui_State = struct('gui_Name', mfilename, ...
'gui_Singleton', gui_Singleton, ...
'gui_OpeningFcn', @gamedishu_OpeningFcn, ...
'gui_OutputFcn', @gamedishu_OutputFcn, ...
'gui_LayoutFcn', [] , ...
'gui_Callback', []);
if nargin && ischar(varargin{1})
gui_State.gui_Callback = str2func(varargin{1});
end
if nargout
[varargout{1:nargout}] = gui_mainfcn(gui_State, varargin{:});
else
gui_mainfcn(gui_State, varargin{:});
end
function gamedishu_OpeningFcn(hObject, eventdata, handles, varargin)
handles.output = hObject;
guidata(hObject, handles);
function varargout = gamedishu_OutputFcn(hObject, eventdata, handles)
varargout{1} = handles.output;
%%(1)开始游戏
function start_game_Callback(hObject, eventdata, handles)
tic %开始计时
I0=imread('background.jpg'); %读取背景图 %% imread 读取图像得到三维矩阵,前两维是空间坐标,第三维取值1/2/3代表三基色红、绿、蓝
I1=imread('mouse.jpg'); %读取地鼠
background_size = size(I0);
mouse_size = size(I1);
I1_Alpha = double((I1(:,:,1)<230 & I1(:,:,2) <230 & I1(:,:,3) <230)); %% 将地鼠图片中的白色区域置1,(隐藏)
hitCount=0; %定义一个变量并取0
ratHole_location=load('ratHole.txt'); %取出鼠洞文本文档中的值 ,已经从背景图片中获得(应该是鼠洞的左上角坐标值)
ratHole_num=size(ratHole_location,1); %确定鼠洞的个数并赋值给N
ratHole_location(:,1) = ratHole_location(:,1) + mouse_size(2)./2; % 求得鼠洞出口的中心位置
ratHole_location(:,2) = ratHole_location(:,2) + mouse_size(1)./2; % 为什么是:X+y,Y+x
rand_ratLocation=floor(rand*ratHole_num)+1; % 对N中的元素随机取整(随机取1-12),floor取比它小的整数,rand取0-1的随机小数
set(handles.end_game,'UserData',0); %终止程序isStop=0
imshow(I0); %显示Image1的内容
set(gca, 'NextPlot', 'Add'); %gca返回当前axes对象的句柄值,nextplot重绘模式,add使用当前的坐标轴,把新的图形对象加到此坐标轴中
ratImage_changed = image(-1000,-1000,I1); % image(x,y,C), x,y指定坐标轴的范围,显示相同的图片
set(ratImage_changed,'AlphaData', I1_Alpha); % 改变 I1_Alpha 值,可以改变明暗(透明程度)
pos_clickedShow = text(0, -8, ''); % text(x,y,'string')在图形指定位置显示字符串
for k=1:100000
x_rat=ratHole_location(rand_ratLocation,1);
y_rat=ratHole_location(rand_ratLocation,2); % 定义地鼠的横纵坐标
rat_rescale_factor = (y_rat+200)./(background_size(1)+200); %%地鼠缩放因子,有不同的方法设置rescale_factor,100 是随便取的数字
%将地鼠贴图到背景图的范围内,YData有点疑问
set(ratImage_changed ,'XData', [x_rat-mouse_size(2)*rat_rescale_factor./2, x_rat+mouse_size(2)*rat_rescale_factor./2],...
'YData', [y_rat-mouse_size(1)*rat_rescale_factor+10.* rat_rescale_factor, y_rat+10.*rat_rescale_factor]);
pos_clicked=get(gca,'currentpoint'); %确定鼠标的坐标 ,获取最近一次点击的位置,返回一个2*3矩阵,axes是3D的,每行代表一个点的坐标
x_clicked=pos_clicked(1,1);
y_clicked=pos_clicked(1,2);
set(pos_clickedShow, 'String', sprintf('%d %d',x_clicked,y_clicked)); % 显示当下鼠标点击的位置
drawnow;
%判断鼠标是否点击在地鼠的范围内
if ((x_clicked>=x_rat-mouse_size(2)*rat_rescale_factor./2)...
&&(x_clicked<=(x_rat+x_rat+mouse_size(2)*rat_rescale_factor./2))...
&&(y_clicked>=y_rat-mouse_size(1)*rat_rescale_factor)...
&&(y_clicked<=y_rat))
hitCount=hitCount+1; % 对变量DJ进行累加
set(handles.correct_hit,'String',sprintf('正确打击:%3.0f次',hitCount)); % 在text2中显示DJ的值
rand_ratLocation=floor(rand*ratHole_num)+1; % 随机取整N中的元素
end;
isStop=get(handles.end_game,'UserData'); % 把pushbutton2的内容赋值给isStop
if (isStop==1); % 判断isStop==1
break;
end;
end;
set(handles.game_time, 'String', sprintf('游戏时间:%3.0f秒',toc)); %计时结束,并在text1中显示时间
%%(2)结束游戏
function end_game_Callback(hObject, eventdata, handles)
set(handles.end_game,'UserData',1); % isStop=1
4.2flappy bird
function varargout = flappy_point(varargin)
gui_Singleton = 1;
gui_State = struct('gui_Name', mfilename, ...
'gui_Singleton', gui_Singleton, ...
'gui_OpeningFcn', @flappy_point_OpeningFcn, ...
'gui_OutputFcn', @flappy_point_OutputFcn, ...
'gui_LayoutFcn', [] , ...
'gui_Callback', []);
if nargin && ischar(varargin{1})
gui_State.gui_Callback = str2func(varargin{1});
end
if nargout
[varargout{1:nargout}] = gui_mainfcn(gui_State, varargin{:});
else
gui_mainfcn(gui_State, varargin{:});
end
function flappy_point_OpeningFcn(hObject, eventdata, handles, varargin)
handles.output = hObject;
global g y1 y2 y3 Fs1 Fs2 Fs3 picMbg picMbd flysound vwall cond record
record=0;
flysound=0;
g=5; %%重力加速度 %%============================================================================
vwall=4; %%类似于鸟的水平速度 %%============================================================================
cond=0; %%条件数
[y1,Fs1] = audioread('fb_music\die.wav');
[y2,Fs2] = audioread('fb_music\jump.wav');
[y3,Fs3] = audioread('fb_music\fly.wav');
axes(handles.axes1);
cla reset; %%清除当前的 axes
picbg=imread('fb_pic\BG.bmp');
imshow(picbg,'xdata',[1,80],'ydata',[1,110]);
set(handles.axes1,'unit','normalized','visible','on');
axis([0 80 0 110]); %%表示坐标轴的最小最大值
axis off; %%关闭所用坐标轴上的标记、格栅、单位标记
set(handles.kaishi,'enable','on');
set(handles.qingchu,'enable','on');
picMbg=picbg;
size1=size(picbg(:,1,1));
for i=1:size1(1)
picMbg(i,:,:)=picbg(size1(1)+1-i,:,:); %%横坐标,逆序
end
picbd=imread('fb_pic\bird.png');
picMbd=picbd;
size1=size(picbd(:,1,1));
for i=1:size1(1)
picMbd(i,:,:)=picbd(size1(1)+1-i,:,:);
end
guidata(hObject, handles);
function varargout = flappy_point_OutputFcn(hObject, eventdata, handles)
varargout{1} = handles.output;
%%(1)【清除】按钮
function qingchu_Callback(hObject, eventdata, handles)
global record
record=0;
set(handles.gaofen,'string',num2str(record)); %%高分清除掉
%%(2)【按键按下】回调函数
function figure1_KeyPressFcn(hObject, eventdata, handles)
global v cond
press=get(hObject,'currentkey'); %%获取当下按下的按键的值
if strcmp(press,'downarrow') %%向下键,开始
if (cond==0)
kaishi_Callback(hObject, eventdata, handles);
return;
end
end
switch press
case {'space','uparrow'} %% 空格键、向上键,向上跳
v=5; %%=================================================================================================
game_level=get(handles.selecte_level,'value');
switch game_level
case 2
v=2;
case 3
v=5;
case 4
v=8;
end
end
%%(3)【开始】按钮
function kaishi_Callback(hObject, eventdata, handles)
global v record g vwall cond y1 y2 Fs1 Fs2 flysound picMbg picMbd
%dt=str2num(get(handles.shijian,'string')); %时间 0.05秒
dt=0.05; %%================================================================================================
%%选择游戏难度
game_level=get(handles.selecte_level,'value');
switch game_level
case 2
g=2;
dt=0.02;
vwall=3;
case 3
g=5;
dt=0.05;
vwall=11;
case 4
g=8;
dt=0.07;
vwall=13;
end
cond=1;
flysound=1;
v=0.0; %%鸟的初始垂直高度
h=70; %%鸟的初始高度
xx1=110; %%每张图两个障碍物,横坐标
xx2=155;
s=0; %%鸟横向飞过的路程
dx=0;
hh1=round(20+40*rand); %%障碍物,随机高度 (20+40*rand) 20-60之间 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
hh2=round(20+40*rand); %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
axes(handles.axes1);
cla reset; %%清除当前axes
hold on; %%使当前轴与图形保持而不被刷新,准备接受此后将绘制, (新图与旧图共存)
a1=imshow(picMbg,'xdata',[1,80],'ydata',[1,110]); %显示第一张背景
a2=imshow(picMbg,'xdata',[80,159],'ydata',[1,110]); %显示第二张背景
bd=imshow(picMbd,'xdata',[27,33],'ydata',[68.5,73.5]); %显示鸟
hold off; %%使当前轴与图形不在具备被刷新的性质 (原图被新图代替)
axis xy; %%使用笛卡尔坐标系,原点在左下角
axis([0 80 0 110]);
set(handles.kaishi,'enable','off');
set(handles.qingchu,'enable','off');
%%设置障碍物,用粗线表示
L1=line([xx1,xx1],[hh1+40,110],'color','g','linewidth',42,'erasemode','normal'); %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
L2=line([xx1,xx1],[0,hh1-10],'color','g','linewidth',42,'erasemode','normal'); %%%%%%%%%%%%%%%%%%%%%%%%%%
L3=line([xx2,xx2],[hh2+40,110],'color','g','linewidth',42,'erasemode','normal'); %%%%%%%%%%%%%%%%%%%%%
L4=line([xx2,xx2],[0,hh2-10],'color','g','linewidth',42,'erasemode','normal'); %%%%%%%%%%%%%%%%%%%%%%%%%%%
%%障碍物的前端区域
L5=line([xx1,xx1],[hh1+30,hh1+40],'color',[0 1 0.5],'linewidth',48,'erasemode','normal'); %%%%%%%%%%
L6=line([xx1,xx1],[hh1-10,hh1],'color',[0 1 0.5],'linewidth',48,'erasemode','normal'); %%%%%%%%
L7=line([xx2,xx2],[hh2+30,hh2+40],'color',[0 1 0.5],'linewidth',48,'erasemode','normal'); %%%%%%%%%%%%
L8=line([xx2,xx2],[hh2-10,hh2],'color',[0 1 0.5],'linewidth',48,'erasemode','normal'); %%%%%%%%%%%%%%%%%
while(cond==1) %%死循环
dx=dx+1;
count=fix(dx/3.5); %% fix取整函数,朝零向取整
if(count>80) %%图片宽度 80
count=0;
dx=0;
end
picx1=1-count;
picx2=80-count;
set(a1,'xdata',[picx1,picx1+79]); %%显示背景图片
set(a2,'xdata',[picx2,picx2+79]);
h=h+v*dt-0.5*g*dt^2; %%鸟的高度,只受重力作用
v=v-g*dt; %%鸟的速度,垂直方向上的
xx1=xx1-vwall*dt; %%飞过 dt 时间之后的,水平位置 8*0.05=0.4,水平每次减少 0.4
xx2=xx2-vwall*dt;
prescore=fix((s-40)/45.0); %%之前得分 s=84,prescore=0;
if(prescore<0)
prescore=0;
end
s=s+vwall*dt; %%鸟的飞行长度 s=85,score=1
score=fix((s-40)/45.0);
if(score<0)
score=0;
end
if(score>prescore) %%当前得分大于之前得分
switch game_level
case 1
sound(y2,Fs2); %%前两个游戏等级有声音提示,后两个没有,有声音提示游戏较卡
case 2
sound(y2,Fs2);
end
end
set(bd,'ydata',[h-2,h+2]); %%设置每次循环鸟的高度
set(L1,'xdata',[xx1,xx1]); %%设置每次循环,障碍物的水平位置
set(L2,'xdata',[xx1,xx1]);
set(L5,'xdata',[xx1,xx1]);
set(L6,'xdata',[xx1,xx1]);
set(L3,'xdata',[xx2,xx2]);
set(L4,'xdata',[xx2,xx2]);
set(L7,'xdata',[xx2,xx2]);
set(L8,'xdata',[xx2,xx2]);
if(xx1<(-5)) %%每次循环 xx1减少一点
hh1=round(20+40*rand); %%设置随机高度 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
xx1=85;
set(L1,'xdata',[xx1,xx1],'ydata',[hh1+40,110]); %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
set(L2,'xdata',[xx1,xx1],'ydata',[0,hh1-10]); %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
set(L5,'xdata',[xx1,xx1],'ydata',[hh1+30,hh1+40]); %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
set(L6,'xdata',[xx1,xx1],'ydata',[hh1-10,hh1]); %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%55
end
if(xx2<(-5))
hh2=round(20+40*rand); %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
xx2=85;
set(L3,'xdata',[xx2,xx2],'ydata',[hh2+40,110]); %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
set(L4,'xdata',[xx2,xx2],'ydata',[0,hh2-10]); %%%%%%%%%%%%%%%%%%%%%%%%%%%%%
set(L7,'xdata',[xx2,xx2],'ydata',[hh2+30,hh2+40]); %%%%%%%%%%%%%%%%%%%%%%%%%%%%%
set(L8,'xdata',[xx2,xx2],'ydata',[hh2-10,hh2]); %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
end
if((h>110)||(h<0)) %%如果鸟的高度超出背景图片范围,死亡
cond=0; %%条件数置0,跳出死循环
set(handles.kaishi,'enable','on');
set(handles.qingchu,'enable','on');
if(record<=score)
record=score; %%最高得分低于当前得分,替换
set(handles.gaofen,'string',num2str(record));
end
sound(y1,Fs1); %%死亡的声音
%flysound=0;
text(12,70,'Game Over','fontsize',40,'color','k');
while(h>0) %%当鸟的高度超过图片上限时,死亡,鸟降落
h=h-1;
pause(0.005);
set(bd,'ydata',[h-2,h+2]);
end
else %%当鸟的高度在背景图范围内时,
if((xx1<=38)&&(xx1>=22)) %%(1) %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
if((h>(hh1+28))||(h<(hh1+2))) %%死亡 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
cond=0;
set(handles.kaishi,'enable','on');
set(handles.qingchu,'enable','on');
if(record<=score)
record=score;
set(handles.gaofen,'string',num2str(record));
end
sound(y1,Fs1);
%flysound=0;
text(12,70,'Game Over','fontsize',40,'color','k');
while(h>0)
h=h-1;
pause(0.005);
set(bd,'ydata',[h-2,h+2]);
end
end
end
if((xx2<=38)&&(xx2>=22)) %%(2) %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
if((h>(hh2+28))||(h<(hh2+2))) %%死亡 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
cond=0;
set(handles.kaishi,'enable','on');
set(handles.qingchu,'enable','on');
if(record<=score)
record=score;
set(handles.gaofen,'string',num2str(record));
end
sound(y1,Fs1);
%flysound=0;
text(12,70,'Game Over','fontsize',40,'color','k');
while(h>0)
h=h-1;
pause(0.005);
set(bd,'ydata',[h-2,h+2]);
end
end
end
end
set(handles.fenshu,'string',num2str(score));
drawnow;
end
function qingchu_CreateFcn(hObject, eventdata, handles)
function kaishi_CreateFcn(hObject, eventdata, handles)
function fenshu_Callback(hObject, eventdata, handles)
function fenshu_CreateFcn(hObject, eventdata, handles)
if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
set(hObject,'BackgroundColor','white');
end
function gaofen_Callback(hObject, eventdata, handles)
function gaofen_CreateFcn(hObject, eventdata, handles)
if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
set(hObject,'BackgroundColor','white');
end
function shijian_Callback(hObject, eventdata, handles)
function shijian_CreateFcn(hObject, eventdata, handles)
if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
set(hObject,'BackgroundColor','white');
end
function selecte_level_Callback(hObject, eventdata, handles)
function selecte_level_CreateFcn(hObject, eventdata, handles)
if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
set(hObject,'BackgroundColor','white');
end
%%%=====================================================================================================================
5信号实时采集(delsys)
function get_original_semg
HOST_IP = '127.0.0.1';
NUM_SENSORS = 2;
global CH1 CH2 plotHandlesEMG data_arrayEMG data_save byteflag flag p1 p2 p3 p4
CH1=5;
CH2=6;
plotHandlesEMG = zeros(NUM_SENSORS,1);
data_arrayEMG = [];
data_save=[];
byteflag=0;
flag=0;
p1=imread('photo\snooze.png');
p2=imread('photo\open.jpg');
p3=imread('photo\grasp.jpg');
p4=imread('photo\end2.jpg');
interfaceObjectEMG = tcpip(HOST_IP,50041);
interfaceObjectEMG.InputBufferSize = 6400;
commObject = tcpip(HOST_IP,50040);
axesHandlesEMG = zeros(NUM_SENSORS,1);
figureHandleEMG = figure('Name', 'EMG Data','Numbertitle', 'off', 'CloseRequestFcn', {@localCloseFigure, interfaceObjectEMG, commObject});
set(figureHandleEMG, 'position', [400 50 850 600]);
for i = 1:NUM_SENSORS
axesHandlesEMG(i) = subplot(2,2,i);
plotHandlesEMG(i) = plot(axesHandlesEMG(i),0,'-y','LineWidth',1);
set(axesHandlesEMG(i),'YGrid','on');
set(axesHandlesEMG(i),'XGrid','on');
set(axesHandlesEMG(i),'Color',[.15 .15 .15]);
set(axesHandlesEMG(i),'YLim', [-.0005 .0005]);
set(axesHandlesEMG(i),'YLimMode', 'manual');
set(axesHandlesEMG(i),'XLimMode', 'manual');
set(axesHandlesEMG(i),'XLim', [0 2000]);
xlabel(axesHandlesEMG(i),'Samples');
title(sprintf('EMG %i', i));
end
axis;
subplot(2,2,3);
bytesToReadEMG = 2560;
interfaceObjectEMG.BytesAvailableFcn = {@localReadAndPlotMultiplexedEMG,plotHandlesEMG,bytesToReadEMG};
interfaceObjectEMG.BytesAvailableFcnMode = 'byte';
interfaceObjectEMG.BytesAvailableFcnCount = bytesToReadEMG;
drawnow;
try
fopen(interfaceObjectEMG);
fopen(commObject);
catch
localCloseFigure( interfaceObjectEMG, commObject);
delete(figureHandleEMG);
error('CONNECTION ERROR: Please start the Delsys Trigno Control Application and try again');
end
fprintf(commObject, sprintf(['START\r\n\r']));
function localReadAndPlotMultiplexedEMG(interfaceObjectEMG, ~,~,~, ~)
bytesReady = interfaceObjectEMG.BytesAvailable;
bytesReady = bytesReady - mod(bytesReady,2560);
if (bytesReady == 0)
return;
end
global CH1 CH2 plotHandlesEMG data_arrayEMG data_save byteflag flag p1 p2 p3 p4
data = cast(fread(interfaceObjectEMG,bytesReady), 'uint8');
data = typecast(data, 'single');
data_save = [data_save; data];
if(size(data_arrayEMG, 1) < 32000)
data_arrayEMG = [data_arrayEMG; data];
else
data_arrayEMG = [data_arrayEMG(size(data,1) + 1 : size(data_arrayEMG, 1));data];
end
byteflag=byteflag+bytesReady;
if byteflag>=12800
byteflag=0;
data_ch1 = data_arrayEMG(CH1:16:end);
data_ch2 = data_arrayEMG(CH2:16:end);
set(plotHandlesEMG(1), 'Ydata', data_ch1);
set(plotHandlesEMG(2), 'Ydata', data_ch2);
flag=flag+1
switch flag
case {1,200,400,600,800}
imshow(p1);
case {100,500}
imshow(p2);
case {300,700}
imshow(p3);
case 900
imshow(p4);
end
drawnow
end
function localCloseFigure(figureHandle,~,interfaceObject1, commObject)
global CH1 CH2 data_save
ch1 = data_save(CH1:16:end);
ch2 = data_save(CH2:16:end);
save patient_sEMG\semg ch1 ch2
data = [ch1,ch2];
load patient_sEMG\Patient_name.mat
ct = datestr(now,31);
rename = [ct(1:4),ct(6:7),ct(9:10),ct(12:13),ct(15:16),pname];
save (char(strcat('patient_sEMG\',rename)),'data');
if isvalid(interfaceObject1)
fclose(interfaceObject1);
delete(interfaceObject1);
clear interfaceObject1;
end
if isvalid(commObject)
fclose(commObject);
delete(commObject);
clear commObject;
end
delete(figureHandle);