wxarduino.h
#ifndef __WX_ARDUINO__
#define __WX_ARDUINO__
#include <wx/wx.h>
#include "serialport.h"
#include "connectargsdlg.h"
class App:public wxApp
{
public:
bool OnInit();
};
class Frame:public wxFrame
{
public:
Frame(const wxString&);
void OnSendData(wxTimerEvent&);
void OnConnectDevice(wxCommandEvent&);
void OnReleaseDevice(wxCommandEvent&);
void OnExit(wxCommandEvent&);
private:
enum{
ID_SEND_DATA = 100,
ID_CONNECT_DEVICE,
ID_RELEASE_DEVICE
};
static const unsigned int MAX = 2;
wxMenu *device_path;
wxTimer timer;
SerialPort serial;
wxSlider *servos[MAX];
wxBoxSizer *box[MAX];
wxStaticText *servos_text[MAX];
unsigned char data[MAX];
DECLARE_EVENT_TABLE()
};
#endif
wxarduino.cpp
#include "wxarduino.h"
DECLARE_APP(App)
IMPLEMENT_APP(App)
bool App::OnInit()
{
Frame *frame = new Frame(wxT("wxArduino"));
frame->Show(true);
return true;
}
BEGIN_EVENT_TABLE(Frame,wxFrame)
EVT_MENU(wxID_EXIT,Frame::OnExit)
EVT_MENU(ID_CONNECT_DEVICE,Frame::OnConnectDevice)
EVT_MENU(ID_RELEASE_DEVICE,Frame::OnReleaseDevice)
EVT_TIMER(ID_SEND_DATA,Frame::OnSendData)
END_EVENT_TABLE()
Frame::Frame(const wxString &title):wxFrame(NULL,wxID_ANY,title,wxDefaultPosition,wxDefaultSize,wxMINIMIZE_BOX | wxCLOSE_BOX | wxCAPTION | wxSYSTEM_MENU),timer(this,ID_SEND_DATA),serial()
{
timer.Stop();
wxMenu *file = new wxMenu;
file->Append(wxID_EXIT,wxT("E&xit\tAlt-e"),wxT("Exit"));
wxMenu *tools = new wxMenu;
tools->Append(ID_CONNECT_DEVICE,wxT("C&onnect Device\tAlt-c"),wxT("Connect Device"));
tools->Append(ID_RELEASE_DEVICE,wxT("R&elease Device\tAlt-r"),wxT("Release Device"));
wxMenuBar *bar = new wxMenuBar;
bar->Append(file,wxT("File"));
bar->Append(tools,wxT("Tools"));
SetMenuBar(bar);
wxBoxSizer *top = new wxBoxSizer(wxVERTICAL);
this->SetSizer(top);
for(int i = 0;i < MAX;++i){
box[i] = new wxBoxSizer(wxHORIZONTAL);
top->Add(box[i],0,wxALIGN_CENTER_HORIZONTAL | wxALL,5);
wxString text;
text.Printf(wxT("Servo %d:"),i + 1);
servos_text[i] = new wxStaticText(this,wxID_STATIC,text,wxDefaultPosition,wxDefaultSize,0);
box[i]->Add(servos_text[i],0,wxALIGN_CENTER_HORIZONTAL | wxALIGN_CENTER_VERTICAL,5);
servos[i] = new wxSlider(this,wxID_ANY,90,0,180,wxDefaultPosition,wxSize(200,-1),wxSL_HORIZONTAL | wxSL_AUTOTICKS | wxSL_LABELS);
box[i]->Add(servos[i],0,wxALIGN_CENTER_HORIZONTAL | wxALL,5);
}
CreateStatusBar(2);
SetStatusText(wxT("wxArduino"));
top->Fit(this);
top->SetSizeHints(this);
}
void Frame::OnSendData(wxTimerEvent &event)
{
for(int i = 0;i < MAX;++i){
data[i] = servos[i]->GetValue();
}
serial.Write(data,MAX);
}
void Frame::OnConnectDevice(wxCommandEvent &event)
{
ConnectArgsDialog dlg(this,wxID_ANY,wxT("Connect"),wxDefaultPosition,wxDefaultSize,wxDEFAULT_DIALOG_STYLE);
if(dlg.ShowModal() == wxID_OK){
serial.Open(dlg.GetDevicePath(),dlg.GetBaudRate());
timer.Start(30);
}
}
void Frame::OnReleaseDevice(wxCommandEvent &event)
{
serial.Close();
timer.Stop();
}
void Frame::OnExit(wxCommandEvent &event)
{
timer.Stop();
Close();
}
connectargsalg.h
#ifndef __CONNECT_ARGS_DIALOG__
#define __CONNECT_ARGS_DIALOG__
#include <wx/wx.h>
#include <windows.h>
class ConnectArgsDialog:public wxDialog
{
public:
ConnectArgsDialog();
ConnectArgsDialog(wxWindow *parent,
wxWindowID id = wxID_ANY,
const wxString &caption = wxT("Connect Args"),
const wxPoint &pos = wxDefaultPosition,
const wxSize &size = wxDefaultSize,
long style = wxCAPTION | wxRESIZE_BORDER | wxSYSTEM_MENU);
bool Create(wxWindow *parent,
wxWindowID id = wxID_ANY,
const wxString &caption = wxT("Connect Args"),
const wxPoint &pos = wxDefaultPosition,
const wxSize &size = wxDefaultSize,
long style = wxCAPTION | wxRESIZE_BORDER | wxSYSTEM_MENU);
void Init();
void CreateControls();
bool TransferDataToWindow();
bool TransferDataFromWindow();
wxString GetDevicePath(){return device_path->GetString(device_path->GetCurrentSelection());}
long GetBaudRate(){return wxAtoi(baud_rate->GetString(baud_rate->GetCurrentSelection()));}
private:
wxChoice *device_path;
wxChoice *baud_rate;
DECLARE_CLASS(ConnectArgsDialog)
};
#endif
connectargsdlg.cpp
#include "connectargsdlg.h"
IMPLEMENT_CLASS(ConnectArgsDialog,wxDialog)
ConnectArgsDialog::ConnectArgsDialog()
{
Init();
}
ConnectArgsDialog::ConnectArgsDialog(wxWindow *parent,wxWindowID id,const wxString &caption,const wxPoint &pos,const wxSize &size,long style)
{
Create(parent,id,caption,pos,size,style);
Init();
}
inline void ConnectArgsDialog::Init()
{
}
bool ConnectArgsDialog::Create(wxWindow *parent,wxWindowID id,const wxString &caption,const wxPoint &pos,const wxSize &size,long style)
{
SetExtraStyle(wxWS_EX_BLOCK_EVENTS | wxDIALOG_EX_CONTEXTHELP);
if(!wxDialog::Create(parent,id,caption,pos,size,style)){
return false;
}
CreateControls();
GetSizer()->Fit(this);
GetSizer()->SetSizeHints(this);
Center();
return true;
}
void ConnectArgsDialog::CreateControls()
{
wxBoxSizer *top = new wxBoxSizer(wxVERTICAL);
this->SetSizer(top);
wxBoxSizer *box = new wxBoxSizer(wxHORIZONTAL);
top->Add(box,0,wxALIGN_CENTER_HORIZONTAL | wxALIGN_CENTER_VERTICAL,5);
wxArrayString paths;
for(int i = 1;i <= 10;++i){
wxString com;
com.Printf(wxT("COM%d"),i);
HANDLE handle = CreateFile(com.wc_str(),GENERIC_READ | GENERIC_WRITE,NULL,NULL,OPEN_EXISTING,FILE_FLAG_OVERLAPPED,NULL);
if(handle != INVALID_HANDLE_VALUE){
paths.Add(com);
CloseHandle(handle);
}
}
device_path = new wxChoice(this,wxID_ANY,wxDefaultPosition,wxDefaultSize,paths);
box->Add(device_path,0,wxALIGN_CENTER_HORIZONTAL | wxALIGN_CENTER_VERTICAL,5);
wxArrayString speed;
speed.Add(wxT("300"));
speed.Add(wxT("1200"));
speed.Add(wxT("2400"));
speed.Add(wxT("4800"));
speed.Add(wxT("9600"));
speed.Add(wxT("19200"));
speed.Add(wxT("38400"));
speed.Add(wxT("57600"));
speed.Add(wxT("115200"));
baud_rate = new wxChoice(this,wxID_ANY,wxDefaultPosition,wxDefaultSize,speed);
box->Add(baud_rate,0,wxALIGN_CENTER_HORIZONTAL | wxALIGN_CENTER_VERTICAL,5);
wxBoxSizer *ResetOkCancelBox = new wxBoxSizer(wxHORIZONTAL);
top->Add(ResetOkCancelBox,0,wxALIGN_CENTER_HORIZONTAL | wxALL,5);
wxButton *ok = new wxButton(this,wxID_OK,wxT("&Ok"),wxDefaultPosition,wxDefaultSize,0);
ResetOkCancelBox->Add(ok,0,wxALIGN_CENTER_VERTICAL | wxALL,5);
wxButton *cancel = new wxButton(this,wxID_CANCEL,wxT("&Cancel"),wxDefaultPosition,wxDefaultSize,0);
ResetOkCancelBox->Add(cancel,0,wxALIGN_CENTER_VERTICAL | wxALL,5);
}
bool ConnectArgsDialog::TransferDataToWindow()
{
return true;
}
bool ConnectArgsDialog::TransferDataFromWindow()
{
return true;
}
serialport.h
#ifndef __SERIAL_PORT__
#define __SERIAL_PORT__
#include <wx/wx.h>
#include <windows.h>
class SerialPort
{
public:
SerialPort();
~SerialPort();
bool Open(const wxString,const DWORD);
void Close();
void Write(unsigned char*,DWORD);
void Read(unsigned char*,DWORD);
private:
HANDLE com;
DCB dcb;
COMMTIMEOUTS timeouts;
OVERLAPPED overlapped;
};
#endif
serialport.cpp
#include "serialport.h"
SerialPort::SerialPort():dcb(),timeouts(),overlapped()
{
com = NULL;
}
SerialPort::~SerialPort()
{
Close();
}
bool SerialPort::Open(const wxString path,const DWORD baud_rate)
{
Close();
com = CreateFile(path.wc_str(),GENERIC_READ | GENERIC_WRITE,NULL,NULL,OPEN_EXISTING,FILE_FLAG_OVERLAPPED,NULL);
if(com == INVALID_HANDLE_VALUE){
Close();
return false;
}
memset(&dcb,0,sizeof(dcb));
wxString def;
def.Printf(wxT("%d,n,8,1"),baud_rate);
BuildCommDCB(def.wc_str(),&dcb);
if(!SetCommState(com,&dcb)){
Close();
return false;
}
memset(&timeouts,0,sizeof(timeouts));
timeouts.ReadIntervalTimeout = MAXDWORD;
timeouts.ReadTotalTimeoutConstant = 0;
timeouts.ReadTotalTimeoutMultiplier = 0;
timeouts.WriteTotalTimeoutConstant = 0;
timeouts.WriteTotalTimeoutMultiplier = 0;
if(!SetCommTimeouts(com,&timeouts)){
Close();
return false;
}
memset(&overlapped,0,sizeof(overlapped));
overlapped.Offset = 0;
overlapped.OffsetHigh = 0;
overlapped.hEvent = CreateEvent(NULL,TRUE,FALSE,NULL);
return true;
}
void SerialPort::Close()
{
if(com){
CloseHandle(com);
com = NULL;
}
}
void SerialPort::Write(unsigned char *data,DWORD length)
{
if(com){
PurgeComm(com, PURGE_RXCLEAR | PURGE_TXCLEAR | PURGE_RXABORT | PURGE_TXABORT);
WriteFile(com,data,length,NULL,&overlapped);
}
}
void SerialPort::Read(unsigned char *data,DWORD length)
{
if(com){
PurgeComm(com, PURGE_RXCLEAR | PURGE_TXCLEAR | PURGE_RXABORT | PURGE_TXABORT);
ReadFile(com,data,length,NULL,&overlapped);
}
}
servo.pde
#include <Servo.h>
const unsigned int MAX = 2;
Servo servos[MAX];
void setup() {
Serial.begin(9600);
for(int i = 0;i < MAX;++i){
servos[i].attach(i + 3);
servos[i].write(90);
}
}
void loop() {
for(int i = 0;Serial.available() > 0;++i){
delay(1); //速度小於1ms接收資料會錯誤
int angle = Serial.read();
servos[i].write(angle);
}
}
沒有留言:
張貼留言