Labels

Linux (6) OpenCV (4) Deep Learning (3) MATLAB (3) Mac OS X (3) Windows (2) C# (1) Node JS (1)

2014年9月14日 星期日

Sending Data through UART USB dongle on Mac OS X

The Universal Asynchronous Receiver/Transmitter (UART) is a hardware that enables data transmission between parallel and serial form. Common UART communication protocols include RS-232RS-422 or RS-485.  I believe engineers who have lived in PC-era have used this cable before:




Today's computer no longer has RS-232 port. Fortunately, UART still exist in our life, just in different form:
This is USB-UART dongle made by FTDI chip. The chip on the board emulates a UART port so we can still use old technology to communicate with new chip, such as TI's Bluetooth Low Energy (BLE) chip CC2540.

So how can we connect to USB-UART? Actually Mac OS X has a command  "Screen". Just open an terminal and follow the steps below:

1. list the USB-UART device:
  $ ls /dev/cu.*                                                              
    /dev/cu.Bluetooth-Modem         /dev/cu.usbserial  
    This command will list the connected devices on your Mac. Our target is usbserial

2. Connect to the device, simple type the "screen" and baud rate:
  $ screen /dev/cu.usbserial 115200  
    The number 115200 is the baud rate used to communicate between two devices

3. To leave the screen, type CTRL-A then CTRL-\ 

Also there are many GUI tool can be used. I recommend using CoolTerm:

A good Coolterm tutorial can be found here:


CoolTerm is written in VB and can also be run on multiple platforms (Windows & Linux), which is a very convenient feature.

2014年8月29日 星期五

Simple Windows UI Automation (Controlling other windows or processes ) by Using AutoIt or C#

Although few people are talking Windows programming nowadays, Windows Automation is still useful. I currently studied several ways to do Windows automation for factory automation or controlling POS (Point-of-Sales). All methods are calling Windows APIs (e.g. FindWindow & SendMessage), but using different wrapper.

The simplest way is to use AutoIt, which is a great wrapper for Windows API. It also has a built-in Window Info Tool:

With a few lines you can write an automation script. For example, we call a notepad window, wait for its show-up, send text to it and then close it without saving:
Run("notepad.exe")
WinWaitActive("Untitled - Notepad")
Send("This is some text.")
WinClose("Untitled - Notepad")
WinWaitActive("Notepad", "Do you want to save");
Send("!n")  //Alt-n to quit notepad without saving 


Although we can totally build an application by using AutoIt, most of the time we still want to control other Windows through our own program. Here is an example in C#.

IntPtr hWnd = IntPtr.Zero;
foreach (Process pList in Process.GetProcesses())
{
    if (pList.MainWindowTitle.Contains(wName))
        hWnd = pList.MainWindowHandle;
}
return hWnd; //Note: may be zero if can't find a matched title

Or we can call Windows API directly in C#. For wait for Window Active, we can use a timer to find window periodically:
[DllImport("user32.dll", EntryPoint = "FindWindowEx")]
    public static extern IntPtr FindWindowEx(IntPtr hwndParent, IntPtr hwndChildAfter, string lpszClass, string lpszWindow);
[DllImport("User32.dll")]
    public static extern int SendMessage(IntPtr hWnd, int uMsg, int wParam, string lParam);
    
private void timer1_tick(object sender, EventArgs e)
{
    Process [] notepads = Process.GetProcessesByName("notepad");
    if(notepads.Length==0) return; else timer1.enabled=false;           
    if (notepads[0] != null)
    {
        IntPtr child = FindWindowEx(notepads[0].MainWindowHandle, new IntPtr(0), "Edit", null);
        SendMessage(child, 0x000C, 0, textBox1.Text);
    }
}
For program like Notepad, it's better to find process first, because the title of window is changed by it's content.

There is a great Windows message APIs wrapper for using WM_DATACOPY called MessageHelper :
https://gist.github.com/BoyCook/5075907

More advanced UI automation tricks can be found in:
UI Automation Clients for Managed Code

One important application of Windows Automation is to send inputs (keys or mouse clicks) to background Windows. However, I didn't found an effective way to do this task. SendMessage or PeekMessage not always work. The current method I am using is to set my application on top, call "SetForegroundWindow" and "SendKeys". For mouse clicks, I'm still looking for effective method.

// import the function in your class
[DllImport ("User32.dll")]
static extern int SetForegroundWindow(IntPtr point);

// Find the target process and send keys

Process p = Process.GetProcessesByName("notepad").FirstOrDefault();
if (p != null)
{
    IntPtr h = p.MainWindowHandle;
    SetForegroundWindow(h);
    SendKeys.Send("{F1}");
    SendKeys.SendWait("{Enter}");
}

2014年8月26日 星期二

Using HTTP basicAuth, bodyParser, cookieParser and other modules in ExpressJS 4.0

ExpressJS 4.0 removes all middlewares and make them independent packages. Therefore we cannot use ExpressJS 3.0 code directly. For basicAuth, some people implement their own version of HTTP basic authentication. But I think the easiest way is to use npm to install "basic-auth-connect" module:

var basicAuth = require('basic-auth-connect');
app.use(basicAuth('username', 'password'));

Follow the same rule, just install the necessary modules then we can use the old 3.0 codes! But the names of the new modules are different from original ones. The complete mapping table is as below (thanks to  Chris Sevilleja):

Express 3.0 NameExpress 4.0 Name
bodyParserbody-parser
compresscompression
cookieSessioncookie-session
loggermorgan
cookieParsercookie-parser
sessionexpress-session
faviconstatic-favicon
response-timeresponse-time
error-handlererrorhandler
method-overridemethod-override
timeoutconnect-timeout
vhostvhost
csrfcsurf

