Search

'프로젝트'에 해당되는 글 3건

  1. 2009.02.26 FT232 가지고 놀기 Part.2 1
  2. 2009.02.26 FT232 가지고 놀기 Part.1
  3. 2008.12.12 드라군 1

FT232 가지고 놀기 Part.2

프로젝트/FTDI 2009. 2. 26. 19:18 Posted by 보노보노보노

이것은 USB로 PC와 시리얼 로 접속한뒤 블루투스나 Rs-232로 데이터를 전송하는 모듈이다.

모듈은 내부 핀설정을 통해 블루투스에서 받은 데이터를 RS-232C로 전송하거나

RS-232로 받은 데이터를 블루투스로 보내는 어답터 역활을 수행하기도 한다.
흰색부분이 3pin RS-232신호핀이다.

위의 점퍼로 설정이 가능 한데, 저 점퍼를 세로로 하면 BT-RE232C 통신이 가능하다.

FT232 가지고 놀기 Part.1

프로젝트/FTDI 2009. 2. 26. 19:08 Posted by 보노보노보노






FTDI사에서 만든 USB-serial 칩이다.

PC와 연결시 VCP로 인식이 되지만 D2XX드라이버로 제어가 가능하다.

사용법은 FTD2XX.DLL 파일을 이용하는것이다.

클래식 인터페이스나 FT-WIN32 인터페이스중에서 하나만 사용하여야 하지만 나는 클래식 인터페이스를 사용하였다.

#include <ftd2xx.h> //FTDI사에서 제공.

int board_present; // 보드의 연결상태를 확인하고 저장하기 위한 변수.
int bus_busy; // USB 버스의 사용유무 확인용 FLAG
CString m_NameNmbr; // FTDI칩과 연결시에 DESCRIPTIN(이름으로 열기)으로 OPEN할때 문자열 비교용.

HMODULE m_hmodule; // FTD2XX.dll 핸들을 얻어오기 위한 코드 내부의 핸들..
FT_HANDLE m_ftHandle; // FT_핸들 선언.


typedef FT_STATUS (WINAPI *PtrToOpen)(PVOID, FT_HANDLE *); //
PtrToOpen m_pOpen;
FT_STATUS Open(PVOID pvDevice)
{
if (!m_pOpen)
return FT_INVALID_HANDLE; // FT_INVALID_HANDLE FT_STATUS에 1로 되어 있음.

return (*m_pOpen)(pvDevice, &m_ftHandle ); //핸들 반환.
} ;

/* FTD2xx.h 안에 원래 함수
FTD2XX_API
FT_STATUS WINAPI FT_Open(
int deviceNumber,
FT_HANDLE *pHandle
); */


typedef FT_STATUS (WINAPI *PtrToOpenEx)(PVOID, DWORD, FT_HANDLE *);
PtrToOpenEx m_pOpenEx;
FT_STATUS OpenEx(PVOID pArg1, DWORD dwFlags)
{
if (!m_pOpenEx)
return FT_INVALID_HANDLE;

return (*m_pOpenEx)(pArg1, dwFlags, &m_ftHandle);
} ;


typedef FT_STATUS (WINAPI *PtrToListDevices)(PVOID, PVOID, DWORD);
PtrToListDevices m_pListDevices;
FT_STATUS ListDevices(PVOID pArg1, PVOID pArg2, DWORD dwFlags)
{
if (!m_pListDevices)
return FT_INVALID_HANDLE;

return (*m_pListDevices)(pArg1, pArg2, dwFlags);
} ;


typedef FT_STATUS (WINAPI *PtrToClose)(FT_HANDLE);
PtrToClose m_pClose;
FT_STATUS USBDrvClose()
{
if (!m_pClose)
return FT_INVALID_HANDLE;

return (*m_pClose)(m_ftHandle);
} ;


typedef FT_STATUS (WINAPI *PtrToRead)(FT_HANDLE, LPVOID, DWORD, LPDWORD);
PtrToRead m_pRead;
FT_STATUS Read(LPVOID lpvBuffer, DWORD dwBuffSize, LPDWORD lpdwBytesRead)
{
if (!m_pRead)
return FT_INVALID_HANDLE;

return (*m_pRead)(m_ftHandle, lpvBuffer, dwBuffSize, lpdwBytesRead);
} ;




