Matlab GPIB - how to read Message AVailable from Status Byte Register? - matlab

as the title says...
I want to check the SBR register of device connected over GPIB. I am interested in reading the MAV bit 4, which should be set if instrument has something it would like to send me.
The problem is, that in order to check the SBR, I inevitably have to send another query (*STB?), which clears the device output buffer by default. In other words, whenever I check if there is something to read, I remove it just by looking. Here is code to reproduce it, problem is at the last call to fscanf():
>> fid = gpib('agilent', 7, 26);
>> fopen(fid)
>> fprintf(fid, '*SRE 255; *SRE?') % Enable everything in SBR
>> fscanf(fid) % Returns +191 as expected (255 - 64 for MSS)
>> fprintf(fid, '*IDN?') % Make any query...
>> fprintf(fid, '*STB?') % Read SBR
% The line above generates device Query Error (beep)
>> fscanf(fid) % << Returns +0 !!!
>> fclose(fid) % Just to prevent flames :]
I suspect, that there is some way to check the SBR without querying the device, but I could not find anything. MATLAB help for VISA drivers is silent on the topic of communicating directly with the driver or the bus.
I also tried to check for BusManagementStatus with no avail.
For reference, I am using MATLAB R2011b, with 32-bit Agilent VISA drivers, and the GPIB enabled device is Agilent E4980A LCR Meter. Thanks for any help.

OK, I think that I figured it out. Please correct me if I am wrong...
First of all I need to anticipate the need to check for available message, because in my solution I won't be able to check for Error Queue, Master Summary, and other bits, that are set in SBR.
Then, before my actual commands (that may produce some output), I need to mask the Service Request Enable Register (SRER) to only allow MAV bit. Thats done like so (following from example in question):
>> fprintf(fid, '*SRE 16');
>> fprintf(fid, '...ACTUAL COMMANDS THAT ARE TO BE EXECUTED...');
Now I can check, whether the device sends a service request, using the aforementioned BusManagementStatus command. The following command returns true iff there is MAV bit set in SBR.
>> strcmp(fid.BusManagementStatus.ServiceRequest, 'on')
The disadvantage is that there is no way to check for errors during my ACTUAL COMMANDS execution. If I do so, it might produce errors... :]

Related

Sensoray 826 cards driver problems with MATLAB

this is my first topic if anything wrong please advise me.
I am not a great matlab user but I need to use matlab with sensoray 826 to capture the data.
However, once I install the driver and try to run 826 Matlab demo I got the error code below.
Warning: Warnings messages were produced while parsing. Check the functions you intend to use for correctness. Warning text can be viewed using:
[notfound,warnings]=loadlibrary(...)
I try to find the root cause of this problem and get new error.
[notfound, warnings] = loadlibrary('C:\Program Files (x86)\Sensoray\826\API\x64\s826.dll')
Error using loadlibrary
There was an error loading the library "C:\Program Files (x86)\Sensoray\826\API\x64\s826.dll"
Unrecognized function or variable 's826_proto'.
Caused by:
Error using feval
Unrecognized function or variable 's826_proto'.
At this point I believe that the error is cause from incorrect DLL file from the sensoray.
I try to contact the Sensoray but they rarely answer back to me.
If anyone know how to solve this issue please kindly reply back to me.
The code I use to run in Matlab:
% Load the 826 API and open a connection to the 826 board
dllPath = 'C:\Program Files (x86)\Sensoray\826\API\x64\s826.dll'; % Replace with the correct path to the DLL file
hdrPath = 'C:\Program Files (x86)\Sensoray\826\API\826api.h'; % Replace with the correct path to the header file
[errcode, boardflags] = s826.SystemOpen(dllPath, hdrPath);
if errcode ~= 0
error('Error opening connection to 826 board: %d', errcode);
end
% Configure the rotary sensor
counter = 0; % Choose the counter that the rotary sensor is connected to (0-3)
s826.CounterModeWrite(counter, s826.CNTR_QUADX4); % Configure the counter for quadrature input
s826.CounterPreloadWrite(counter, 0, 0); % Reset the counter
% Read the counter value
count = s826.CounterRead(counter);
% Close the connection to the 826 board
s826.SystemClose();
I would like to go step by step since I never use this 826 cards before.
So first just correctly call the DLL and H file is enough for me.

Displaying Data as a String in Simulink RT Display Port

My issue involves using the RS-232 Simulink RT blocks.
A model is uploaded to the target PC (xPC) and it transmits and receives data from a variable frequency drive (VFD) that controls a motor. The issue arises on the receiving end when I take data and try to send that data to a display block in my model as a string. Code would be helpful here:
disp = uint8(zeros(1,24));
display = uint8(zeros(1,length(disp)));
cmd = 0;
status = stat_lb;
%% Start-Up
% Initialization Period
if (status == 0 || status == 1)
cmd = 0;
msg = uint8('Start up');
display = [msg uint8(zeros( 1, length(disp)- length(msg) ))];
end
...
%Multiple status cases with unique displays.
...
disp = display
So, here the cmd portion functions as expected. As noted above, I want to display the display string on a display block in my Simulink model. As you can see, though, it is of type uint8, so I need to convert it to type string; however, when I pass it through either the ascii2str Simulink block or just place it in the function call (e.g. display = ascii2str(display)) I get the following error message:
Executing the 'CheckData' command produced the following error: Invalid parameter/value pair arguments
My thought is that this has something to do with the fact that I am using MEX and this function (ascii2str) is not supported. Anyways, I am wondering if anyone knows why I receive this error and if there is anything I can do to resolve it.
Oh, and one last thing: I can get the display to work if I just remove the ascii2str; however, the only problem with this is that the display is in uint8 form and not really helpful. So, if there is any other way that I can decode the uint8 to a string I am all ears.
Thanks!
I have found that there is no support for this feature in Simulink RT. One option is to use external functions, but I found it better for my application to simply output a number and have a table in the simulation that explained what each number meant.

