// ADSampleDlg.cpp : implementation file // #include "stdafx.h" #include "ADSample.h" #include "ADSampleDlg.h" #include "DetectDialog.h" #include "aiousb.h" #ifdef _DEBUG #define new DEBUG_NEW #undef THIS_FILE static char THIS_FILE[] = __FILE__; #endif ///////////////////////////////////////////////////////////////////////////// // Task Globals #pragma pack(push, 1) typedef struct { unsigned char ChannelRange[16], CalibMode, TrigMode, StartStopCH, Oversample, AIMUXChEx //AIMUX start and end address bit extension register. ; } TUSBAI1664Config; #pragma pack(pop) int Channels = 64; #define ADTimerID (0x68A) unsigned long DeviceIndex = diOnly; bool bCal = true; TUSBAI1664Config Config; ///////////////////////////////////////////////////////////////////////////// // CADSampleDlg dialog CADSampleDlg::CADSampleDlg(CWnd* pParent /*=NULL*/) : CDialog(CADSampleDlg::IDD, pParent) { //{{AFX_DATA_INIT(CADSampleDlg) m_calFName = _T(""); //}}AFX_DATA_INIT // Note that LoadIcon does not require a subsequent DestroyIcon in Win32 m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME); } void CADSampleDlg::DoDataExchange(CDataExchange* pDX) { CDialog::DoDataExchange(pDX); //{{AFX_DATA_MAP(CADSampleDlg) DDX_Control(pDX, IDC_STOP_BUTTON, m_StopButton); DDX_Control(pDX, IDC_VOLT_LIST, m_VoltList); DDX_Control(pDX, IDC_CAL_EDIT, m_CalEdit); DDX_Control(pDX, IDC_CAL_STATIC, m_CalStatic); DDX_Control(pDX, IDC_GO_BUTTON, m_goBTN); DDX_Control(pDX, IDC_RANGE_COMBO, m_rangeBox); DDX_Text(pDX, IDC_CAL_EDIT, m_calFName); //}}AFX_DATA_MAP } BEGIN_MESSAGE_MAP(CADSampleDlg, CDialog) //{{AFX_MSG_MAP(CADSampleDlg) ON_WM_PAINT() ON_WM_QUERYDRAGICON() ON_CBN_SELCHANGE(IDC_RANGE_COMBO, OnSelchangeRangeCombo) ON_BN_CLICKED(IDC_GO_BUTTON, OnGoButton) ON_WM_TIMER() ON_BN_CLICKED(IDC_STOP_BUTTON, OnStopButton) //}}AFX_MSG_MAP END_MESSAGE_MAP() ///////////////////////////////////////////////////////////////////////////// // CADSampleDlg message handlers // 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 CADSampleDlg::OnPaint() { if (IsIconic()) { CPaintDC dc(this); // device context for painting SendMessage(WM_ICONERASEBKGND, (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 to obtain the cursor to display while the user drags // the minimized window. HCURSOR CADSampleDlg::OnQueryDragIcon() { return (HCURSOR) m_hIcon; } BOOL CADSampleDlg::OnInitDialog() { CDialog::OnInitDialog(); // 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 unsigned long Status, PID, ConfigBufSize; double Hz; //If you only have the one board, QueryDeviceInfo() with diOnly will succeed //with the right PID. If you have more than one board, or haven't plugged it //in, it will fail, and this code will pop up the detector form so the user //can pick a board or cancel. Status = QueryDeviceInfo(DeviceIndex, &PID, NULL, NULL, NULL, NULL); if ( (Status != ERROR_SUCCESS) || ! (((PID >= 0x804A) && (PID <= 0x805D)) || ((PID >= 0x814A) && (PID <= 0x815D))) ) { DetectDialog DetectBox; if ( DetectBox.DoModal() == IDOK ) { DeviceIndex = DetectBox.index; QueryDeviceInfo(DeviceIndex, &PID, NULL, NULL, NULL, NULL); } else { exit(1); } } switch ( PID ) { case 0x804A: case 0x804B: case 0x804C: case 0x804D: case 0x804E: case 0x814A: case 0x814B: case 0x814C: case 0x814D: case 0x814E: Channels = 32; break; case 0x804F: case 0x8050: case 0x8051: case 0x8052: case 0x8053: case 0x814F: case 0x8150: case 0x8151: case 0x8152: case 0x8153: Channels = 64; break; case 0x8054: case 0x8055: case 0x8056: case 0x8057: case 0x8058: case 0x8154: case 0x8155: case 0x8156: case 0x8157: case 0x8158: Channels = 96; break; case 0x8059: case 0x805A: case 0x805B: case 0x805C: case 0x805D: case 0x8159: case 0x815A: case 0x815B: case 0x815C: case 0x815D: Channels = 128; break; } if ( ADC_QueryCal(DeviceIndex) != ERROR_SUCCESS ) { //this board doesn't have calibration bCal = false; m_CalStatic.ModifyStyle(WS_VISIBLE, 0, 0); m_CalEdit.ModifyStyle(WS_VISIBLE, 0, 0); } //Stop the counter, in case it was running. Hz = 0; CTR_StartOutputFreq(DeviceIndex, 0, &Hz); //Set the combo box to the first A/D range, then call OnSelchangeRangeCombo() //to set all the channels to that range. m_rangeBox.SetCurSel(0); OnSelchangeRangeCombo(); ZeroMemory(&Config, sizeof(Config)); Config.CalibMode = 0; //Take actual data, not internal calibration sources. Config.TrigMode = 0x05; //Scan selected channels each counter rising edge. //Config.Oversample = 0; //No oversample. Config.Oversample = 14; //+14 oversample. ConfigBufSize = sizeof(Config); ADC_SetConfig (DeviceIndex, &Config, &ConfigBufSize); m_calFName = ":AUTO:"; UpdateData(false); return TRUE; // return TRUE unless you set the focus to a control } void CADSampleDlg::OnSelchangeRangeCombo() { int I; byte RangeCode; UpdateData(true); //The ranges in the combo box are listed in order, so that the index is equal //to the range code. RangeCode = m_rangeBox.GetCurSel(); //Config.ChannelRange[0] controls channels $00, $10, $20, etc; //Config.ChannelRange[1] controls channels $01, $11, $21, etc; etc. //For simplicity, we set 'em all to the same range. for (I = 0; I <= 0xF; I++) Config.ChannelRange[I] = RangeCode ; m_VoltList.ResetContent(); } void CADSampleDlg::OnGoButton() { unsigned long Status, ConfigBufSize; unsigned char StartChannel, EndChannel; StartChannel = 0; EndChannel = Channels - 1; Config.StartStopCH = (EndChannel << 4) | (StartChannel & 0xF); Config.AIMUXChEx = (EndChannel & 0xF0) | (StartChannel >> 4); ConfigBufSize = sizeof(Config); ADC_SetConfig(DeviceIndex, &Config, &ConfigBufSize); if ( bCal ) { Status = ADC_SetCal(DeviceIndex, m_calFName.GetBuffer(0)); m_calFName.ReleaseBuffer(); if ( Status != ERROR_SUCCESS ) { CString Msg; itoa(Status, Msg.GetBuffer(9), 10); Msg.ReleaseBuffer(); MessageBox("Calibration Error #" + Msg, "Calibration Error", MB_ICONEXCLAMATION); return; } } m_CalEdit.EnableWindow(false); m_rangeBox.EnableWindow(false); m_goBTN.EnableWindow(false); m_StopButton.EnableWindow(true); SetTimer(ADTimerID, 45, NULL); } void CADSampleDlg::OnStopButton() { // TODO: Add your control notification handler code here KillTimer(ADTimerID); m_CalEdit.EnableWindow(true); m_rangeBox.EnableWindow(true); m_goBTN.EnableWindow(true); m_StopButton.EnableWindow(false); } void CADSampleDlg::OnTimer(UINT nIDEvent) { unsigned long Status; double * Volts; Volts = (double *)(malloc(sizeof(Volts[0]) * Channels)); Status = ADC_GetScanV(DeviceIndex, &Volts[0]); if ( Status != ERROR_SUCCESS ) { CString Msg; OnStopButton(); itoa(Status, Msg.GetBuffer(9), 10); Msg.ReleaseBuffer(); Msg = "Error " + Msg + " from ADC_GetScanV."; MessageBox(LPCTSTR(Msg), "ADC_GetScanV Error", MB_ICONEXCLAMATION); } else { CString ChannelData; m_VoltList.ResetContent(); for ( int I = 0; I < Channels; ++I ) { ChannelData.Format("Ch %d: %.4f V", I, Volts[I]); m_VoltList.AddString(ChannelData); } } free(Volts); CDialog::OnTimer(nIDEvent); }