Sunday, August 17, 2014

MATLAB SFTP with WinSCP

One of the ways to transfer files using SFTP in MATLAB (sort of) is simply to do it in an external tool (e.g., WinSCP). Assuming the tool supports scripting (WinSCP's scripting), you can prepare the scripts first and simply call the tool using the ! command with the path to the script file. A few thoughts: 1. put it in a timer function to automate the transfer 2. dynamically generate the script so that actions can vary in each session 3. wonder if the session can be maintained in which case we could provide some sort of interactivity in MATLAB's command window.

Saturday, May 3, 2014

MATLAB MySQL query datetime column type

When you do a SELECT * in MySQL query from MATLAB, you would expect all the entries in the table to be returned.

Apparently, there are cases where it will not return everything. (Matlab R2013a, MySQL 5.5.32)

It seems that if you have '0000-00-00 00:00:00' in the datetime field of a row, which is the zero value of the datetime type, the row will not be returned even if you do the select all query.

However, if you are querying other columns (besides the datatime column), the row that has the zero value datetime will be returned.



Tuesday, April 15, 2014

moving things to github

I am in the process of moving some of the source code from the past postings into github. It is easier to share, easier to maintain, and easier to get feedback (if any).

https://github.com/weishang

As a side-note/rant, if you look at the source control options for Matlab, I don't know, it feels lacking. With all the options available nowadays (2014), Matlab supports MS visual sourcesafe, whose final version is 2005.


Saturday, February 1, 2014

Multi-'screen' MATLAB GUI

Once again, I had little time cleaning up the post so read at your own risk. :-) 

Why bother?


First and foremost, the multi-screen GUI I am talking about is much like a Single Page Application (SPA) in the context of web application. Everything you see in the GUI can change entirely as you 'navigate' from "screen" to "screen". An example would be an application that has various stages to it, as the user goes from stage to stage, only the relevant information/controls will show on the GUI. Of course, you can always just slap everything on the GUI without considering splitting them into "screens", but you only have so much space on the GUI and every bit of information that shouldn't be there is wasting the UI space.

<begin digression>
Also, one can also implement the application using multiple GUIs instead of multiple screens. Such approach is more appropriate in the case where the different GUIs have to be shown at the same time, but there are distinct features about each GUI so it doesn’t really make sense to put them all in the same GUI, also, reusability is another issue. But that’s a different topic altogether.
<end digression>

Enough background. Below is how.

First of all, there is no such feature (multiple-screen GUI) in Matlab, but there is a little trick we can use to make it appear so, and that is with the use of 'uipanel'.

