S/w.H/w.info.Projects.
SHiP 블로그에서 IT정보를~
2010년 10월 10일 일요일
[매트랩] 이미지 처리 - 2
[매트랩] 이미지 처리 - 1
2010년 6월 3일 목요일
Serial Port MFC
// SerialDlg.cpp : implementation file
//
#include "stdafx.h"
#include "Serial.h"
#include "SerialDlg.h"
#include "comm.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#endif
// CAboutDlg dialog used for App About
class CAboutDlg : public CDialog
{
public:
CAboutDlg();
// Dialog Data
enum { IDD = IDD_ABOUTBOX };
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
// Implementation
protected:
DECLARE_MESSAGE_MAP()
};
CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD)
{
}
void CAboutDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
}
BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)
END_MESSAGE_MAP()
// CSerialDlg dialog
CSerialDlg::CSerialDlg(CWnd* pParent /*=NULL*/)
: CDialog(CSerialDlg::IDD, pParent)
{
m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}
void CSerialDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
DDX_Text(pDX, IDC_EDIT1, m_EditData);
DDX_CBIndex(pDX, IDC_PORT, m_nSettingPort);
DDX_CBIndex(pDX, IDC_BAUDRATE, m_nSettingBaud);
}
BEGIN_MESSAGE_MAP(CSerialDlg, CDialog)
ON_WM_SYSCOMMAND()
ON_WM_PAINT()
ON_WM_QUERYDRAGICON()
//}}AFX_MSG_MAP
ON_BN_CLICKED(IDC_CHECK_COMM, &CSerialDlg::OnBnClickedCheckComm)
ON_BN_CLICKED(IDOK, &CSerialDlg::OnBnClickedOk)
ON_BN_CLICKED(IDCANCEL, &CSerialDlg::OnBnClickedCancel)
ON_MESSAGE(WM_RECEIVEDATA,OnReceiveData)
END_MESSAGE_MAP()
// CSerialDlg message handlers
BOOL CSerialDlg::OnInitDialog()
{
CDialog::OnInitDialog();
// Add "About..." menu item to system menu.
// IDM_ABOUTBOX must be in the system command range.
ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
ASSERT(IDM_ABOUTBOX < 0xF000);
CMenu* pSysMenu = GetSystemMenu(FALSE);
if (pSysMenu != NULL)
{
CString strAboutMenu;
strAboutMenu.LoadString(IDS_ABOUTBOX);
if (!strAboutMenu.IsEmpty())
{
pSysMenu->AppendMenu(MF_SEPARATOR);
pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
}
}
// Set the icon for this dialog. The framework does this automatically
// when the application's main window is not a dialog
SetIcon(m_hIcon, TRUE); // Set big icon
SetIcon(m_hIcon, FALSE); // Set small icon
// TODO: Add extra initialization here
//for(int i=0; i<2; i++){
m_Comm.SetHwnd(this->m_hWnd);
LoadSettings();
//}
UpdateData(FALSE);
return TRUE; // return TRUE unless you set the focus to a control
}
void CSerialDlg::OnSysCommand(UINT nID, LPARAM lParam)
{
if ((nID & 0xFFF0) == IDM_ABOUTBOX)
{
CAboutDlg dlgAbout;
dlgAbout.DoModal();
}
else
{
CDialog::OnSysCommand(nID, lParam);
}
}
// If you add a minimize button to your dialog, you will need the code below
// to draw the icon. For MFC applications using the document/view model,
// this is automatically done for you by the framework.
void CSerialDlg::OnPaint()
{
if (IsIconic())
{
CPaintDC dc(this); // device context for painting
SendMessage(WM_ICONERASEBKGND, reinterpret_cast<WPARAM>(dc.GetSafeHdc()), 0);
// Center icon in client rectangle
int cxIcon = GetSystemMetrics(SM_CXICON);
int cyIcon = GetSystemMetrics(SM_CYICON);
CRect rect;
GetClientRect(&rect);
int x = (rect.Width() - cxIcon + 1) / 2;
int y = (rect.Height() - cyIcon + 1) / 2;
// Draw the icon
dc.DrawIcon(x, y, m_hIcon);
}
else
{
CDialog::OnPaint();
}
}
// The system calls this function to obtain the cursor to display while the user drags
// the minimized window.
HCURSOR CSerialDlg::OnQueryDragIcon()
{
return static_cast<HCURSOR>(m_hIcon);
}
void CSerialDlg::OnBnClickedCheckComm()
{
// TODO: Add your control notification handler code here
UpdateData(TRUE);
BOOL bCheck =((CButton*)GetDlgItem(IDC_CHECK_COMM))->GetCheck();
if(bCheck)//통신시작
{
// for(int i=0; i<2; i++){
if(m_Comm.OpenCommPort(&Int2TTY())!=TRUE)
{
CString str;
str.Format("COM%d이 이미 사용중인지 확인하세요",m_nSettingPort);
AfxMessageBox(str);
((CButton*)GetDlgItem(IDC_CHECK_COMM))->SetCheck(!bCheck);
return;
}
GetDlgItem(IDC_CHECK_COMM)->SetWindowTextA("통신종료");
GetDlgItem(IDC_PORT)->EnableWindow(FALSE);
GetDlgItem(IDC_PORT2)->EnableWindow(FALSE);
GetDlgItem(IDC_BAUDRATE)->EnableWindow(FALSE);
}
else{
//for(int i=0; i<2; i++){
m_Comm.CloseConnection();
//}
GetDlgItem(IDC_CHECK_COMM)->SetWindowTextA("통신시작");
GetDlgItem(IDC_PORT)->EnableWindow(TRUE);
GetDlgItem(IDC_PORT2)->EnableWindow(TRUE);
GetDlgItem(IDC_BAUDRATE)->EnableWindow(TRUE);
}
}
TTYSTRUCT CSerialDlg::Int2TTY()
{
TTYSTRUCT tty;
ZERO_MEMORY(tty);
tty.byCommPort = (BYTE) m_nSettingPort;
tty.byXonXoff = FALSE;
tty.byByteSize = (BYTE)_nDataValues[m_nSettingData];
tty.byFlowCtrl = (BYTE)_nFlow[m_nSettingFlow];
tty.byParity = (BYTE)m_nSettingParity;
tty.byStopBits = (BYTE)_nStopBits[m_nSettingStop];
tty.dwBaudRate = (DWORD)_nBaudRates[m_nSettingBaud];
return tty;
}
TTYSTRUCT CSerialDlg::LoadSettings()
{
CWinApp *pApp = AfxGetApp();
m_nSettingPort = pApp->GetProfileInt(CS_REGKEY_SETTINGS, CS_REGENTRY_PORT,1);
m_nSettingParity = 0;
m_nSettingBaud = pApp->GetProfileIntA(CS_REGKEY_SETTINGS, CS_REGENTRY_BAUD,1);
m_nSettingData = 1;
m_nSettingStop = 0;
m_nSettingFlow = 0;
return Int2TTY();
}
void CSerialDlg::SaveSettings()
{
CWinApp *pApp = AfxGetApp();
pApp->WriteProfileInt(CS_REGKEY_SETTINGS, CS_REGENTRY_PORT, m_nSettingPort);
pApp->WriteProfileInt(CS_REGKEY_SETTINGS, CS_REGENTRY_PARITY,m_nSettingParity);
pApp->WriteProfileInt(CS_REGKEY_SETTINGS, CS_REGENTRY_BAUD, m_nSettingBaud);
pApp->WriteProfileInt(CS_REGKEY_SETTINGS, CS_REGENTRY_DATABITS, m_nSettingData);
pApp->WriteProfileInt(CS_REGKEY_SETTINGS, CS_REGENTRY_STOPBITS, m_nSettingStop);
pApp->WriteProfileInt(CS_REGKEY_SETTINGS, CS_REGENTRY_FLOW, m_nSettingFlow);
}
void CSerialDlg::OnBnClickedOk()
{
// TODO: Add your control notification handler code here
char start[] = {0x02, 0x00, 0xf0};
//for(int i=0; i<2; i++)
m_Comm.WriteCommBlock(start,3);
// SaveSettings();
// CDialog::OnOK();
}
void CSerialDlg::OnBnClickedCancel()
{
// TODO: Add your control notification handler code here
// for(int i=0; i<2; i++)
// {
SaveSettings();
m_Comm.CloseConnection();
//}
CDialog::OnCancel();
}
LONG CSerialDlg::OnReceiveData(UINT WParam, LONG a)
{
int i;
int nLen = WParam;
CString str;
UpdateData(TRUE);
BYTE ch;
int temp;
// for(int j=0; j<2; j++){
for(i=0;i<nLen;i++)
{
ch =(int)m_Comm.abIn[i];
str.Format("%x",ch);
m_EditData += str;
}
// }
UpdateData(FALSE);
return TRUE;
}
Serial Port 연결 (C)
//Comm.cpp Rs232c통신을 하기 위한 클래스
// 2001년 3월 26일 (주) 마이크로 로보트 S/W팀 정웅식
//
#include "stdafx.h"
#include "comm.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
IMPLEMENT_DYNCREATE(CComm, CObject)
// 통신프로토콜 Table
BYTE _nFlow[] = {FC_NONE,FC_DTRDSR,FC_RTSCTS,FC_XONXOFF};
// 통신 데이타 사이즈 테이블
int _nDataValues[] = {7,8};
// 통신속도 Table
int _nBaudRates[] = {// CBR_1200, CBR_2400, CBR_4800,
CBR_9600, CBR_14400, CBR_19200,
CBR_38400, CBR_56000, CBR_57600,
CBR_115200, };
BYTE _nStopBits[] = { ONESTOPBIT, TWOSTOPBITS };
//BOOL bTxEmpty=TRUE;
UINT ReceMessage;
CComm::CComm( )
{
idComDev=NULL;
fConnected=FALSE;
bTxEmpty=TRUE;
}
CComm::~CComm( )
{
DestroyComm();
}
//BEGIN_MESSAGE_MAP(CComm, CObject)
//{{AFX_MSG_MAP(CComm)
// NOTE - the ClassWizard will add and remove mapping macros here.
//}}AFX_MSG_MAP
//END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CComm message handlers
//CommWatchProc()
//통신을 하는 프로세저 즉 데이타가 들어왔을대 감시하는
//루틴 본루틴은 OpenComPort 함수 실행시 프로시저로 연결됨
//OpenComPort 함수 참조
DWORD CommWatchProc(LPVOID lpData)
{
DWORD dwEvtMask ;
OVERLAPPED os ;
CComm* npComm = (CComm*) lpData ;
char InData[COM_MAXBLOCK + 1];
int nLength ;
//idCommDev 라는 핸들에 아무런 com 포트가 안붙어 있으면
// 에라 리턴
if ( npComm == NULL ||
!npComm->IsKindOf( RUNTIME_CLASS( CComm ) ) )
return (DWORD)(-1);
memset( &os, 0, sizeof( OVERLAPPED ) ) ;
os.hEvent = CreateEvent( NULL, // no security
TRUE, // explicit reset req
FALSE, // initial event reset
NULL ) ; // no name
if ( os.hEvent == NULL )
{
MessageBox( NULL, "Failed to create event for thread!", "comm Error!",
MB_ICONEXCLAMATION | MB_OK );
return ( FALSE ) ;
}
DWORD dwEventFlags = EV_BREAK | EV_CTS | EV_DSR | EV_ERR | EV_RING |
EV_RLSD | EV_RXCHAR | EV_RXFLAG | EV_TXEMPTY;
if (!SetCommMask(npComm->idComDev, dwEventFlags))
return ( FALSE ) ;
while (npComm->fConnected)
{
dwEvtMask = 0;
WaitCommEvent(npComm->idComDev, &dwEvtMask, NULL );
if ((dwEvtMask & EV_BREAK) == EV_BREAK)
{
;;;
}
else if ((dwEvtMask & EV_CTS) == EV_CTS)
{
;;;
}
else if ((dwEvtMask & EV_ERR) == EV_ERR)
{
;;;
}
else if ((dwEvtMask & EV_RING) == EV_RING)
{
;;;
}
else if ((dwEvtMask & EV_RLSD) == EV_RLSD)
{
;;;
}
else if ((dwEvtMask & EV_RXCHAR) == EV_RXCHAR)
{
do
{
memset(InData,0,80);
if (nLength = npComm->ReadCommBlock((LPSTR) InData, COM_MAXBLOCK ))
{
npComm->SetReadData(InData,nLength);
//이곳에서 데이타를 받는다.
}
}
while ( nLength > 0 ) ;
}
else if ((dwEvtMask & EV_RXFLAG) == EV_RXFLAG)
{
;;;
}
else if ((dwEvtMask & EV_TXEMPTY) == EV_TXEMPTY)
{
npComm->bTxEmpty = TRUE;
}
}
CloseHandle( os.hEvent );
return( TRUE );
}
//데이타를 읽고 데이타를 읽었다는
//메세지를 리턴한다.
void CComm::SetReadData(LPSTR data, int nLen)
{
memcpy(abIn,data,nLen);
//설정된 윈도우에 WM_RECEIVEDATA메세지를
//날려주어 현제 데이타가 들어왔다는것을
//알려준다.
//SendMessage(m_hwnd,ReceMessage,nLen,0);
SendMessage(m_hwnd,WM_RECEIVEDATA,nLen,0);
}
//메세지를 전달할 hwnd설정
void CComm::SetHwnd(HWND hwnd)
{
m_hwnd=hwnd;
}
//com 포트를 열고 연결을 시도한다.
//OpenComport()
BOOL CComm::OpenCommPort(LPTTYSTRUCT lpTTY)
{
char szPort[ 15 ] ;
BOOL fRetVal ;
COMMTIMEOUTS CommTimeOuts ;
osWrite.Offset = 0 ;
osWrite.OffsetHigh = 0 ;
osRead.Offset = 0 ;
osRead.OffsetHigh = 0 ;
//이벤트 창구 설정
osRead.hEvent = CreateEvent( NULL, TRUE, FALSE, NULL );
if (osRead.hEvent == NULL)
{
return FALSE ;
}
osWrite.hEvent = CreateEvent( NULL, TRUE, FALSE, NULL );
if (NULL == osWrite.hEvent)
{
CloseHandle( osRead.hEvent );
return FALSE;
}
if (lpTTY->byCommPort > COM_MAXPORTS)
lstrcpy( szPort, "\\\\.\\TELNET" ) ;
else
wsprintf( szPort, "COM%d", lpTTY->byCommPort );
// COMM device를 화일형식으로 연결한다.
if ((idComDev =
CreateFile( szPort, GENERIC_READ | GENERIC_WRITE,
0, // exclusive access
NULL, // no security attrs
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL |
FILE_FLAG_OVERLAPPED, // overlapped I/O
NULL )) == (HANDLE) -1 )
return ( FALSE ) ;
else
{
//컴포트에서 데이타를 교환하는 방법을 char단위를 기본으로 설정하자
SetCommMask( idComDev, EV_RXCHAR ) ;
SetupComm( idComDev, 4096, 4096 ) ;
//디바이스에 쓰레기가 있을지 모르니까 깨끗이 청소를 하자!
PurgeComm( idComDev, PURGE_TXABORT | PURGE_RXABORT |
PURGE_TXCLEAR | PURGE_RXCLEAR ) ;
CommTimeOuts.ReadIntervalTimeout = 0xFFFFFFFF ;
CommTimeOuts.ReadTotalTimeoutMultiplier = 0 ;
CommTimeOuts.ReadTotalTimeoutConstant = 1000 ;
CommTimeOuts.WriteTotalTimeoutMultiplier = 0 ;
CommTimeOuts.WriteTotalTimeoutConstant = 1000 ;
SetCommTimeouts( idComDev, &CommTimeOuts ) ;
}
fRetVal = SetupConnection(lpTTY) ;
if (fRetVal)//연결이 되었다면 fRetVal TRUE이므로
{
fConnected = TRUE ;//연결되었다고 말해줌
//프로시전를 CommWatchProc에 연결하니까 나중에 데이타가 왔다갔다
//하면 모든 내용은 CommWatchProc가 담당한다.
AfxBeginThread((AFX_THREADPROC)CommWatchProc,(LPVOID)this);
}
else
{
fConnected = FALSE ;
CloseHandle( idComDev) ;
}
return ( fRetVal ) ;
}
//화일로 설정된 컴포트와 실질 포트와 연결을 시킨다.
//SetupConnection 이전에 CreateComPort를 해주어야 한다.
BOOL CComm::SetupConnection(LPTTYSTRUCT lpTTY)
{
BOOL fRetVal;
DCB dcb;
dcb.DCBlength = sizeof( DCB ) ;
GetCommState( idComDev, &dcb ) ;//dcb의 기본값을 받는다.
dcb.BaudRate = lpTTY->dwBaudRate;
dcb.ByteSize = lpTTY->byByteSize;
dcb.Parity = lpTTY->byParity;
dcb.StopBits = lpTTY->byStopBits;
// setup hardware flow control FC_DTRDSR
BOOL bSet = (BYTE)((lpTTY->byFlowCtrl & FC_DTRDSR) != 0);
dcb.fOutxDsrFlow = bSet;
if(bSet)
dcb.fDtrControl = DTR_CONTROL_HANDSHAKE;
else
dcb.fDtrControl = DTR_CONTROL_ENABLE;
// FC_RTSCTS
bSet = (BYTE)((lpTTY->byFlowCtrl & FC_RTSCTS) != 0);
dcb.fOutxCtsFlow = bSet;
if(bSet)
dcb.fRtsControl = RTS_CONTROL_HANDSHAKE;
else
dcb.fRtsControl = RTS_CONTROL_ENABLE;
// setup software flow control FC_XONXOFF
bSet = (BYTE)((lpTTY->byFlowCtrl & FC_XONXOFF) != 0);
dcb.fInX = dcb.fOutX = bSet;
dcb.XonChar = ASCII_XON;
dcb.XoffChar = ASCII_XOFF;
dcb.XonLim = 1;
dcb.XoffLim = 1;
// other various settings
dcb.fBinary = TRUE;
dcb.fParity = TRUE;
fRetVal = SetCommState( idComDev, &dcb ) ; //변경된 Dcb 설정
return ( fRetVal ) ;
}
//컴포트로 부터 데이타를 읽는다.
int CComm::ReadCommBlock(LPSTR lpszBlock, int nMaxLength )
{
BOOL fReadStat ;
COMSTAT ComStat ;
DWORD dwErrorFlags;
DWORD dwLength;
// only try to read number of bytes in queue
ClearCommError( idComDev, &dwErrorFlags, &ComStat ) ;
dwLength = min( (DWORD) nMaxLength, ComStat.cbInQue ) ;
if (dwLength > 0)
{
fReadStat = ReadFile( idComDev, lpszBlock, dwLength, &dwLength, &osRead ) ;
if (!fReadStat)
{
if(GetLastError() == ERROR_IO_PENDING)
{
OutputDebugString("\n\rIO Pending");
// we have to wait for read to complete. This function will timeout
// according to the CommTimeOuts.ReadTotalTimeoutConstant variable
// Every time it times out, check for port errors
while(!GetOverlappedResult(idComDev, &osRead,
&dwLength, TRUE))
{
DWORD dwError = GetLastError();
if(dwError == ERROR_IO_INCOMPLETE)
{
// normal result if not finished
continue;
}
else
{
// CAN DISPLAY ERROR MESSAGE HERE
// an error occured, try to recover
::ClearCommError(idComDev, &dwErrorFlags, &ComStat);
if(dwErrorFlags > 0)
{
// CAN DISPLAY ERROR MESSAGE HERE
}
break;
}
}
}
else
{
// some other error occured
dwLength = 0;
ClearCommError(idComDev, &dwErrorFlags, &ComStat);
if(dwErrorFlags > 0)
{
// CAN DISPLAY ERROR MESSAGE HERE
}
}
}
}
return ( dwLength ) ;
}
// 컴포트에 데이터를 쓴다.
BOOL CComm::WriteCommBlock( LPSTR lpByte , DWORD dwBytesToWrite)
{
DWORD dwErrorFlags;
BOOL fWriteStat ;
DWORD dwBytesWritten ;
COMSTAT ComStat;
DWORD dwLength = dwBytesToWrite;
bTxEmpty = FALSE;
fWriteStat = WriteFile( idComDev, lpByte, dwBytesToWrite, &dwBytesWritten, &osWrite ) ;
//if (dwBytesToWrite != dwBytesWritten)
if(!fWriteStat)
{
if(GetLastError() == ERROR_IO_PENDING)
{
OutputDebugString("\n\rIO Pending");
// 읽을 문자가 남아 있거나 전송할 문자가 남아 있을 경우 Overapped IO의
// 특성에 따라 ERROR_IO_PENDING 에러 메시지가 전달된다.
//timeouts에 정해준 시간만큼 기다려준다.
while(!GetOverlappedResult(idComDev, &osWrite,
&dwLength, TRUE))
{
DWORD dwError = GetLastError();
if(dwError == ERROR_IO_INCOMPLETE)
{
// normal result if not finished
continue;
}
else
{
// CAN DISPLAY ERROR MESSAGE HERE
// an error occured, try to recover
::ClearCommError(idComDev, &dwErrorFlags, &ComStat);
if(dwErrorFlags > 0)
{
// CAN DISPLAY ERROR MESSAGE HERE
AfxMessageBox("ERROR");
}
break;
}
}
}
else
{ // some other error occured
dwLength = 0;
ClearCommError(idComDev, &dwErrorFlags, &ComStat);
if(dwErrorFlags > 0)
{
// CAN DISPLAY ERROR MESSAGE HERE
AfxMessageBox("ERROR");
}
}
}
return ( TRUE ) ;
}
//컴포트를 완전히 해제한다.
BOOL CComm::DestroyComm()
{
if (fConnected)
CloseConnection();
if (osRead.hEvent!=NULL)
CloseHandle( osRead.hEvent ) ;
if (osWrite.hEvent != NULL)
CloseHandle( osWrite.hEvent ) ;
return ( TRUE ) ;
}
//연결을 닫는다.
BOOL CComm::CloseConnection()
{
// set connected flag to FALSE
fConnected = FALSE ;
// disable event notification and wait for thread
// to halt
SetCommMask( idComDev, 0 ) ;
EscapeCommFunction( CLRDTR ) ;
EscapeCommFunction( CLRRTS ) ;
PurgeComm( idComDev, PURGE_TXABORT | PURGE_RXABORT |
PURGE_TXCLEAR | PURGE_RXCLEAR ) ;
CloseHandle( idComDev ) ;
return ( TRUE ) ;
}
void CComm::EscapeCommFunction(DWORD dwFunc)
{
// TODO: Add your control notification handler code here
::EscapeCommFunction(idComDev,dwFunc);
}
2010년 5월 18일 화요일
[공모전] bada Developer Challenge (5/17개최)