how to query userinput via phone, within matlab

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')

How to send SMS messages in Matlab by using AT commands? Not using email gateways

Problems:
I am able to use hyperterminal to send SMS via COM9. All good.
But I cannot properly use AT commands in matlab to do the same thing. I even cannot pass the first "AT" step. The error I received is "Unexpected Error: Unexpected Error: An error occurred during writing." It seems coming from fprintf. Help!
Here is the codes:
try
s = serial('COM9','BaudRate',9600);
fopen(s);
tx='AT';
tx1=char(13);
tx2=char(10);
fprintf(s, '%s', sprintf('%s%s%s', tx, tx1, tx2));
out = fscanf(s);
disp(out);
fclose(s);
catch aException
fclose(s);
error(message('MATLAB:serial:fprintf:opfailed', aException.message));
You have done the serial communication part properly. In AT command set, to check the working of the device it's enough if you send 'AT' and a line feed. Also you gave both carriage return and line feed to the device simultaneously. That could create a problem. Also while writing MATLAB code for the first time, try sending the characters individually as you do in Hyperterminal. It will solve your problem.
There will be no problem from MATLAB's perspective when the communication link is created successfully.

Continuously acquire data in MATLAB using callbacks and persistent variables

I have just recently started to use MATLAB to acquire data off of a data acquisition board and was in need of a function to acquire data continuously (i.e. until I ctrl^C out of the function). To do this I am using the data acquisition toolbox on a 32-bit windows OS.
Based on the documentation in matlab help and a few of the answers on this site, I found that after adding channels to my input handle I should:
set my 'SamplesPerTrigger' to Inf
set the 'TimerPeriod' to some value to trigger the 'TimerFcn'
set the 'TimerFcn' to some subfunction callback which appends data to a persistent variable
Is this a correct way to do this?
My code is as follows:
function acquire_arena_test(samprate,daq_device ,device_ID ,channels, saveroot)
setup.SampleRate = samprate;
setup.DAQdevice = {daq_device, device_ID};
setup.AIChannels = channels;
setup.SaveRoot = {saveroot};
ai = analoginput(setup.DAQdevice{1},setup.DAQdevice{2});
addchannel(ai,[setup.AIChannels]);
set(ai,'SamplesPerTrigger',Inf);
set(ai,'TimerPeriod',0.5);
set(ai,'TimerFcn',{#AcquireData,ai});
start(ai);
while(strcmpi(get(ai,'Running'),'On'))
pause(1)
end
stop(ai);
time = datestr(now,30);
save([saveroot time], 'data');
delete(ai);
clear ai;
function AcquireData(hObject, ~)
persistent totalData;
data = getdata(hObject);
if isempty(totalData)
totalData =data;
else
totalData = [totalData; data];
end
The initial analog input is definitely working properly. I have tried many permutations of giving the AcquireData callback to 'TimerFcn'. The error I receive is
`??? Error using ==> acquire_arena_test>AcquireData
Too many input arguments.
Warning: The TimerFcn callback is being disabled.
To enable the callback, set the TimerFcn property. `
Thanks in advance for any help.
I think the syntax you use for setting up your TimerFcn is wrong. You write
set(ai,'TimerFcn',{#AcquireData,ai});
but this means that your function AcquireData will be called with tree parameters: AcquireData(ai, event, ai) as explained here, which then of course triggers the error message since your AcquireData function only accepts two parameters. Just change your code to
set(ai,'TimerFcn',#AcquireData);
and it should work; the ai object is automatically passed as the first parameter (see the link to the MATLAB documentation above).
Sorry about answering my own question, but I figured it out. The trigger was not needed after all. Using a national instruments board (or a sound card, as it turns out) you can just change the LoggingMode to 'disk' and specify a file to save the .daq (data acquisition toolbox) file to save as with LogFileName. If you want to use the memory on your board, change the mode to disk&Memory. Helpful document:
http://www.mathworks.com/help/toolbox/daq/f12-16658.html
The script below acquires data during the pause, which is as long as you want it to be..
daqreset;
clear all;
ai = analoginput('nidaq','Dev1');
chans = addchannel(ai,0:6);
set(ai,'SamplesPerTrigger',Inf);
set(ai,'SampleRate',1000)
set(ai,'LogToDiskMode','Overwrite')
set(ai,'LogFileName','log.daq')
set(ai,'LoggingMode', 'disk')
start(ai)
pause()
stop(ai)
data = daqread('log.daq');
delete(ai);
Note that you still need to set 'SamplesPerTrigger' to Inf for this to work properly. Thank you to Jonas for his help as well.