2014年7月26日 星期六

Configure MATLAB MEX compiler on OSX by Using clang/clang++

The MATLAB mex cannot be directly run on OSX, due to the Apple's proprietary C/C++ compiler. Therefore we need to modify mex config file. There are many ways to achieve this. My steps are as following:

1. Run "mex -setup" in MATLAB, you will see the options:

The options files available for mex are:
 1: /Applications/MATLAB_R2010a.app/bin/gccopts.sh : 
      Template Options file for building gcc MEX-files
 
  2: /Applications/MATLAB_R2010a.app/bin/mexopts.sh : 
      Template Options file for building MEX-files via the system ANSI compiler'



2.  Select "mexopts.sh" as template. MATLAB will create a copy at your home folder:
"~/MATLAB/R2011b/mexopts.h"

3. Open "~/MATLAB/R2011b/mexopts.h" and find string "maci64", change CC='gcc' to CC='clang', and CXX='g++' to CXX='clang++':


4. MATLAB MEX will complain that  "error: unknown type name 'char16_t' typedef char16_t CHAR16_T;". To solve this issue, add the definition in preprocessor flag "-Dchar16_t=uint16_T" :

COPTIMFLAGS='-O2 -DNDEBUG -Dchar16_t=uint16_T'


4. Restart MATLAB, MEX should work fine!

2014年6月3日 星期二

Fix vncserver error "code=exited, status=2/INVALIDARGUMENT" on Fedora

Sometimes if you didn't shutdown your Fedora server cleanly, you will encounter the following error when restarting vncserver:

vncserver.service - LSB: start|stop|restart|try-restart|status|force-reload vncserver
  Loaded: loaded (/etc/rc.d/init.d/vncserver)
  Active: failed since Tue, 03 Jun 2014 11:08:08 -0400; 2h 14min ago
Process: 2145 ExecStart=/etc/rc.d/init.d/vncserver start (code=exited, status=2/INVALIDARGUMENT)

  CGroup: name=systemd:/system/vncserver.service

To solve this issue, just go to  /tmp/.X11-unix and remove directories X[1-9]. Don't remove X0, that's your console session. You will be cool again!

2013年12月29日 星期日

Setup VNC server on Fedora

The VNC server can support multi-user desktops and is very useful for Linux system (On Windows I prefer to use Teamviewer). There is a great tutorial written by Jack Wallen. However on Fedora there is minor difference on setting up firewall. The steps of setting up VNC server on Fedora is listed below:

1. Install VNC server
yum -y install tigervnc-server


2. Add VNC user
su vncuser1
vncpasswd


3. Edit VNC config file
sudo vim /etc/sysconfig/vncservers
add the following lines:
VNCSERVERS="1:vncuser1 2:vncuser2 "
VNCSERVERARGS[1]="-geometry 1800x1200"
VNCSERVERARGS[1]="-geometry 1440x960"


4. Start VNC server
sudo service vncserver start


5. Enable firewall port 5901 by running config (Note editing iptable doesn't work on Fedora). Remember to add port 5902 for second user.
sudo system-config-firewall


6. Connect with VNC viewer (I use Mac version). Remember to add :1 after your IP address!








2013年7月14日 星期日

Using LIBSVM with OpenCV Mat


  LIBSVM is the most popular machine learning tool developed by C. J. Lin at National Taiwan University (http://www.csie.ntu.edu.tw/~cjlin/libsvm/). This code demonstrates how to load a data matrix in CSV format using OpenCV, and allocates LIBSVM data structure to do SVM predict. 


#include "svm.h"
#include <iostream>

#include "opencv2/opencv.hpp"
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/ml/ml.hpp"
#include <iostream>

using namespace cv;
using namespace std;


const char *CSV_FILE = "/Users/kuanting/libsvm-3.17/heart_scale.csv";
const char *MODEL_FILE = "/Users/kuanting/libsvm-3.17/heart_scale.model";

int main(int argc, char * argv[])
{
    CvMLData dataFile;
    
    // Load matrix data in csv format
    if (dataFile.read_csv(CSV_FILE) != 0)
    {
        fprintf(stderr, "Can't read csv file %s\n", CSV_FILE);
        return -1;
    }
    
    Mat dataMat(dataFile.get_values()); // Default data type is float
    
    struct svm_model *SVMModel;
    if ((SVMModel = svm_load_model(MODEL_FILE)) == 0) {
        fprintf(stderr, "Can't load SVM model %s", MODEL_FILE);
        return -2;
    }
    
    struct svm_node *svmVec;
    svmVec = (struct svm_node *)malloc((dataMat.cols+1)*sizeof(struct svm_node));
    double *predictions = new double[dataMat.rows];
    float *dataPtr = dataMat.ptr<float>(); // Get data from OpenCV Mat
    double prob_est[2];  // Probability estimation
    int r, c;
    for (r=0; r<dataMat.rows; r++)
    {
        for (c=0; c<dataMat.cols; c++)
        {
            svmVec[c].index = c+1// Index starts from 1; Pre-computed kernel starts from 0
            svmVec[c].value = dataPtr[r*dataMat.cols + c];
        }
        svmVec[c].index = -1;   // End of line
        
        if(svm_check_probability_model(SVMModel))
        {
            predictions[r] = svm_predict_probability(SVMModel, svmVec, prob_est);
            printf("%f\t%f\t%f\n", predictions[r], prob_est[0], prob_est[1]);
        }
        else
        {
            predictions[r] = svm_predict(SVMModel, svmVec);
            printf("%f\n", predictions[r]);
        }
    }
    
    return 0;
}