📄 xldaiodemodlg.cpp
字号:
// xlDAIOdemoDlg.cpp : Implementation
//
#include "stdafx.h"
#include "xlDAIOdemo.h"
#include "xlDAIOdemoDlg.h"
#include "vxlapi.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
// *** GLOBAL definitions ***
#define MESSAGECNT 100
BOOL gChannelActivated = FALSE; // our config is valid and channel is activated
unsigned int gLastDigital = 0; // last value of digital inputs
unsigned int gLastAnalog[4]; // last value of analog inputs @@@@
XLaccess gChannelMask = 0; // mask of selected channel
XLportHandle gPort; // global port handles
HANDLE gRxHandle=NULL;
/////////////////////////////////////////////////////////////////////////////
// ReceiveThread - background task receiving messages
unsigned long threadID;
HANDLE threadHandle = NULL;
DWORD WINAPI ReceiveThread (void *param) {
unsigned int msgscnt, ret;
XLevent msgs[MESSAGECNT];
while (TRUE) {
if (gChannelActivated) {
if (gRxHandle) WaitForSingleObject(gRxHandle, 1); else Sleep(1);
msgscnt = MESSAGECNT;
if (xlReceive(gPort, &msgscnt, msgs) != XL_SUCCESS) continue;
for (ret=0;ret<msgscnt;ret++){
if (msgs[ret].tag == XL_RECEIVE_DAIO_DATA) {
gLastDigital = msgs[ret].tagData.daioData.value_digital;
gLastAnalog[0] = msgs[ret].tagData.daioData.value_analog[0];
gLastAnalog[1] = msgs[ret].tagData.daioData.value_analog[1];
gLastAnalog[2] = msgs[ret].tagData.daioData.value_analog[2];
gLastAnalog[3] = msgs[ret].tagData.daioData.value_analog[3];
}
}
} else { // suspend thread when measurement is not running
Sleep(100);
}
}
return 0;
}
/////////////////////////////////////////////////////////////////////////////
// CXlDAIOdemoDlg DialogBox
CXlDAIOdemoDlg::CXlDAIOdemoDlg(CWnd* pParent) : CDialog(CXlDAIOdemoDlg::IDD, pParent) {
//{{AFX_DATA_INIT(CXlDAIOdemoDlg)
m_Analog1 = 0;
m_Analog2 = 0;
m_Analog3 = 0;
m_Analog4 = 0;
m_MeasurementFrequency = 0;
m_PwmValue = 0;
m_PwmFrequency = 0;
m_SelectedChannelName = _T("No channel activated");
//}}AFX_DATA_INIT
m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}
void CXlDAIOdemoDlg::DoDataExchange(CDataExchange* pDX) {
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CXlDAIOdemoDlg)
DDX_Control(pDX, IDC_EDIT4, m_Analog4Ctrl);
DDX_Control(pDX, IDC_EDIT3, m_Analog3Ctrl);
DDX_Control(pDX, IDC_EDIT2, m_Analog2Ctrl);
DDX_Control(pDX, IDC_EDIT1, m_Analog1Ctrl);
DDX_Control(pDX, IDC_LIST2, m_Screen);
DDX_Control(pDX, IDC_SLIDER1, m_PwmValueCtrl);
DDX_Control(pDX, IDC_CHECK4, m_DigitalOut4);
DDX_Control(pDX, IDC_CHECK3, m_DigitalOut3);
DDX_Control(pDX, IDC_CHECK2, m_DigitalOut2);
DDX_Control(pDX, IDC_CHECK1, m_DigitalOut1);
DDX_Control(pDX, IDC_LIST1, m_DigitalStateList);
DDX_Control(pDX, IDC_BUTTON2, m_StopCtrl);
DDX_Control(pDX, IDC_BUTTON1, m_StartCtrl);
DDX_Text(pDX, IDC_EDIT1, m_Analog1);
DDX_Text(pDX, IDC_EDIT2, m_Analog2);
DDX_Text(pDX, IDC_EDIT3, m_Analog3);
DDX_Text(pDX, IDC_EDIT4, m_Analog4);
DDX_CBIndex(pDX, IDC_COMBO1, m_MeasurementFrequency);
DDX_Slider(pDX, IDC_SLIDER1, m_PwmValue);
DDX_CBIndex(pDX, IDC_COMBO2, m_PwmFrequency);
DDX_Text(pDX, IDC_SELECTEDCHANNELNAME, m_SelectedChannelName);
//}}AFX_DATA_MAP
}
BEGIN_MESSAGE_MAP(CXlDAIOdemoDlg, CDialog)
//{{AFX_MSG_MAP(CXlDAIOdemoDlg)
ON_WM_PAINT()
ON_WM_QUERYDRAGICON()
ON_BN_CLICKED(IDC_BUTTON1, OnStart)
ON_BN_CLICKED(IDC_BUTTON2, OnStop)
ON_BN_CLICKED(IDC_BUTTON3, OnSetAnalog)
ON_BN_CLICKED(IDC_CHECK1, OnSetDigital1)
ON_BN_CLICKED(IDC_CHECK2, OnSetDigital2)
ON_BN_CLICKED(IDC_CHECK3, OnSetDigital3)
ON_BN_CLICKED(IDC_CHECK4, OnSetDigital4)
ON_BN_CLICKED(IDC_BUTTON4, OnMeasureNow)
ON_BN_CLICKED(IDC_BUTTON5, OnSetConfiguration)
ON_WM_TIMER()
ON_NOTIFY(NM_RELEASEDCAPTURE, IDC_SLIDER1, OnReleasedcaptureSlider1)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CXlDAIOdemoDlg Message Handler
BOOL CXlDAIOdemoDlg::OnInitDialog() {
CDialog::OnInitDialog();
SetIcon(m_hIcon, TRUE);
SetIcon(m_hIcon, FALSE);
// Start background task, and make sure it is running
threadHandle = CreateThread(NULL, 0, ReceiveThread, 0, 0, &threadID);
if (threadHandle == NULL) {
MessageBox("Error: Cannot start receive thread.");
exit(0);
}
// we will set priority to low, to avoid problems with UI when lot of messages are received
SetThreadPriority(threadHandle, THREAD_PRIORITY_BELOW_NORMAL);
// then we have to setup all dialog controls
m_PwmValueCtrl.SetRange (0, 10000, TRUE); // PWM is in percent value with two decimal places precision
m_PwmValueCtrl.SetTicFreq (1000);
SetTimer(NULL, 250, NULL); // default refresh timer
m_StopCtrl.EnableWindow(FALSE); // channel is not activated
return TRUE;
}
/////////////////////////////////////////////////////////////////////////////
// CXlDAIOdemoDlg OnPaint Function
void CXlDAIOdemoDlg::OnPaint() {
if (IsIconic()) {
CPaintDC dc(this);
SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0);
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;
dc.DrawIcon(x, y, m_hIcon);
} else {
CDialog::OnPaint();
}
}
HCURSOR CXlDAIOdemoDlg::OnQueryDragIcon() {
return (HCURSOR) m_hIcon;
}
/////////////////////////////////////////////////////////////////////////////
// OnCancel - close application correctly
void CXlDAIOdemoDlg::OnCancel() {
OnStop();
if (threadHandle) {
if (TerminateProcess (threadHandle, 0))
CloseHandle( threadHandle );
}
CDialog::OnCancel();
}
/////////////////////////////////////////////////////////////////////////////
// AddMessage - adds message to output window and scrolls it
void CXlDAIOdemoDlg::AddMessage(CString msg) {
m_Screen.InsertString(-1,msg);
m_Screen.SetTopIndex(m_Screen.GetCount( )-1);
}
////////////// FUNCTIONALITY IMPLEMENTATION //////////////////////////////////
/////////////////////////////////////////////////////////////////////////////
// OnTimer - on periodic timer (default 500ms we will update measured values)
void CXlDAIOdemoDlg::OnTimer(UINT nIDEvent) {
unsigned int pos;
CString txt;
if (!gChannelActivated) return;
if (m_DigitalStateList.GetCount() != 8) { // @@@@ // we have wrong content in our output list
m_DigitalStateList.ResetContent();
for (pos = 0; pos < 8; pos++) {
txt.Format ("D %d\tNo data", pos );
m_DigitalStateList.InsertString(pos, txt);
}
}
// update digital input values
for (pos = 0; pos < 8; pos++) {
txt.Format ("D %d\t%s", pos, ((1 << pos) & gLastDigital)? "High":"Low" );
m_DigitalStateList.DeleteString(pos);
m_DigitalStateList.InsertString(pos, txt);
}
txt.Format("%d", gLastAnalog [0]);
m_Analog1Ctrl.SetWindowText(txt);
txt.Format("%d", gLastAnalog [1]);
m_Analog2Ctrl.SetWindowText(txt);
txt.Format("%d", gLastAnalog [2]);
m_Analog3Ctrl.SetWindowText(txt);
txt.Format("%d", gLastAnalog [3]);
m_Analog4Ctrl.SetWindowText(txt);
}
/////////////////////////////////////////////////////////////////////////////
// OnFirstStart - function detects if there is valid configuration, when not tries to update it
// returns false when was already defined
BOOL CXlDAIOdemoDlg::OnFirstStart() {
unsigned int hwType, hwIndex, hwChannel, pos;
XLdriverConfig cfg;
// could we found valid configuration?
if (xlGetApplConfig ("xlDAIOdemo", 0, &hwType, &hwIndex, &hwChannel, XL_BUS_TYPE_DAIO) == XL_SUCCESS) return FALSE;
hwType = 0;
hwIndex = 0;
hwChannel = 0;
// there was not valid configuration, so we will check present hardware
// and use first hardware channel capable to DAIObus or first hardware channel with IOcab inserted
if (xlGetDriverConfig (&cfg) != XL_SUCCESS) return FALSE;
for (pos = 0; pos < cfg.channelCount; pos++) {
// if we have no hardware yet - get first capable
if (!hwType && (cfg.channel[pos].channelBusCapabilities & XL_BUS_COMPATIBLE_DAIO)) {
hwType = cfg.channel[pos].hwType;
hwIndex = cfg.channel[pos].hwIndex;
hwChannel = cfg.channel[pos].hwChannel;
}
// if there is IOcab inserted, than take this one and leave
if (cfg.channel[pos].channelBusCapabilities & XL_BUS_ACTIVE_CAP_DAIO) {
hwType = cfg.channel[pos].hwType;
hwIndex = cfg.channel[pos].hwIndex;
hwChannel = cfg.channel[pos].hwChannel;
xlSetApplConfig ("xlDAIOdemo", 0, hwType, hwIndex, hwChannel, XL_BUS_TYPE_DAIO);
return TRUE;
}
}
// if we have some change, update it
if (hwType) {
xlSetApplConfig ("xlDAIOdemo", 0, hwType, hwIndex, hwChannel, XL_BUS_TYPE_DAIO);
return TRUE;
}
return FALSE;
}
/////////////////////////////////////////////////////////////////////////////
// OnStart - starts the channel with DAIO bus
void CXlDAIOdemoDlg::OnStart() {
unsigned int hwType, hwIndex, hwChannel, pos;
XLaccess initAccess;
XLdriverConfig cfg;
if (gChannelActivated) return;
xlOpenDriver();
if (OnFirstStart()) {
xlPopupHwConfig (NULL, 0);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -