Matlab serial communication inconsistency - matlab

I want to control a Prior ProScan II controller and the fitting motorized stage with Matlab R2016b. Manual Tested with R2010b, got the same results. The relevant commands of the stage are VS(page 46), P(p.43), PS(p.44). In a plain terminal, immediately after the stage halts I can issue the P or PS command, returning the current position of the X and Y axes. If done in Matlab prompt, it MIGHT need a second or two to return the proper value, before that it returns 'R' - Probably not the ACK of the previous command as it is returned after init, without any R-ACKed commands issued before. When used in a script in a separate .m file, it can only return 'R'. My code in main.m is as follows:
%Opening serial port
s = serial('COM9');
set(s,'BaudRate',9600,'Terminator','CR'); %Note that CR will be concatenated to all commands
fopen(s);
s %print for debugging
t=1 %loop index
while true
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%Here is code to mess with a joystick that works fine, using VS command
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
if button(joy, 3) == 1 %Button3 of joystick should trigger position reading
fprintf(s,'vs,0,0'); %Halt joystick movement
pause(1) %Debouncing
fprintf(s,'p'); %Axe-pos reading command
fgets(s) %Reading the answer
end
%This way to increment follows the skipped parts and is required for timing
if mod(t, 100)==0
fprintf(s,'%s',Command);
t=1;
else
t=t+1;
end
If the segment in if..end is invoked from the Matlab prompt, it works fine in most cases.
>> s = openserial()
%properties as before, skipped to save space
>> fprintf(s,'ps');
>> fgets(s)
ans =
100000,100000
or
>> fprintf(s,'p');
>> fgets(s)
ans =
100000,100000,0
If I Ctrl+C out of the infinite loop but leave the serial open and issue
>> fprintf(s,'p');
>> fgets(s)
ans =
R
returns. Using fscanf() instead of fgets() yields the same results.
Is there any known bug of fprintf() or the ones mentioned above that could cause this? What could I do to succesfully and consistently read within a script? Thank you for any answers.

Solution was to force flush the serial input buffer, flushinput(s) before the line pause(1). For some reason, even fscanf() instead of fgets() didn't flush it. I still don't know why it worked fine outside the script but not within. Additionally, it also worked in a separate script.

Related

matlab: different result in script and command window

