HC-SR04 Measures Really Slow in Simulink with Arduino IO(Legacy)
2 次查看(过去 30 天)
显示 更早的评论
Hello everyone,
I'm trying to measure some distance with HC-SR04 on Matlab Simulink. And I want to do it by creating my own custom block on Arduino IO Package in Simulink.
What I did so far is,
Modified Adioes.m as below; Included these lines at the beginning of the code
#include <NewPing.h>
NewPing sonar(12, 11, 200);[/code]
Also added these lines to the switch case:
[code]case 400:
int distance;
delay(50); // Wait 50ms between pings (about 20 pings/sec). 29ms should be the
//I also tried without delay(50) line.
shortest delay between pings.
distance = sonar.ping_cm();
Serial.println(distance);
s=-1; /* we are done with the aux function so -1 */
break;
I uploaded this code successfully to my Uno then added these lines to Arduino.m.
% Ultrasound
function val=Ultrasound(a)
% roundTrip(a,byte); sends something to the arduino and back
% The first argument, a, is the arduino object.
% The second argument, byte, is any integer from 0 to 255.
% The output is the same byte, which was received from the
% arduino and sent back along the serial connection unchanged.
%
% This is provided as an example for people that want to add
% their own code to this arduino class (the section handling
% this dummy function in the pde file is handled as "case 400:",
% one might take the parameter, perform some potentially useful
% operation, and then send any result back via serial connection).
%
% Examples:
% roundTrip(a,48); % sends '48' to the arduino and back.
% a.roundTrip(53); % sends '53' to the arduino and back.
%
%%%%%%%%%%%%%%%%%%%%%%%%%ARGUMENT CHECKING %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% check arguments if a.chkp is true
% if a.chkp,
%
% % check nargin
% if nargin~=2,
% error('Function must have one argument');
% end
%
% % check argument (must be a byte)
% errstr=arduino.checknum(byte,'byte',0:255);
% if ~isempty(errstr), error(errstr); end
%
% end
%
% % check a.aser for validity if a.chks is true
% if a.chks,
% errstr=arduino.checkser(a.aser,'valid');
% if ~isempty(errstr), error(errstr); end
% end
%%%%%%%%%%%%%%%%%%%%%%%%%SEND ARGUMENT ALONG %%%%%%%%%%%%%%%%%%%%%%%%%%%%%
if strcmpi(get(a.aser,'Port'),'DEMO'),
% handle demo mode
% minimum analog output delay
pause(0.0014);
% sets the output
%val=byte;
else
% check a.aser for openness if a.chks is true
if a.chks,
errstr=arduino.checkser(a.aser,'open');
if ~isempty(errstr), error(errstr); end
end
% send mode and byte
fwrite(a.aser,[88],'uchar');
% get value back
val=fscanf(a.aser,'%d');
end
end % Ultrasound
the line fwrite(a.aser,[88],'uchar'); simply sends "88" to Arduino via Serial and the number 88 triggers a case which is "400" in our case. After Arduino execute the "case 400" it sends the distance from sonar.ping_cm() line.
So lastly I create a msfunction to call with a block on simulink. Here it is the code for msfunction:
function msfun_arduino_ultrasound(block)
% Level-2 M-File S-Functions, Copyright 2014, The MathWorks, Inc.
% instance variables
myArduino = [];
myPin = 0;
setup(block);
%%---------------------------------------------------------
function setup(block)
% Register the number of ports.
block.NumInputPorts = 0;
block.NumOutputPorts = 1;
block.SetPreCompOutPortInfoToDynamic;
block.OutputPort(1).Dimensions = 1;
block.OutputPort(1).SamplingMode = 'sample';
% Set up the states
block.NumContStates = 0;
block.NumDworks = 0;
% Register the parameters.
block.NumDialogPrms = 3; % arduinoVar, arduinoPin, Sample Time
block.DialogPrmsTunable = {'Nontunable', 'Nontunable', 'Nontunable'};
% Set the sample time
block.SampleTimes = [block.DialogPrm(3).Data 0];
block.SetAccelRunOnTLC(false); % run block in interpreted mode even w/ Acceleration
block.SimStateCompliance = 'DefaultSimState';
% the ArduinoIO Setup block uses the Start method to initialize the arduino
% connection; by using InitConditions, we ensure that we don't access
% the variable before it is created
block.RegBlockMethod('CheckParameters', @CheckPrms); % called during update diagram
% block.RegBlockMethod('Start', @Start); % called first
block.RegBlockMethod('PostPropagationSetup', @PostPropSetup);
block.RegBlockMethod('InitializeConditions', @InitConditions); % called second
block.RegBlockMethod('Outputs', @Output); % called first in sim loop
% block.RegBlockMethod('Update', @Update); % called second in sim loop
block.RegBlockMethod('Terminate', @Terminate);
end
function CheckPrms(block)
try
validateattributes(block.DialogPrm(1).Data, {'char'}, {'nonempty'}); % Name of arduino instance
validateattributes(block.DialogPrm(2).Data, {'numeric'}, {'real', 'scalar', 'nonnegative'}); % pin
errstr=arduino.checknum(block.DialogPrm(2).Data,'pin number',2:69);
if ~isempty(errstr), disp(errstr); error(errstr); end
validateattributes(block.DialogPrm(3).Data, {'numeric'}, {'real', 'scalar', 'nonzero'}); % sample time
catch %#ok<CTCH>
error('Simulink:ArduinoIO:invalidParameter', 'Invalid value for a mask parameter');
end
end
function PostPropSetup(block)
st = block.SampleTimes;
if st(1) == 0
error('The ArduinoIO library blocks can only handle discrete sample times');
end
end
function InitConditions(block)
% fprintf('%s: InitConditions\n', getfullname(block.BlockHandle));
customData = getSetupBlockUserData(bdroot(block.BlockHandle), block.DialogPrm(1).Data);
myArduino = customData('arduinoHandle');
%myPin = block.DialogPrm(2).Data;
%myArduino.pinMode(myPin, 'input');
end
function Output(block)
% fprintf('%s: Output\n', getfullname(block.BlockHandle));
duration = myArduino.Ultrasound();
if isempty(duration )
duration = 0;
end
block.OutputPort(1).Data = duration ;
end
function Terminate(block) %#ok<INUSD>
% The ArduinoIO Setup block handles cleanup of myArduino
end
end
You can see the result in the picture below. I get correct measurements, however, to get the distance measurement for 1.6 seconds I need to wait 10-15 seconds. So it's not real time anymore. There is a huge delay. What is your opinion about this delay?
![](https://www.mathworks.com/matlabcentral/answers/uploaded_files/191637/image.png)
1 个评论
AC
2019-3-19
Did you fix this problem ? I also want to measuse distance with HC-SR04 sensor on Simulink..
回答(1 个)
另请参阅
类别
在 Help Center 和 File Exchange 中查找有关 Arduino Hardware 的更多信息
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!