I implemented a few months ago a function that sends data from Matlab to a Weiss WSG50 gripper. This is a Robotic Gripper Tool and uses binary codes as commands. I established a connection with the tcpip function. I wrote my commands and sended them with ´fwrite´ as uint8-data to the gripper. My tcpip object is a client. The gripper a server. The gripper sucessful runs the command perfectly. Until here everthing works as I expected.
The Trouble begins, when I tryied to receive data back from the gripper. The gripper reacts with a awnser message on every sended command (Could be more then one message). But my ´BytesAvailable´ stays empty.
I know that could be diffcult to reproduce, because it may be necessary to have access to the gripper. But eventual I do something basic wrong with setting up the TCPIP object. I tryied already to use ´tcpclient´ but with this function sending is not working also.
%% WORKING PART
%Preparing the gripper
gripper = tcpip('172.16.6.72',1000);
gripper.OutputBufferSize = 3000;
gripper.ByteOrder = 'littleEndian';
gripper.Timeout = 1;
fopen(gripper);
%Command
release = [170; 170; 170; 38; 8; 0; 0; 0; 160; 64; 0; 0; 210; 67; 0; 0];
release = hex2dec(release);
fwrite(gripper, uint8(release), 'uint8');
fclose(gripper);
%% NOT WORKING PART
readdata = fread(gripper,gripper.BytesAvailable);
If ´BytesAvailable´ is empty it absolutly makes sense, that this is not working. No Data no reading. My Question is it a problem with the gripper or am I doing something totally wrong with the tcpip object configuration?
Related
Conceptual question:
How can I query userinput via phone (android) within a matlab script running on a server? What would it take to make this work? Could this be achieved using a COM interface like outlook's?
Thanks
Here's the code I wrote to make this happen, suggestions welcome...
install matlab app then...
%matlab instance #1, run on server
t = tcpip('0.0.0.0', 1234, 'NetworkRole', 'server');
fprintf('server is set up. \n\nwaiting for client to connect... ');
fopen(t);
fprintf('connected.\n')
fprintf('listening for user commands...\n\n');
while true
if t.BytesAvailable>0
data = fread(t,t.BytesAvailable);
if data==1
disp('1')
elseif size(data,1)>1 %parse several integers as strings
switch char(data')
case 'asdf'
disp('do asdf');
% >> at this point any input can be run using 'eval' << %
end
end
else
pause(2); %wait some seconds
end
end
%matlab instance #2, run on same server
%enable mobile app connection
connector on;
(connect then via mobile app, run following code from the mobile console)
try
t = tcpip('localhost',1234);
fclose(t)
fopen(t)
catch
fprintf('connection failed.\n');
return
end
fprintf('connection established.\n')
% send command to server
fwrite(t,'asdf')
I still have problems with Octave. I need to receive large (>10M) images via a web socket connection, process the data and send it back. I work with Octave 4.2.1 in Windows 7, the sockets package is version 1.2.0 and can be found here: https://octave.sourceforge.io/sockets/
Here is the minimal code example:
pkg load sockets;
rcv_sck=socket(AF_INET, SOCK_STREAM, 0);
bind(rcv_sck,12345);
a=listen(rcv_sck,0);
b=accept(rcv_sck);
data = [];
bufflen = 4600;
total = 0;
count = 0;
while (total < 10000)
[buff,count]=recv(b, bufflen);
data = horzcat(data, buff);
total += count;
endwhile
disconnect (b);
disconnect (rcv_sck);
fileID = fopen('data.jpg','w');
fwrite('data.jpg', data);
fclose(fileID);
imshow ('data.jpg')
it can be tested with netcat
ncat.exe 127.0.0.1 12345 < test.jpg
My problem is, that I am not able to receive data bigger than 4608 bytes. If I send more data, the receive array is cut to this size. This is why i choose 4600 bytes as a buffer length. Now I try to put the chunks of small data blocks together to get the correct data.
But this has two serious issues:
1) I have to know the size of the data I am sending, a problem which can be solved by sending the size first as a parameter. In my example i have set the size to 10000 bytes.
2) More important: it is terribly slow. For a jpeg of 170kB it takes 7 seconds to send the data.
Any hints or tipps are greatly appreciated, thank you.
jan
If you want to read data until disconnect I would suggest
data = recv (b, Inf, MSG_WAITALL);
without any loop or horcat. And on your client side (netcat) use -q0:
netcat.exe -q0 localhost 12345 < test.jpg
Btw, if you want to store it on the server side, why don't you use
system ("netcat -l -p 12345 > data.jpg");
in the first place?
Can any body help me out with the problem I am facing while making a tcpip connection with an instrument.Its like when I make a connection with the tcpip address using the following it works perfectly fine for any no of times.
1.test and measurement tool(TMTOOL in matlab)
2.Zoc terminal
3.teraterm.
but when I try to implement the following script its does run but dont know some how doesn't seem to send the command to the pan and tilt unit which I am tryin to control.
I am trying with two scripts:
A.
obj1=tcpip('169.254.32.28',4000);
fopen(obj1);
cmd=5000;
fprintf(obj1,'pp%d',cmd)
fclose(obj1);
delete(obj1);
I am trying to send a command pp5000
B.
%commands
lat=51.57668;
lon=-1.26765;
alti=500;
% Find a tcpip object.
obj1 = instrfind('Type', 'tcpip', 'RemoteHost', '169.254.32.28', 'RemotePort', 4000, 'Tag', '');
% Create the tcpip object if it does not exist
% otherwise use the object that was found.
if isempty(obj1)
obj1 = tcpip('169.254.32.28', 4000);
else
fclose(obj1);
obj1 = obj1(1)
end
% Connect to instrument object, obj1.
fopen(obj1);
i=1;
tic
for i=1:10
% Communicating with instrument object, obj1.
fprintf(obj1, 'gg%f,%f,%f',lat,lon,alti);
i=i+1;
toc
end
fclose(obj1);
delete(obj1);
Desired result:
gg51.57668,-1.26765,500
The second script is just a little bit modified version of the automatic script generated from TMTOOL im matlab
Basically I want to print some commands on the desired object every half a second.
can anyone suggest some alternative or improvement that could be done to achieve the desired results.
I have been unable to execute these scripts and I think it should be correct with whatever small knowledge of matlab I have.I am a new user and I would appreciate if you could help.
Thanks
Salil
You could always use the Java classes (sockets) to pass data back and forth, it how I do it.
File 1:
import java.net.ServerSocket
import java.io.*
server_socket = ServerSocket(4000);
client_socket = server_socket.accept;
out = PrintWriter(client_socket.getOutputStream, true);
in = BufferedReader(InputStreamReader(client_socket.getInputStream));
str = in.readLine(); % Read in data
out.println(data); % send data
File 2:
import java.io.*;
import java.net.*;
server_socket = Socket('localhost', 4000);
in = BufferedReader(InputStreamReader(server_socket.getInputStream));
out = PrintWriter(server_socket.getOutputStream,true);
Get and send input the same way as above. When you're done don't forget to close everything.
out.close();
in.close();
client_socket.close();
server_socket.close();
The MATLAB imread function provides the ability to read an image from a URL. This generally works OK, but occasionally I encounter an image that takes a very long time to respond.
For instance, at the time of posting the following URL appears to just be stuck in a 'connecting...' state for over 5 minutes before finally succeeding.
http://www.hollywoodheadache.com/wp-content/uploads/2007/12/tom-and-julia.jpg
Is there any way I can set a timeout within MATLAB?
Thanks
I don't know how to interrupt imread with a timer object. Besides, I suspect about its possibility. But I may recommend you to check whether you can access to the file first, and then, you get the file. I have written the following function to check the file and internet status:
function flag = does_url_exist(urlName)
url =java.net.URL(urlName);
try
link = openStream(url);
parse = java.io.InputStreamReader(link);
snip = java.io.BufferedReader(parse);
if ~isempty(snip)
flag = 1;
else
flag = 0;
end
catch exception
flag = 0;
end
end
Then it is as follows:
fname = 'http://www.hollywoodheadache.com/wp-content/uploads/2007/12/tom-and-julia.jpg';
if(does_url_exist(fname))
img = imread(fname);
end
Note that for internet connection checking, I took the initial code from this post. Also note that if you are sure that the file exists, it is not efficient to check it again since it increases the running time.
I am trying to create a matlab script (m-file) which shall be controlled by an external VBA script.
The matlab script shall do the same operation every time (even params change, but this is not the matter in this case) for a certain number of loops.
If I see it right, I can use matlab funktions in VBA like this: http://www.mathworks.de/help/techdoc/matlab_external/f135590.html#f133975
My main problem is how to implement the matlab part of this problem...at the moment my control part looks like this:
start.m:
run = 1;
reset = 0;
while run ~= 0 % Loop until external reset of 'run' to '0'
if reset ~= 0
doReset(); % Reset the parameters for the processing
reset = 0;
disp('I did a reset');
end
disp('I am processing');
doProcess();
pause(1)
end
disp('I am done');
The reset part works very fine while changing the value by the script, but when I manually try to change the value of 'run' or 'reset' to any other value in my workspace, nothing happens...my script doen't abort, neither does the reset-if do it's work...
this seems to me that the script doesn't recognize any changes in the workspace?!
later the variables 'run' and 'reset' shall be set or unset by the VBA script.
Is there any plausible reason why I can't abort the loop by hand?
Thanks for any advice!
greets, poeschlorn
Edit:
It seems that the script loads the variables once before starting and never again during runtime...is there a possibility to have explicit access to a workspace variable?
Edit 2:
I use Matlab 2010b with no additional Toolboxes at the moment
Edit 3:
I found out, that there are several 'workspaces' or RAMs in Matlab. If my function is running, the variables are stored in 'base' (?) workspace, which is not the matlab workspace on which you can click and change every value. So I have to get access to this ominous 'base' space and change the flag 'run' to zero.
I assume your problem is simply that your loop is blocking execution of the external interface. While the loop runs you cannot access the other interfaces.
I wanted to do a similar thing -- allow control of a matlab loop by an external program (either Ruby or another matlab instance). The most flexible solution by far was using UDP. There is a great toolbox called PNET for matlab, and I assume VB must have a socket library too. I simply open a UDP port on both sides, and use simple text commands to control and give feedback.
obj.conn = pnet('udpsocket', 9999);
command = '';
while run ~= 0
nBytes = pnet(obj.conn, 'readpacket');
if nBytes > 0
command = pnet(obj.conn, 'read', nBytes, 'string');
end
switch command
case '--reset--'
doReset(); % Reset the parameters for the processing
reset = 0;
disp('I did a reset');
case '--abort--'
run = 0;
disp('Going to abort');
case '--echo--'
pnet(obj.conn, 'write', '--echo--');
pnet(obj.conn, 'writepacket', remoteAddress, remotePort);
end
doProcess();
end
This way I can build my own extensible control interface without worrying about blocking from the loop, it can work cross-platform and cross-language, can work within a machine or across the network.
UPDATE:
To talk between two UDP clients, you need to set up two complimentary UDP ports, both are clients (this example is all in matlab, pretend obj here is a structure, in my case it is a class i wrap around the pnet functionality):
obj = struct();
obj.success = 0;
obj.client1Port = 9999;
obj.client2Port = 9998;
obj.client1Address = '127.0.0.1';
obj.client2Address = '127.0.0.1';
obj.conn1 = pnet('udpsocket', obj.client1Port);
obj.conn2 = pnet('udpsocket', obj.client2Port);
pnet(obj.conn1, 'write', '--echo--')
pnet(obj.conn1, 'writepacket', obj.client2Address, obj.client2Port);
nBytes = pnet(obj.conn2, 'readpacket');
if nBytes > 0
command = pnet(obj.conn2, 'read', nBytes, 'string');
if regexpi(command,'--echo--')
obj.success = obj.success+1;
fprintf('Client 2 recieved this message: %s\n',command);
pnet(obj.conn2, 'write', '--echo--')
pnet(obj.conn2, 'writepacket', obj.client1Address, obj.client1Port);
end
end
nBytes = pnet(obj.conn1, 'readpacket');
if nBytes > 0
command = pnet(obj.conn1, 'read', nBytes, 'string');
if regexpi(command,'--echo--')
obj.success = obj.success+1;
fprintf('Client 1 got this back: %s\n',command);
end
end
if obj.success == 2
fprintf('\nWe both sent and received messages!\n');
end
Is your script a script m-file or a function?
If it's a function, you'll be losing the scope of the workspace variables which is why it's not working. I'd turn your code into a function like this:
function processRun(run,reset)
while run ~= 0 % Loop until external reset of 'run' to '0'
if reset ~= 0
doReset; % Reset the parameters for the processing
reset = 0;
disp('I did a reset');
end
disp('I am processing');
[run,reset] = doProcess;
pause(1)
end
You can then set the values of run and reset evertime you call the function from VBA.
If you have a script, try removing the run and reset lines from the top, and set their values in the workspace before you run the script. I think you're overwriting your workspace values by running the script file.
Sorry, I don't have enough rep to make a comment so I'll quote it here:
#Adam Leadbetter: Thanks, this makes sense. The only thing I habe trouble with is how to pause (after this reset and then resume) the script when it has been started by run=1 as param... – poeschlorn Feb 25 at 7:17
If you want to break out of the loop once reset has been set to one, and then wait for the loop to continue again once run = 1 that is pretty much the same as just starting over again?
function processRun()
run = 1;
while run ~= 1
run = doProcess();
end
if doProcess() returns 0 then the function processRun() will end (like the behaviour you want to have when reset), the next time processRun is called it starts over, with "reset"/default values.
Or am I missing something?