The concept is fairly simple, assuming you have already got a design in mind, i.e., you are clear about what uicontrols go into to what uipanel, all you need to do is have them populated in the right panels, subsequently, we show and hide the panels as we see fit. Note that the panels should have been resized at this point so they overlap completely, and at any given time, only one panel should be shown (Visible = 'on'), while others are hidden (isVisible = 'off'). (I don't understand why 'on'/'off' are used instead of true/false or 1/0.)

Now, I would strongly recommended creating everything programmatically instead of relying on Matlab’s GUIDE, as the panel will need to be resized, moved around, which is impossible to do in GUIDE. You also need to pay special attention to the unit setting for all the uicontrols when you are doing this, if there is any mis-matches or invalid values, then the uicontrols may not show up, or when you resize the GUI, the uicontrols in a panel may all go crazy.
Below is the link to a fairly simple demo that shows the multi-screen in action of the application. Three buttons to show one of the three panels (much like the tab effect if you just position them in a better way).
https://github.com/weishang/matlab-multiScreen

What else?


The trick described in this post is using overlapping panels as screens and show/hide the panels as you desired. Here’s what else you can do with this trick.
  • A demo application which goes from one screen to the next, much like a slide show. With the help of the timer object (may find this post useful). 
  • A GUI with the ‘tab’ effect 
  • A fully blown single page application 
  • ...

Saturday, August 31, 2013

MATLAB GUI and Timer Object

I shouldn't really started this post at all since I have little time to 'beautify' the post, but what's described in this post can be very useful for someone that needs to have the GUI update itself at a fixed time interval, say, plotting the latest forecast data. Note that it doesn't have to be a fixed timer interval, in fact if you put enough thought into this, the schedule for the updates can be very flexible (by using database, etc).

Be warned though, the quality of the post is lacking, but I will make sure the sample application is running as expected so all you need to do is to expand on it and plug in all the pieces you need/have.

If you are not familiar with MATLAB GUI, you should read up on it (and unfortunately this post is probably not for you). If you are fairly familiar with MATLAB GUI, but haven't used  the timer object much. Here is the documentation, it is best if you try out a few examples that uses timer object without the GUI, just to get a feel for it.

Now, without further ado, below is a walk through of creating a MATLAB GUI-based digital clock (from scratch).

1. Type GUIDE in matlab, and choose to create a blank gui.

2. Create a static text on the GUI, make it and its fontsize big, and tag it as lbl_timeNow

3. Save the GUI (with the name, say, myClock), and open up its m-file.

4. In the OpeningFcn (prefixed with whatever name), insert the following code

timer_obj = timer(...
    'StartFcn',         @user_timer_start, ...              % start function
    'TimerFcn',         {@user_timer_update, hObject}, ...  % timer function, has to specific the handle to the GUI,
    'StopFcn',          @user_timer_stop, ...               % stop function
    'ErrorFcn',         @user_timer_err, ...                % error function
    'ExecutionMode',    'fixedRate', ...                    %
    'Period',           0.1, ...                           % updates every xx seconds
    'TasksToExecute',   inf, ...
    'BusyMode',         'drop');


start(timer_obj);        % start the timer object

setappdata(hObject, 'timer_obj', timer_obj');  % save the timer object as app data

Effectively, we just created and started a timer whose TimerFcn gets executed every 0.1 second. And the timer is saved as the app data so when we try to close the GUI, we can easily get our hands on the timer and get rid of it at the same time. 

5. Implement the user_timer_update function (which is set as the TimerFcn of the timer). Insert the following function to the m file. Notice how it has three input parameters, the last of which was past in in step 5 with '{@user_timer_update, hObject},'.

function user_timer_update(src,evt, fig_handle)

handles = guihandles(
fig_handle);

set(handles.lbl_timeNow, 'string', datestr(now, 'yyyy-mm-dd HH:MM:SS'));


6. Put in the other timer functions, StartFcn, StopFcn, ErrorFcn into the m file. They are just dump text printer for now. 

function user_timer_start(src, evt)
disp('Timer started!');

function user_timer_stop(src, evt)
disp('Timer stop');

function user_timer_err(src, evt)
disp('Timer error');


7.  We are almost done, just need to make sure the timer is removed when we close the GUI. So go to the GUIDE editor, and select 'CloseRequestFcn' property of the figure, it should populate the function in the m file for you. Now, before delete(hObject), put in

stop(getappdata(hObject, 'timer_obj')); % stops the timer 
delete(getappdata(hObject, 'timer_obj'));  % delete the timer object 

8. Now, here is a list of things that you may want to do: 

  • make the gui look pretty 
  • properly implement the other timer functions, StartFcn, StopFcn, etc. 


Here is what it looks like and here are .fig and .m files. 



Well. That's all for now. Good luck. 

Saturday, July 27, 2013

Connecting to (local) MySQL database in MATLAB

If you try to connect to a local MySQL database based on the Matlab documentation on the database function (see connection example here), you are likely to get the 'Unable to find JDBC driver' error. 

To fix the error, first download the JDBC driver from MySQL website. 


Once download, unzip and find the mysql-connector-java-5.0.8-bin.jar (or more current version) file and move it to Matlab's java path ($matlabroot\java\jar\). 

Next, type prefdir in MATLAB and find your preferences folder, once in that folder, create a text file called javaclasspath.txt, and place the $matlabroot\java\jar\name_of_the_jar_file in and save the file, restart Matlab.

Now if you type javalclasspath, you should see the jar file appear at the bottom of the static path.

Finally, to test out if everything works as expected, run 

conn = database('mysql', 'root', 'DB_password', 'com.mysql.jdbc.Driver',  'jdbc:mysql://localhost/');

conn

tables(conn)


close(conn);

* May need to adjust database name, user account, password, driver name, and url of the database. 


Saturday, June 22, 2013

MATLAB Database Toolbox + MS Access + Date Comparison Problem

I was trying to get a date comparison into a simple select statement.

query = 'select * from telemetry where measured_at < `06/06/2012 11:25:00 AM`;';

I kept getting this "super" informative error message.

Error using database/fetch (line 37)
[Microsoft][ODBC Microsoft Access Driver] Too few parameters. Expected 1.

Error in get_DB_conn (line 17)
x = fetch(conn, query);

"Too few parameters". Hmm, I thought I called the function the wrong way. Then again, where statement with other fields worked just fine. Took me sometime to figure out this is a formatting issue. Apparently, I need to place 'special markers' around the date so that it knows it is a date. doh!

Changed to

query = 'select * from telemetry where measured_at < #06/06/2012 11:25:00 AM#;';

and it works fine now.

Maybe it is nice to have this piece of information emphasized somewhere in the documentation?