typedef FT_STATUS (WINAPI *PtrToWrite)(FT_HANDLE, LPVOID, DWORD, LPDWORD);
PtrToWrite m_pWrite;
FT_STATUS Write(LPVOID lpvBuffer, DWORD dwBuffSize, LPDWORD lpdwBytes)
{
if (!m_pWrite)
return FT_INVALID_HANDLE;

return (*m_pWrite)(m_ftHandle, lpvBuffer, dwBuffSize, lpdwBytes);
} ;


typedef FT_STATUS (WINAPI *PtrToSetBaudRate)(FT_HANDLE, ULONG);
PtrToSetBaudRate m_pSetBaudRate;
FT_STATUS SetBaudRate(ULONG ulBaudRate)
{
if (!m_pSetBaudRate)
return FT_INVALID_HANDLE;

return (*m_pSetBaudRate)(m_ftHandle,ulBaudRate);
} ;

typedef FT_STATUS (WINAPI *PtrToSetDataCharacteristics)(FT_HANDLE,UCHAR,UCHAR,UCHAR);
PtrToSetDataCharacteristics m_pSetDataCharacteristics;
FT_STATUS SetSetDataCharacteristics(UCHAR WordLenth, UCHAR StopBit, UCHAR Parity)
{
if (!m_pSetDataCharacteristics)
return FT_INVALID_HANDLE;

return (*m_pSetDataCharacteristics)(m_ftHandle, WordLenth, StopBit, Parity);
} ;

typedef FT_STATUS (WINAPI *PtrToSetFlowControl)(FT_HANDLE, USHORT, UCHAR, UCHAR);
PtrToSetFlowControl m_pSetFlowControl;
FT_STATUS SetFlowControl(USHORT FlowControl, UCHAR XonChar, UCHAR XoffChar)
{
if (!m_pSetFlowControl)
return FT_INVALID_HANDLE;

return (*m_pSetFlowControl)(m_ftHandle, FlowControl, XonChar, XoffChar);
} ;



typedef FT_STATUS (WINAPI *PtrToResetDevice)(FT_HANDLE);
PtrToResetDevice m_pResetDevice;
FT_STATUS ResetDevice()
{
if (!m_pResetDevice)
return FT_INVALID_HANDLE;

return (*m_pResetDevice)(m_ftHandle);
} ;


typedef FT_STATUS (WINAPI *PtrToPurge)(FT_HANDLE, ULONG);
PtrToPurge m_pPurge;
FT_STATUS Purge(ULONG dwMask)
{
if (!m_pPurge)
return FT_INVALID_HANDLE;

return (*m_pPurge)(m_ftHandle, dwMask);
} ;


typedef FT_STATUS (WINAPI *PtrToSetTimeouts)(FT_HANDLE, ULONG, ULONG);
PtrToSetTimeouts m_pSetTimeouts;
FT_STATUS SetTimeouts(ULONG dwReadTimeout, ULONG dwWriteTimeout)
{
if (!m_pSetTimeouts)
return FT_INVALID_HANDLE;

return (*m_pSetTimeouts)(m_ftHandle, dwReadTimeout, dwWriteTimeout);
} ;

typedef FT_STATUS (WINAPI *PtrToGetQueueStatus)(FT_HANDLE, LPDWORD);
PtrToGetQueueStatus m_pGetQueueStatus;
FT_STATUS GetQueueStatus(LPDWORD lpdwAmountInRxQueue)
{
if (!m_pGetQueueStatus)
return FT_INVALID_HANDLE;

return (*m_pGetQueueStatus)(m_ftHandle, lpdwAmountInRxQueue);
} ;


typedef FT_STATUS (WINAPI *PtrToGetEventStatus)(FT_HANDLE, DWORD);
PtrToGetEventStatus m_pGetEventStatus;
FT_STATUS GetEventStatus(DWORD dwEventDWord)
{
if (!m_pGetEventStatus)
return FT_INVALID_HANDLE;

return (*m_pGetEventStatus)(m_ftHandle, dwEventDWord);
} ;


