0

I created an interface which automatically reads in data through the serial port, hence the reason I implemented the BytesAvailableFcn Callback

handles.fileID.BytesAvailableFcnMode = 'terminator';
handles.fileID.BytesAvailableFcn = {@streamData_fastTrak, handles};

The data that is read is displayed in a table chosen by the user (through use of radio buttons in the GUI). When an option is chosen a callback occurs to save the selected radio button to a variable which is saved in the handles struct. I have followed the program step for step and I am sure this callback does occur and that the variable is saved. However when the serial callback occurs the handles struct still has the old option value.

Here is the serial callback code:

function handles = streamData_fastTrak(hObject, eventdata, handles)

handles.num = handles.num + 1;

%receive data through serial
line = transpose(fscanf(handles.fileID, ' %f ' ));
table_data = get(handles.uitable1, 'data');
table_data_style = get(handles.uitable4, 'data');

display(handles.butt_state);
display(handles.num);

if(fix(line(1)) == 1 && strcmp(handles.butt_state, 'style_button'))

    table_data_style(handles.select_Indices(1), 2:(length(line)+1)) = num2cell(line);
    set(handles.uitable4, 'data', table_data_style);
    display(handles.select_Indices);

elseif(fix(line(1)) > 1 && strcmp(handles.butt_state, 'stat_button'))

    table_data(line(1)-1, 1:length(line)) = num2cell(line);
    set(handles.uitable1, 'data', table_data);

    if(line(1) == countStates(handles))
        streamSensor_1_2_3(hObject, handles);
        handles.time_step = handles.time_step + 1;
    end
end

And the radio button callback:

function uipanel2_SelectionChangeFcn(hObject, eventdata, handles)

handles.butt_state =  get(get(handles.uipanel2,'SelectedObject'), 'tag');
display(handles.butt_state);
guidata(hObject, handles);

2 Answers2

0

The way I see it there are 2 ways to approach the problem:

The first way (I don't recommend this as much as the second one) is to pass the data you want updates to a string control and have it read back by your serial port function.

The other way that i recommend is to include a dummy button with a call back that calls

handles.fileID.BytesAvailableFcn = {@streamData_fastTrak, handles};

Again - this will update the new "handles" data to the callback function

For example

Assuming a dummy push button with tag PB1

function handles = streamData_fastTrak(hObject, eventdata, handles)

%% do stuff here

%% update handles data

PB1_Callback (handles.PB1,event,dat)

guidata(handles.PB1,handles) %% function ends


%% dummy button callback function%%
function PB1_Callback(hObject,event,handles)

handles.fileID.BytesAvailableFcn = {@streamData_fastTrak, handles};

guidata(hObject,handles) %% dummy button function ends

You can make the dummy button invisible by making the background color of the button same as that of the UI.

Nate Barbettini
  • 51,256
  • 26
  • 134
  • 147
  • Thanks for your answer! You should try to format the parts of your answer that are code so make it easier to read. Any line with 4 spaces preceding text will be considered a line of code, or alternatively you can inline some code `like this` by surrounding the text with _backtick_ `. You can read more about formatting here: http://stackoverflow.com/help/formatting – Tas Aug 18 '15 at 22:58
0

When you first declare your callback function for the ByteAvailableFcn in the line:

handles.fileID.BytesAvailableFcn = {@streamData_fastTrak, handles};

Matlab assign the function handle to the event and also pass the handles stucture at this point of time. This is now frozen into the private workspace of the callback. If you change the handles structure later on in your code (as you do when you try to attach the variable handles.butt_state), the callback doesn't know it, it still use the handles structure that was passed when you declared the callback.


There are several ways of getting this value correctly but I'll give 2 of them:

1) get the value from the radio button when needed

in your streamData_fastTrak callback function, query the button state directly from the uicontrol (instead of checking for a saved value)

handles.butt_state =  get(get(handles.uipanel2,'SelectedObject'), 'tag');

This way you are sure to get the latest state of the radio button.


2) Store value in appdata

Every time the button state is changed, store the value somewhere, but you still have to query this value when your callback want to execute. A good place to save values are in the appdata (accessed using setappdata and getappdata). So in your button callback:

function uipanel2_SelectionChangeFcn(hObject, eventdata, handles)
   butt_state =  get(get(handles.uipanel2,'SelectedObject'), 'tag');
   setappdata(handles.uipanel2, 'butt_state' , butt_state );
   display(butt_state);

And in your streamData_fastTrak callback:

function handles = streamData_fastTrak(hObject, eventdata, handles)
   butt_state = getappdata(handles.uipanel2, 'butt_state' );
   %// and the rest of your code ...
Hoki
  • 11,637
  • 1
  • 24
  • 43