제1회 삼성 bada Developer Challenge가 개최됩니다.
세계대회 출전을 통해 역량을 키울 수 있는 좋은 기회가 될 것 같습니다.
공모전 세부 내용은 Bada 웹사이트를 통해 확인하실 수 있으며,
Bada SDK는 이미 Release 되어 사용할 수 있으니 바로 학습/개발 가능합니다
1차 제출 일정이 7월 말입니다.
- bada Developer Challenge 바로 가기
- bada SDK 다운로드 -
2010년 5월 9일 일요일
[Java] Serial Communication API (시리얼통신)
아직까지도 주요 통신 수단인 시리얼 통신(RS-232C)은 현재 J2SE에서 제공하고 있지 않다.
하지만 하드웨어 관련한 프로젝트를 해보면 알겠지만 매우 필요한 수단이다.
일단은 표준 API가 아니므로 추가적으로 설치해야하는데 다음 링크를 따라가보자
[링크] : http://java.sun.com/products/javacomm/index.html
[파일] :
* 설치
1. 링크를 따라가면 화면 좌측으로 다운로드 링크가 있다. 따라가도록 하자.
2. 아래쪽으로 플랫폼을 선택할 수 있는데 윈도우라면 Generic을 선택한 후 다운로드를 진행한다.
(현재는 로그인을 해야 다운로드가진행된다. 메일주소와 이름등만 적으면 되므로 가입후 진행하자)
2. 첨부파일 저장 후 comm.jar, javax.comm.properties, win32com.dll 파일을 java.exe 파일이 있는 C:\Program Files\Java\jdk1.6.0_18\bin (경로는 본인에 맞게)에 복사한다.
3. comm.jar를 클래스 패스에 추가시킨다.
4. 사용하려는 클래스에서 import javax.comm.*; 을 하여 사용한다.
* 사용예제
import java.io.*;
import javax.comm.*;
public class Rs232c {
public static void main( String arg[] ) {
try {
CommPortIdentifier ports = CommPortIdentifier.getPortIdentifier( "COM1" );
SerialPort port = ( SerialPort )ports.open( "RS232C", 1000 );
port.setSerialPortParams( 9600,
SerialPort.DATABITS_8, SerialPort.STOPBITS_1, SerialPort.PARITY_NONE );
port.setFlowControlMode( SerialPort.FLOWCONTROL_NONE );
OutputStream out = port.getOutputStream();
String msg = "Serial Comm.\n";
out.write( msg.getBytes() );
out.flush();
out.close();
port.close();
}
catch( Exception e ) {
System.out.println( "Error:" + e.getMessage() );
}
}
}
2010년 5월 7일 금요일
[GOCR] 소스분석 <gocr-0.48/src/ocr0.c/ocr0_oO()>
문자인식을 위한 프로젝트를 진행하기위해 gocr소스를 분석하였다.
일단 전체적으로 분석하기에는 구조가 조금 복잡한 면이 있어서
알파벳 o,O를 분석하는 함수인 ocr0_oO()를 분석하고자 한다.
static wchar_t ocr0_oO(ocr0_shared_t *sdata){...}
- 내부 사용 함수
get_bw()
num_cross()
loop()
setac()
1. char get_bw(int x0, int x1, int y0, int y1, pix * p, int cs, int mask)
- Look for dots in the rectangular region x0 <= x <= x1 and y0 <= y <= y1 in pixmap p. The two low order bits in mask indicate the color of dots to look for: If mask==1 then look for black dots (where a pixel value less than cs is considered black). If mask==2 then look for white dots. If mask==3 then look for both black and white dots. If the dots are found, the corresponding bits are set in the returned value. Heavily used by the engine ocr0*.cc
- pixmap p의 x0 <= x <= x1 와 y0 <= y <= y1 범위의 사각형 영역의 점을 찾는다. mask 변수의 하위 2비트는 찾으려고 하는 점들의 색을 나타낸다. : mask==1이면 검은점을 나타내고(cs보다 작은 값은 검은점으로), mask==2이면 흰점을 mask==3이면 검은점과 흰점 둘다 나타낸다. 특정 점을 찾아 그에 해당하는 리턴 값으로 셋팅된다. 주로 ocr0*.cc에서 쓰인다.
2. int num_cross(int x0, int x1, int y0, int y1, pix *p, int cs)
- more general Mar2000 (x0,x1,y0,y1 instead of x0,y0,x1,y1! (history)) look for black crossings throw a line from x0,y0 to x1,y1 and count them follow line and count crossings ([white]-black-transitions)
- ex: horizontal num_cross of 'm' would return 3
- fail for: .a... a-to-b counts no transitions, but there is
* ...#.
* ..#..
* .#..b
- Mar2000보다 일반적인 형태로 x0,y0부터 x1,y1 선분에 있는 검은 색 교차지점(백-흑 변화)을 찾아 그 개수를 리턴한다.
- 예) m의 가로 num_cross값은 3을 리턴한다.
3. int loop(pix *p,int x,int y,int l,int cs,int col, DIRECTION r)
- move from x,y to direction r until pixel of color col is found or maximum of l steps return the number of steps done
- x,y부터 r방향으로 이동하면서 col 색을 찾거나 최고 l스텝까지 이동하여 스텝값을 리턴한다.
4. int setac(struct box *b, wchar_t ac, int weight)
- this function will be replaced by a call of setas() later
- 이 함수는 추후 setas()로 대체될 것이다.
5. int setas(struct box *b, char *as, int weight)
- set alternate chars and its weight, called from the engine if a char is recognized to (weight) percent can be used for filtering (only numbers etc) often usefull if Il1 are looking very similar
should this function stay in box.c ??? weight is between 0 and 100 in percent, 100 means absolutely sure not final, not time critical (js) replace it by a string-function setaobj(*b,"string",weight) and let call setac the setas function
- 서로 엇갈리는 문자들과 이 문자들의 가중치을 정하고, ........ ??? 가중치값은 0과 100퍼센트 사이값이다.
javacomm20-win32_1.zip