int InitDrv()
{
m_hmodule = LoadLibrary("Ftd2xx.dll"); //ftd2xx.dll파일을 로드
if(m_hmodule == NULL)
{
return -1;
}
m_pWrite = (PtrToWrite)GetProcAddress(m_hmodule, "FT_Write"); //ftd2xx.dll에 있는 "FT_WRITE"함수의 주소를 가져옴.
if (m_pWrite == NULL) //만약 함수의 주소를 받아오지 못할 경우 초기화 종료.
{
return -1;
}

m_pRead = (PtrToRead)GetProcAddress(m_hmodule, "FT_Read");
if (m_pRead == NULL)
{
return -1;
}

m_pOpen = (PtrToOpen)GetProcAddress(m_hmodule, "FT_Open");
if (m_pOpen == NULL)
{
return -1;
}

m_pOpenEx = (PtrToOpenEx)GetProcAddress(m_hmodule, "FT_OpenEx");
if (m_pOpenEx == NULL)
{
return -1;
}

m_pListDevices = (PtrToListDevices)GetProcAddress(m_hmodule, "FT_ListDevices");
if(m_pListDevices == NULL)
{
return -1;
}

m_pClose = (PtrToClose)GetProcAddress(m_hmodule, "FT_Close");
if (m_pClose == NULL)
{
return -1;
}

m_pResetDevice = (PtrToResetDevice)GetProcAddress(m_hmodule, "FT_ResetDevice");
if (m_pResetDevice == NULL)
{
return -1;
}

m_pPurge = (PtrToPurge)GetProcAddress(m_hmodule, "FT_Purge");
if (m_pPurge == NULL)
{
return -1;
}

m_pSetTimeouts = (PtrToSetTimeouts)GetProcAddress(m_hmodule, "FT_SetTimeouts");
if (m_pSetTimeouts == NULL)
{
return -1;
}

m_pGetQueueStatus = (PtrToGetQueueStatus)GetProcAddress(m_hmodule, "FT_GetQueueStatus");
if (m_pGetQueueStatus == NULL)
{
return -1;
}

m_pSetBaudRate =(PtrToSetBaudRate)GetProcAddress(m_hmodule,"FT_SetBaudRate");
if (m_pSetBaudRate == NULL)
{
return -1;
}

m_pSetDataCharacteristics =(PtrToSetDataCharacteristics)GetProcAddress(m_hmodule,"FT_SetDataCharacteristics");
if (m_pSetDataCharacteristics == NULL)
{
return -1;
}

m_pSetFlowControl =(PtrToSetFlowControl)GetProcAddress(m_hmodule,"FT_SetFlowControl");
if (m_pSetFlowControl == NULL)
{
return -1;
}

m_pGetEventStatus =(PtrToGetEventStatus)GetProcAddress(m_hmodule,"FT_GetEventStatus");
if (m_pGetEventStatus == NULL)
{
return -1;
}

return 1;
};


FT_STATUS OpenBy()
{
FT_STATUS status; // 샅애확인 위한 구조체 생성.
m_NameNmbr="USB <-> Serial" ; // 이름으로 USB장치를 검색하여 열기 위한 장치이름.

status = OpenEx((PVOID)(LPCTSTR)m_NameNmbr, FT_OPEN_BY_DESCRIPTION);
//이름에 의한 호출로 Product Description이 "USB <-> Serial"으로 되어있는 장치를 엶.
return status; // 정상적으로 OPEN 되었을시 0(FT_OK)반환.
};

FT_STATUS OpenBy(char* DESCRIPTION)
{
FT_STATUS status; // 샅애확인 위한 구조체 생성.
m_NameNmbr=DESCRIPTION; // 이름으로 USB장치를 검색하여 열기 위한 장치이름.

status = OpenEx((PVOID)(LPCTSTR)m_NameNmbr, FT_OPEN_BY_DESCRIPTION);
//이름에 의한 호출로 Product Description이 "USB <-> Serial"으로 되어있는 장치를 엶.
return status; // 정상적으로 OPEN 되었을시 0(FT_OK)반환.
};

int SetFT232()
{
// 232 통신위한 설정.
SetBaudRate(FT_BAUD_115200 ); //115.2k
SetSetDataCharacteristics(FT_BITS_8, FT_STOP_BITS_1,
FT_PARITY_NONE); // 데이터길이, 스탑비트, 페리티 설정.
SetFlowControl(FT_FLOW_NONE,NULL,NULL); //흐름제어 설정부
SetTimeouts(1000,1000); // READ TIMEOUT, WRITE TIMEOUT 설정(ms단위)

return 1;
}
int SetFT232(ULONG Baud, UCHAR Bit, UCHAR StopBit, UCHAR Parity)
{
// 232 통신위한 설정.
SetBaudRate(Baud); //115.2k
SetSetDataCharacteristics(Bit, StopBit, Parity); // 데이터길이, 스탑비트, 페리티 설정.
SetFlowControl(FT_FLOW_NONE,NULL,NULL); //흐름제어 설정부
SetTimeouts(1000,1000); // READ TIMEOUT, WRITE TIMEOUT 설정(ms단위)
return 1;
}

