这是我的代码:
serialPort = 'COM3';
s = serial(serialPort,'BaudRate',9600);
if (s.Status == 'closed')
s.BytesAvailableFcnMode = 'byte';
s.BytesAvailableFcnCount = 200;
s.BytesAvailableFcn = @Serial_OnDataReceived;
fopen(s);
end
这是CallBack功能
function Serial_OnDataReceived(obj,event)
global s;
global i;
global endCheck;
global yVals;
global xVals;
if (s.Status == 'open')
while s.BytesAvailable > 0 && endCheck ~= '1',
data = str2num(fgetl(s));
dlmwrite ('SensorsReading.csv', data, '-append');
yVals = circshift(yVals,-1);
yVals(end) = data(3);
xVals = circshift(xVals,-1);
i = i + 0.0125;
xVals(end) = i;
end
figure(1);
plot(xVals,yVals);
end
端
在FOPEN
功能之后,我收到此警告:
BytesAvailableFcn正在被禁用。启用回调属性 要么使用FOPEN连接到硬件,要么设置BytesAvailableFcn属性。
回调函数Serial_OnDataReceived
中发生的逻辑是否在另一个线程上运行?
有没有办法将参数传递给函数?我想从回调函数修改主脚本中的数组,该函数位于不同的文件中。最好的方法是什么? 我还试图在他们更新时绘制值以显示某种动态动画。
答案 0 :(得分:0)
我不确定是什么产生了警告,但是为了回答你的另一个问题(如何将参数传递给回调以及如何更新情节),更好的方法是准备你的情节以外的回调,然后将句柄传递给回调仅用于更新。
nPointsInFigure = 10 ; %// number of "sliding points" in your figure
step = 0.0125 ; %// X points spacing
xVals = linspace(-(nPointsInFigure-1)*step,0,nPointsInFigure) ; %// prepare empty data for the plot
yVals = NaN(nPointsInFigure,1) ;
figure(1) ;
hp = plot( xVals , yVals ) ; %// Generate the plot (with empty data) it will be passed to the callback.
serialPort = 'COM3';
s = serial(serialPort,'BaudRate',9600);
if (s.Status == 'closed')
s.BytesAvailableFcnMode = 'byte';
s.BytesAvailableFcnCount = 200;
s.BytesAvailableFcn = {@Serial_OnDataReceived,hp,step} ; %// note how the parameters are passed to the callback
fopen(s);
end
您的回调将变为:
function Serial_OnDataReceived(obj,event,hp,step)
global endCheck; %// I don't know how you use that so I could not get rid of it.
xVals = get(hp,'XData') ; %// retrieve the X values from the plot
yVals = get(hp,'YData') ; %// retrieve the Y values from the plot
while obj.BytesAvailable > 0 && endCheck ~= '1',
data = str2num(fgetl(s));
dlmwrite ('SensorsReading.csv', data, '-append');
yVals = circshift(yVals,-1);
yVals(end) = data(3);
xVals = circshift(xVals,-1);
xVals(end) = xVals(end-1) + step ;
end
set( hp , 'XData',xVals , 'YData',yVals ) ; %// update the plot with the new values
另请注意:(1)您无需在回调函数中检查串口的状态是否打开/关闭。如果事件被触发,则表示端口已打开。 (2)您不需要将s
声明为全局,obj
参数实际上是串行对象本身。
答案 1 :(得分:0)
如果Hoki的建议不起作用,请尝试使用计时器。
% The following line is useful for debugging
mytimerCallback = @(~, ~) disp('Caught error For Tenzo Timer');
if isempty(timerXbee)
timerXbee = timer('ExecutionMode','FixedRate','Period',0.1,...
'TimerFcn',{@storeDataFromSerial},'ErrorFcn', mytimerCallback);
try
start(timerXbee);
catch
disp('Timer Xbee');
disp '******** InstrumentSubscription ERROR *********'
disp (exception.message);
disp '***********************************************'
end
end
% If you are using a polling approach, request data
sendRequest(cmd);
connectionRequested = true;
然后实现将在每个句点调用的计时器函数
function storeDataFromSerial(~,~,~)
while (get(xbee, 'BytesAvailable')~=0)
serialProtocol();
end
end
如果要断开设备并关闭通信,请不要忘记使用
停止计时器stop(timerXbee)