how to edit simulink plutosdr qpsk example - matlab

I am working with this example from MathWorks: https://www.mathworks.com/help/supportpkg/plutoradio/examples/qpsk-transmitter-with-adalm-pluto-radio-1.html
When i run the example it creates an sdrqpsktx variable in the matlab workspace
I want to change sdrqpsktx.MessageBits to something smaller.
When i run the following code in matlab:
a = sdrqpsktx.MessageBits(1:448);
sdrqpsktx.MessageBits = a;
I successfully change sdrqpsktx.MessageBits to a.
However when i run this in simulink sdrqpsktx.MessageBits changes back to its original size.
How do i permanently change sdrqpsktx.MessageBits and run the example with my changes?
Thank you.

There is a model callback, probably a StartFcn, that is overwriting your changes to the variable every time you start the simulation. You either need to delete or modify that code.
To see the code go to:
File->Model Properties->Model Properties, and select the Callback tab.
Any callback that is followed by a * has code in it. Click on that callback to see the code.
See Callbacks for Customized Models for more detailed information.

Related

Anylogic: Dynamically change source rate using variable/slider

I am trying to dynamically change the source Arrival rate using a variable "arrivalRate" linked to a slider (see image).
However, during the simulation the initial rate remains the same, even when I change the arrivalRate. I know that the arrivalRate variable is changing successfully (it is an int) - but this has no effect on the source rate during the simulation.
Anyone have an idea what the issue is - or how to fix it?
Whenever you see the = sign before a field, it means it's not dynamic, it is only evaluated at the start of the model or at the element creation and will not change throughout the simulation run unless you force it. In other words, the variable arrivalRate is checked only once to assign the source's arrival rate and that's it.
Now if you want to change it dynamically, in the slider's Action field, write the following:
source.set_rate( arrivalRate );

Editing layer via Python script startEditing, do we have to "close" editing?

I'm working on a vector layer where I have to merge all n+i [id] attributes into entity(n)[id] where entities(n+i)[id] equals the entity(n)[id], then delete all n+i entities.
All works fine but I call several times startEditing functions before commiting changes, and my question is: does calling commitChanges closes startEditing, or does it let it opened, like if it was a file descriptor or a pointer which we needed to free after the job's done?
The code is:
olayer.startEditing()
olayer.changeAttributeValue(n,id_obj,id_obj_sum,NULL,True)
olayer.commitChanges()
olayer.startEditing()
i= i-1
while i >=1:
olayer.deleteFeature(n+i)
i=i-1
olayer.commitChanges()
As you can see, we call several times olayer.startEditing, even more because all that code is in while body...
So will that spawn hordes of startEditing "pointers" or will it just continuously set the olayer editable status as "open to edition" ?
Actually the code works, but it's painfully slow, is this the reason why ?
By and large, you should not start the edit mode more than once in your layer.
You can commit at the end of all your changes to the layer, so that your modifications stay in an edit buffer in the meantime.
QgsVectorLayer.commitChanges() can let the edit mode open if you pass a False as parameter (the parameter is called stopEditing, see the docs). Like this:
# If the commit is sucessful, let the edit mode open
layer.commitChanges(False)
Also, have a look at the with edit(layer): syntax in the QGIS docs. Using such syntax you avoid starting/committing/closing the edit mode, QGIS does it for you.
with edit(layer):
# All my layer modifications here
# When this line is reached, my layer modifications are already committed.

Matlab - Easy way to save entire figure/GUI

I'm looking for an easy way too save the current state of my GUI and be able to load this saved state again. I know there is a video for this (http://blogs.mathworks.com/videos/2010/12/10/how-to-save-and-restore-state-of-a-gui-in-matlab/) but somehow it doesn't work on my computer.
I thought of something like this: (I used gcf because I didn't know the "mainhandle" for my entire GUI)
%Save Data
currentdata = getappdata(gcf);
uisave('currentdata',date);
%Load Data
[filename,pathname]=uigetfile({'*.mat'},'Select input file');
load([pathname,filename]);
The problem with this way is, that the saved Data is opened in a new figure and not the current one from which I chose to open it.
I was also wondering if it is possible to set a folder(which is added to the matlab path) as the deault folder for saving/loading.
Thank you for your help! Klaus
Since your currentdata keeps the whole handles of your GUI, including the handle to the GUI's main figure, so when you load it, there will be a new figure opened.
What one did in the mentioned video is: just save the fields/data that you need to be remained/reloaded in later session.
So either you save these specific fields in the GUI's handles and reload them one by one, or you can use the exchange functions mentioned in the comment under the video.

How can I save output from Simulink?

I'm a student learning to use MATLAB. For an assignment, I have to create a simple state machine and collect some results. I'm used to using Verilog/Modelsim, and I'd like to collect data only when the state machine's output changes, which is not necessarily every time/sample period.
Right now I have a model that looks like this:
RequestChart ----> ResponseChart ----> Unit Delay Block --> (Back to RequestChart)
| |
------------------------> Mux --> "To Workspace" Sink Block
I've tried setting the sink block to save as "Array" format, but it only saves 51 values. I've tried setting it to "Timeseries", but it saves tons of zero values.
Can someone give me some suggestions? Like I said, MATLAB is new to me, please let me know if I need to clarify my question or provide more information.
Edit: Here's a screen capture of my model:
Generally Simulink will output a sample at every integration step. If you want to only output data when a particular event occurs -- in this case only when some data changes -- then do the following,
run the output of the state machine into a Detect Change block (from the Logic and Bit Operations library)
run that signal into the trigger port of a Triggered Subsystem.
run the output of the state machine into the data port of the Triggered Subsystem.
inside the triggered subsystem, run the data signal into a To Workspace block.
Data will only be saved at time point that the trigger occurs, i.e. when your data changes.
In your Simulink window, make sure the Relative Tolerance is small so that you can generate many more points in between your start and ending time. Click on the Simulation option at the top of the window, then click on Model Configuration Parameters.
From there, change the Relative Tolerance to something small... like 1e-10. After that, try running your simulation again. You should have a lot more points in your output array that you can now save.

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.