int USBDrvInit()
{
//open the device
FT_STATUS status = OpenBy(); // USB 디바이스 OPEN위한 함수 실행.
if(!(status==FT_OK)) // USB 열기를 실패할 경우.
{
board_present=0; // 디바이스와 연결 안되었음을 저장.
return -1; // 종료.
}
else // 디바이스를 성공적으로 열었을 경우.
{
ResetDevice(); // 디바이스를 리셋시킴.
Purge(FT_PURGE_RX || FT_PURGE_TX); // 디바이스의 Rx,Tx버퍼를 초기화.


//test for presence of board
board_present=1; //디바이스와 연결되었다는 상태를 저장.
SetFT232();
}
return 1; // 초기화 성공을 알리는 상수 반환.
};

int USBDrvInit(char *DESCRIPTION)
{
//open the device
FT_STATUS status = OpenBy(DESCRIPTION); // USB 디바이스 OPEN위한 함수 실행.
if(!(status==FT_OK)) // USB 열기를 실패할 경우.
{
board_present=0; // 디바이스와 연결 안되었음을 저장.
return -1; // 종료.
}
else // 디바이스를 성공적으로 열었을 경우.
{
ResetDevice(); // 디바이스를 리셋시킴.
Purge(FT_PURGE_RX || FT_PURGE_TX); // 디바이스의 Rx,Tx버퍼를 초기화.


//test for presence of board
board_present=1; //디바이스와 연결되었다는 상태를 저장.
SetFT232();
}
return 1; // 초기화 성공을 알리는 상수 반환.
};


void TxData(char *TxD,UINT len) // 데이터 길이를 정해서 전송시
{
DWORD ret_bytes; // 이전에 전송한 데이터를 받을 주소.

if(!board_present) // 디바이스와 연결이 되지 않았을때
return ; // 함수종료

bus_busy=1; // 버스가 사용중임을 알림.

//keep the timer function from grabbing return data

Write(TxD, len, &ret_bytes); // 전송할 문자열, 길이, 이전에 전송한 데이터(반환) 

bus_busy=0; // 버스의 사용종료 알림.
};


int AsciiToInt_2Digit(char *ascii_) // 2개의 아스키 코드를 정수형변수로 변환.
{
int int_data; // 계산하여 반환될 정수형 데이터 선언.

int_data=(int)ascii_[1]-48;
int_data+=((int)ascii_[0]-48)*10;

return int_data;
}


int RxData(char **RxDD,int lenth) // 문자열의 길이를 지정해서 전손받을때.
{
static char rx[256]; // 전송받을 문자를 받을 배열 설정.

DWORD rec_bytes; // 디바이스측에서 외부장치로부터 받은 데이터의 길이를 저장

if(!board_present) // 디바이스와 연결되지 않았을때
return -1; // 함수종료.

for (int i=0;i<256;i++) // 데이터 받을 곳을 초기화.
rx[i]=NULL;

bus_busy=1; // 버스가 사용중임을 알림.

Read(rx, lenth, &rec_bytes); // 받을 문자열을 저장할 장소, 받을 데이터의 길이,
// 디바이스가 외부로부터 받은 데이터 길이.
bus_busy=0; // 버스의 사용종료 알림.

*RxDD=rx; // 받은 데이터를 입력받은 포인터에 반환.
return 0;
}


int RxData(char **RxDD) // 문자열의 길이를 지정하지 않고 데이터를 받을때.
{
static char rx[256]; // 전송받을 문자를 받을 배열 설정.

DWORD rec_bytes, Rxbyte_lenth; // 디바이스측에서 외부장치로부터 받은 데이터의 길이를 저장,
//
if(!board_present) // 디바이스와 연결되지 않았을때
return -1; // 함수종료.

for (int i=0;i<256;i++) // 데이터 받을 곳을 초기화.
rx[i]=NULL;

bus_busy=1; // 버스가 사용중임을 알림.
GetQueueStatus(&Rxbyte_lenth); // 현재 디바이스가 받은 데이터의 길이 저장

if(Rxbyte_lenth>0) // 수신한데이터가 있으면
{
Read(rx, Rxbyte_lenth, &rec_bytes); //수신한 데이터양만큼 데이터를 수신.
}
bus_busy=0; // 버스의 사용종료 알림.

*RxDD=rx; // 받은 데이터를 입력받은 포인터에 반환.
return Rxbyte_lenth; // 수신한 데이터의 길이 반환.
}