When I execute my script, one of the lines of code sets a variable to a 2x2 array of zeros. If I set a breakpoint, highlight the line and execute it in the command window, it produces an integer (which it should).
The other line sets first_peak to 0, when it should be 667.
(I added the cast in an attempt to resolve the problem because matlab was complaining about the variable type. Of course it didn't work.)
I can't seem to create an MWE without one of my datafiles, so attached are screenshots.
in-script:
command window:
If an MWE were going to produce the error, this one should, but again, it doesn't. The peaks(peak_ndx+1) line would produce the aforementioned 2x2 array, and peaks(peak_ndx) would produce the 0 value.
clear
for ndx = 1 : 6
peaks = [667 911 1288 1719 2114 2363 3505 3718 4010 4372 4682 4867];
peak_ndx=(ndx - 1) * 2 + 1;
peaks(peak_ndx)
peaks(peak_ndx+1)
end
TL;DR
When you hover the mouse over a variable, it shows the value that the variable currently has in the workspace.
The answer lies in the first paragraph you wrote. As you have mentioned, "When I execute my script, one of the lines of code sets a variable to a 2x2 array of zeros.", therefore hovering over second_peak on the line second_peak = cast(peaks(peak_ndx+1), 'int32') shows you zeros. Note that you have put a breakpoint on this line and this line is not executed yet. When you execute that line (unpause/continue running from the breakpoint) or enter that in the command window, you get the desired result.
If you put second_peak on another line and put a breakpoint on that line. Then after the second_peak = cast(peaks(peak_ndx+1), 'int32') line is run and program execution is paused at the next breakpoint, you'll see 1x1 int32 911.
Here is a reproducible example for you:
second_peak = int32([0,0;0,0]); %initially the value that you had
second_peak = int32(911); %put a breakpoint here
second_peak %and also here
Also make it sure that you're not doing unnecessary preallocation here.
Read "A Common Misunderstanding in Array Preallocation" in Loren Shure's blog.
If a variable is declared with the same name as a function, the variable may mask the function in some contexts (such as the Command Window), but not in others, such as in a script.

Matlab is printing comments and other contents of a script to command window

Below is a script in which I sum elements of a vector.
My problem here is that whenever I run the script, Matlab prints everything onto the command window. That is, it prints the comments, and everything else.
I only wanted to print the sum as an output, that is why I did not put ; after y = sum(x).
Can somebody help me prevent Matlab from printing the comments and contents of the script, except the ones I only want to print? Below is the script
%simple script
%this script sums the number of elements in a vector.
x = 1:2:10;
y = sum(x)
Here is the output in command window
Apparently echo on has been set in your MATLAB. You need to turn it off:
>> echo off

Running octave function prints lines of command name

Basically I'm running Octave 4.2.1 in Emacs 25.2.1 all within iTerm2 on macOS Sierra and every time I run a function (any function), a list of what look like command names is printed before the answer. I have tried to look up to see if this has been answered, but I'm having trouble describing the output list in a search. Here is the function command:
octave> f(3)
where f is declared as:
octave> function y = f(x)
>y = x + 10;
>endfunction
and the output is:
yes_or_no
ylabel
ylim
yulewalker
x
xlabel
xlim
xor
end
end_try_catch
end_unwind_protect
endfor
endfunction
endgrent
endif
endparfor
endpwent
endswitch
endwhile
endfunction
endfunction
ans = 13
I have tried placing semicolons at the end of every line (because I was unsure if this is function output that could be silenced with a semicolon), but that didn't pan out.
Edit: I have also tried turning off diary because I'm not sure that diary is. Needless to say, did not work out.
Let me know what I can do to stop this output. And if this is a duplicate due to me not having the vocabulary to search for my solution, obviously just mark it and I'll follow the link.
Thanks!

Prepare command in MATLAB

Is there a way in MATLAB to prepare a command programmatically (ie. writing a command directly to the command prompt) so the user can execute it by pressing an enter?
I want to implement my own "Did you mean:" functionality, that is built into MATLAB already.
It can be done using Java from Matlab to programmatically generate key events, along the lines of this answer.
Let's say the command you want to "prepare" is dir. Then
commandwindow; %// make Matlab command window have focus
robot = java.awt.Robot; %/ Java Robot class
robot.keyPress (java.awt.event.KeyEvent.VK_D); %// key press event
robot.keyRelease (java.awt.event.KeyEvent.VK_D); %// key release event
robot.keyPress (java.awt.event.KeyEvent.VK_I);
robot.keyRelease (java.awt.event.KeyEvent.VK_I);
robot.keyPress (java.awt.event.KeyEvent.VK_R);
robot.keyRelease (java.awt.event.KeyEvent.VK_R);
will type dir onto the command window, exactly as if the user had written it. Then pressing Enter will run the command.
The short answer is no. This can't be done as you want it to. What you are trying to do is to write text to MATLAB's stdin and let it remain there unprocessed. Essentially a modified form of piping.
The closest option available in MATLAB is Evaluate Selection where when you select text you can cause MATLAB to execute it in the command prompt. MATLAB puts this text exactly where you want it but it also immediately executes it. There does not seem to be a way to halt this or emulate its functionality programmatically.
Writing to stdin in MATLAB is not allowed as you can see from
>> fprintf(0, 'help conv')
Error using fprintf
Operation is not implemented for requested file identifier.
where 0 denotes stdin, 1 denotes stdout and 2 denotes stderr. Another naive attempt would be to use fopen()
>> fid = fopen(0, 'w');
Error using fopen
Invalid filename.
but alas this fails too. However, we can see from the first attempt that what you desire
is not implemented
The only option to get exactly what you want is that possibly with some MATLAB hackery the ability is there but I'm not aware of it or anybody who has even attempted it.
EDIT: Luis Mendo has provided the MATLAB hackery solution I was talking about.
The closest you could get to what you want is to use hyperlinks to run MATLAB commands like
>> disp('Did you mean: conv()')
Did you mean: conv()
ans =
12
where conv() is a hyperlink and clicking on it will execute conv(a,b) where a = 3; and b = 4; in this example.

(Matlab) Option to turn pause on and off from output callback of system(string)?

For an aerospace course aerelasticity I am doing an assignment with Nastran in Matlab (by using system(command) and bdf as input file).
I have attached a piece of my code as explanation. In this case the program Nastran produces a punch file (text) with displacements.
Currently the problem is that Matlab disregards the time Nastran needs for analysis to produce this punch file and continues on with the loop, however this punch file is not created yet so matlab turns out an error saying it does not exist and stops the loop.
I "have" a workaround for this by setting the pause times manually found from running it manually for increasing mesh sizes, this gives me at least some data on mesh convergence, however this is not a suitable method to use the rest of the assignment as it will take way too much time, therefore it must be automated.
I was thinking of setting a condition temporarily pausing the loop if the punch file does not exist and turning on again if it exists, however I got stuck with using a pause condition inside a while loop alltogether, it does not seem a solution to me.
Do you have any suggestions / ideas on what I could use / do how to get around this problem
or
know if there is a way to sent a callback from system(nastran) which i can use to create a condition to control the loop or something in that direction?
The following is a piece of code of the created function which turns out the Residual Mean squared error of the mesh which I use to see if the mesh converges:
%% Run Nastran
system('"C:\Users\$$$$\AppData\Roaming\MSC.Software\MSC_Nastran_Student_Edition\2014\Nastran\bin\nastranw.exe" nastranfile.bdf mem=1gb'); % Run the created bdf file
pause(15);
%% Read results and save all relevant results
fpc = fopen('nastranfile.pch','r')
line = 0;
for j=1:6;
line = line+1;
fgets(fpc);
end
line;
counter=0;
data = [];
while ~feof(fpc)
counter= counter+1;
str = fgets(fpc);
line=line+1;
str = str(61:73);
data(counter) = str2num(str)
fgets(fpc);
line=line+1;
end
line;
fclose(fpc);
% Find RMSE
mdl = fitlm(1:length(data),data);
RMEA = mdl.Rsquared.Adjusted;
RMSE = mdl.RMSE;