int RxData_dynamic(char **RxDD) // 받을 데이터에 데이터의 길이가 포함되어 있을경우.
{
static char rx[256]; // 전송받을 문자를 받을 배열 설정.

DWORD ret_bytes, Rxbyte_lenth; // 디바이스측에서 외부장치로부터 받은 데이터의 길이를 저장,
char lenth_data[2]; // 데이터의 길이를 받을 배열 생성.
int lenth_int; // 데이터의 길이 저장변수.

if(!board_present) // 디바이스와 연결되지 않았을때
return -1; // 함수종료.

for (int i=0;i<256;i++) // 데이터를 받을 곳을 초기화.
rx[i]=NULL;

bus_busy=1; // 버스 사용중임을 알림.
GetQueueStatus(&Rxbyte_lenth); // 현재 디바이스가 받은 데이터의 길이 저장

if(Rxbyte_lenth>0) // 수신한 데이터가있을시.
{
Read(lenth_data,2,&ret_bytes); // 길이 데이터 수신.
lenth_int=AsciiToInt_2Digit(lenth_data); //받은길이 데이터를 정수형으로 변환.
Read(rx, lenth_int, &ret_bytes); // 데이터의 길이만큼 데이터 수신.
}
bus_busy=0; // 버스의 사용종료 알림.

*RxDD=rx; // 받은 데이터를 입력받은 포인터에 반환.
return lenth_int; // 수신한 데이터의 길이 반환.
}



 

위와같이 해더파일을 만들엇다

메카트로닉스 산업기사에서 사용하는 imechatronics.h 헤더파일을 수정하였으며.

기존의 FT245 칩을 사용시에  통신속도와 패리티 비트, 스탑비트를 설정 안하여도 된다.

int InitDrv()는  FTD2XX.dll에서 각 핸들을 얻어오는 함수이고.

FT_STATUS OpenBy()는 기본 DESCRIPTION인 "USB <-> Serial"을 사용시 사용하고

int SetFT232() 는 115.2K속도, 데이터 8bit, 1스탑비트, 패리티 비트 없이, 흐름제어를 안하는 기본 설정으로 여는것이고.

int USBDrvInit()는 기본 DESCRIPTION을 이용하여 드라이버를 열고 SerFT232() 함수를 실핼 한것으로 포트를 열기 실패시 -1의 값을 리턴한다.

나머지 함수는 주석을 달았으니 그때그때 보면서 쓰면 될듯...



드라군

프로젝트/드라군 2008. 12. 12. 02:58 Posted by 보노보노보노

올해 AVR을 처음 시작하게 만든녀석.

8051로 하려고 하였으나 처리속도가 안되서 AVR로 넘어가게 한 넘이다.

프레임설계는 PRO-E로 하였고. 제작은 알루미늄 1T를 가위,드릴,망치를 이용하여 수가공하였다.


-프레임 설계 -

드라군이란 이름은 스타에서의 드라군 이미지나 머리속에 깊게 남아 있어서 드라군이라 하였다

이 전에 8051을 이용하여 인태씨가 모터 8개로 4족 보행로봇을 만들었었는데 그 로봇이름 또한 드라군이였다.

어떻하면 이름을 따라하게 된것인데 그래도 괜찮다.
 
- 실제 동작 모습 -
이게 9월 8일에 찍은 영상이다.
로봇에 두종류의 케이블이 연결되어 있는데 하나는 전원 케이블이고 하나는 통신케이블이다 
이때는 리모콘은 아직 만들지 않았을 떄라서 컴퓨터로 제어하였다..



나중에 리모콘을 두종류를 만들었다.

둘다 블루투스로 통신이 가능하게 만들었다.

하나는 일반 리모콘처럼 버튼식으로 만들었고

하나는 자이로센서를 이용해서 원하는 방향으로 흔들면 그 방향으로 움직이도록 만들었다.

사람들이 개끌고 다니냐고 할정도로 이상 하긴 하지만 나름 뿌듯했다.


4족로봇 만든다음 가격을 계산해보니 컴퓨터 한대값이;;;

모터단가가 7만원정도 하니깐 7만원 X 16개 = 112만원

AVR 모듈,프레임등 비용 5만원

거의 120만원이 들어간것이다....

다음에는 싸게 만들어야 겠다는 생각이 들었다.