// ModbucfgView.cpp : implementation of the CModbucfgView class // #include "stdafx.h" #include "Modbucfg.h" #include "ModbucfgDoc.h" #include "ModbucfgView.h" #include ".\modbucfgview.h" #ifdef _DEBUG #define new DEBUG_NEW #undef THIS_FILE static char THIS_FILE[] = __FILE__; #endif ///////////////////////////////////////////////////////////////////////////// // CModbucfgView IMPLEMENT_DYNCREATE(CModbucfgView, CFormView) BEGIN_MESSAGE_MAP(CModbucfgView, CFormView) //{{AFX_MSG_MAP(CModbucfgView) ON_BN_CLICKED(IDC_CHK_Enable_Poll, OnchkEnablePoll) ON_EN_CHANGE(IDC_EDIT_INTERVAL, OnChangeEditInterval) ON_BN_CLICKED(IDC_CMD_WRITE, OnCmdWrite) //}}AFX_MSG_MAP ON_CBN_SELCHANGE(IDC_CBO_READ_FUNCTION, OnCbnSelchangeCboReadFunction) ON_CBN_SELCHANGE(IDC_CBO_WRITE_FUNCTION, OnCbnSelchangeCboWriteFunction) ON_COMMAND(ID_APP_MEM_MAP, OnAppMemMap) ON_EN_CHANGE(IDC_EDIT_QUANT, OnEnChangeEditQuant) ON_EN_CHANGE(IDC_EDIT_ADDR, OnEnChangeEditAddr) ON_EN_CHANGE(IDC_EDIT_QUANT_2, OnEnChangeEditQuant2) ON_LBN_SELCHANGE(IDC_LIST5, OnLbnSelchangeList5) ON_LBN_SELCHANGE(IDC_LST_VALUES, OnLbnSelchangeLstValues) ON_EN_CHANGE(IDC_EDIT_ADDR_WRI, OnEnChangeEditAddrWri) ON_EN_CHANGE(IDC_EDIT_VALUE, OnEnChangeEditValue) ON_WM_VSCROLL() ON_BN_CLICKED(IDC_CMD_READ, OnCmdRead) ON_EN_CHANGE(IDC_EDIT16, OnEnChangeEdit16) ON_BN_CLICKED(IDC_BUTTON1, OnBnClickedButton1) ON_BN_CLICKED(IDC_BUTTON2, OnBnClickedButton2) END_MESSAGE_MAP() ///////////////////////////////////////////////////////////////////////////// // CModbucfgView construction/destruction CModbucfgView::CModbucfgView() : CFormView(CModbucfgView::IDD) /* , m_edtQuant2(false) , m_edtQuant2(_T(""))*/ , m_spinIndex(0) { //{{AFX_DATA_INIT(CModbucfgView) //}}AFX_DATA_INIT // TODO: add construction code here } CModbucfgView::~CModbucfgView() { } void CModbucfgView::DoDataExchange(CDataExchange* pDX) { CFormView::DoDataExchange(pDX); //{{AFX_DATA_MAP(CModbucfgView) DDX_Control(pDX, IDC_CBO_DATA_TYPE, m_cboDataType); DDX_Control(pDX, IDC_EDIT_INTERVAL, m_edtInterval); DDX_Control(pDX, IDC_CHK_Enable_Poll, m_butPollEnable); DDX_Control(pDX, IDC_STAT_STATUS, m_statStatus); DDX_Control(pDX, IDC_STAT_ERROR, m_staError); DDX_Control(pDX, IDC_LST_VALUES, m_lstValues); DDX_Control(pDX, IDC_CBO_WRITE_FUNCTION, m_cboWriteFunctions); DDX_Control(pDX, IDC_CBO_READ_FUNCTION, m_cboReadFunctions); DDX_Control(pDX, IDC_CBO_CONNECTION, m_cboConnections); DDX_Control(pDX, IDC_EDIT_VALUE, m_edtValue); DDX_Control(pDX, IDC_EDIT_QUANT, m_edtQuant); DDX_Control(pDX, IDC_EDIT_DEVICE, m_edtDevice); DDX_Control(pDX, IDC_EDIT_ADDR_WRI, m_edtWriteAddr); DDX_Control(pDX, IDC_EDIT_ADDR, m_edtReadAddr); DDX_Control(pDX, IDC_CMD_WRITE, m_cmdWrite); //}}AFX_DATA_MAP DDX_Control(pDX, IDC_EDIT_QUANT_2, m_edtQuant2); // DDX_Control(pDX, IDC_LIST5, m_list5Values); DDX_Control(pDX, IDC_EDIT6, m_edtIndex); DDX_Text(pDX, IDC_EDIT6, m_spinIndex); DDX_Control(pDX, IDC_EDIT3, m_readEil); DDX_Control(pDX, IDC_EDIT5, m_readSVd); DDX_Control(pDX, IDC_EDIT7, m_readSVfin); DDX_Control(pDX, IDC_EDIT8, m_readSV1); DDX_Control(pDX, IDC_EDIT9, m_readSV2); DDX_Control(pDX, IDC_EDIT10, m_readdtp); DDX_Control(pDX, IDC_EDIT11, m_readdt); DDX_Control(pDX, IDC_EDIT12, m_readdP); DDX_Control(pDX, IDC_EDIT13, m_readdPsecu); DDX_Control(pDX, IDC_EDIT14, m_readSVil); DDX_Control(pDX, IDC_EDIT15, m_readSleil); DDX_Control(pDX, IDC_EDIT16, m_readSTc); DDX_Control(pDX, IDC_EDIT17, m_readNbal_max); DDX_Control(pDX, IDC_EDIT18, m_readFr); DDX_Control(pDX, IDC_EDIT19, m_readN_cur); DDX_Control(pDX, IDC_CMD_READ, m_cmdRead); DDX_Control(pDX, IDC_EDIT4, m_readNil); DDX_Control(pDX, IDC_EDIT20, m_readNil_stat); DDX_Control(pDX, IDC_EDIT21, m_readP_last); DDX_Control(pDX, IDC_EDIT22, m_readN_last); DDX_Control(pDX, IDC_EDIT23, m_readdPil); DDX_Control(pDX, IDC_EDIT24, m_readV_cur); DDX_Control(pDX, IDC_EDIT25, m_readPic); DDX_Control(pDX, IDC_EDIT26, m_readTimer); DDX_Control(pDX, IDC_EDIT27, m_readNbal); DDX_Control(pDX, IDC_EDIT28, m_readP_cde); DDX_Control(pDX, IDC_EDIT29, m_readPp); DDX_Control(pDX, IDC_EDIT30, m_readStat_C_1); DDX_Control(pDX, IDC_EDIT31, m_readStat_C_2); DDX_Control(pDX, IDC_EDIT32, m_readStat_C_3); DDX_Control(pDX, IDC_EDIT33, m_readStat_C_4); DDX_Control(pDX, IDC_EDIT34, m_readStat_C_5); DDX_Control(pDX, IDC_EDIT35, m_readStat_C_6); DDX_Control(pDX, IDC_EDIT36, m_readStat_C_7); DDX_Control(pDX, IDC_EDIT37, m_readStat_C_8); DDX_Control(pDX, IDC_EDIT38, m_readNum_C1a); DDX_Control(pDX, IDC_EDIT39, m_readNum_C1b); DDX_Control(pDX, IDC_EDIT40, m_readNum_C2a); DDX_Control(pDX, IDC_EDIT41, m_readNum_C2b); DDX_Control(pDX, IDC_EDIT42, m_readNum_C3a); DDX_Control(pDX, IDC_EDIT43, m_readNum_C3b); DDX_Control(pDX, IDC_EDIT44, m_readNum_C4a); DDX_Control(pDX, IDC_EDIT45, m_readNum_C4b); DDX_Control(pDX, IDC_EDIT54, m_readN_Seqcond); DDX_Control(pDX, IDC_EDIT57, m_readMAP); DDX_Control(pDX, IDC_EDIT46, m_readTemp_cond_1); DDX_Control(pDX, IDC_EDIT47, m_readTemp_cond_2); DDX_Control(pDX, IDC_EDIT48, m_readTemp_cond_3); DDX_Control(pDX, IDC_EDIT49, m_readTemp_cond_4); DDX_Control(pDX, IDC_EDIT50, m_readTemp_cond_5); DDX_Control(pDX, IDC_EDIT51, m_readTemp_cond_6); DDX_Control(pDX, IDC_EDIT52, m_readTemp_cond_7); DDX_Control(pDX, IDC_EDIT53, m_readTemp_cond_8); DDX_Control(pDX, IDC_EDIT58, m_readStat_C_9); DDX_Control(pDX, IDC_EDIT59, m_readStat_C_10); DDX_Control(pDX, IDC_EDIT60, m_readStat_C_11); DDX_Control(pDX, IDC_EDIT61, m_readStat_C_12); DDX_Control(pDX, IDC_EDIT62, m_readTemp_cond_9); DDX_Control(pDX, IDC_EDIT63, m_readTemp_cond_10); DDX_Control(pDX, IDC_EDIT64, m_readTemp_cond_11); DDX_Control(pDX, IDC_EDIT65, m_readTemp_cond_12); } BOOL CModbucfgView::PreCreateWindow(CREATESTRUCT& cs) { // TODO: Modify the Window class or styles here by modifying // the CREATESTRUCT cs return CFormView::PreCreateWindow(cs); } ///////////////////////////////////////////////////////////////////////////// // CModbucfgView diagnostics #ifdef _DEBUG void CModbucfgView::AssertValid() const { CFormView::AssertValid(); } void CModbucfgView::Dump(CDumpContext& dc) const { CFormView::Dump(dc); } CModbucfgDoc* CModbucfgView::GetDocument() // non-debug version is inline { ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CModbucfgDoc))); return (CModbucfgDoc*)m_pDocument; } #endif //_DEBUG ///////////////////////////////////////////////////////////////////////////// // CModbucfgView message handlers void CModbucfgView::OnInitialUpdate() { CFormView::OnInitialUpdate(); // TODO: Add your specialized code here and/or call the base class LoadControls(); //Dans le cas d'une CFormView, les ascenseurs apparaissent automatiquement dès que //la surface cliente de la fenêtre devient trop petite par rapport à la surface réelle. //pour ne pas avoir à gérer les ascenseurs, je les supprime: une CFormView hérite de la classe CSCrollView //qui dispose de la fonction SetScaleToFitSize pour adapter la surface de la fenêtre à la taille fenêtrée CRect Rect; GetParentFrame()->GetWindowRect(&Rect); SIZE size; size.cx=Rect.Width(); size.cy=Rect.Height(); SetScaleToFitSize(size); //controle spin CSpinButtonCtrl* pSpin=(CSpinButtonCtrl*)GetDlgItem(IDC_SPIN2); pSpin->SetRange(0,100);//plage du control : 0-100 pSpin->SetPos((int)m_spinIndex * 1);//valeur initiale 1 //tableaux pour les write multiple m_bValueMultiple.SetSize(100); m_sValueMultiple.SetSize(100); m_wValueMultiple.SetSize(100); m_fValueMultiple.SetSize(100); m_dValueMultiple.SetSize(100); } void CModbucfgView::LoadControls() { CString str; CString sKey; CConnection* pConnection; POSITION pos; //Read functions m_cboReadFunctions.AddString(CString("LoopbackTest")); m_cboReadFunctions.AddString(CString("Holding Registers")); m_cboReadFunctions.AddString(CString("Input Registers")); m_cboReadFunctions.AddString(CString("Coil Status")); m_cboReadFunctions.AddString(CString("Discrete Inputs")); m_cboReadFunctions.SetCurSel(1); //Write Functions m_cboWriteFunctions.AddString(CString("Single Register")); m_cboWriteFunctions.AddString(CString("Single Coil")); m_cboWriteFunctions.AddString(CString("Multiple Registers")); m_cboWriteFunctions.AddString(CString("Multiple Coils")); m_cboWriteFunctions.SetCurSel(0); pos = gConnections.GetStartPosition(); m_cboConnections.ResetContent(); while (NULL!=pos) { gConnections.GetNextAssoc(pos,sKey,pConnection); m_cboConnections.AddString(sKey); } m_cboConnections.SetCurSel(0); //Default Values str=_T("1"); m_edtDevice.SetWindowText(str); str=_T("0"); m_edtValue.SetWindowText(str); m_edtWriteAddr.SetWindowText(str); m_edtReadAddr.SetWindowText(str); str=_T("10"); m_edtQuant.SetWindowText(str); str=_T("1000"); m_edtInterval.SetWindowText(str); str=_T("10"); m_edtQuant2.SetWindowText(str); //Data Type m_cboDataType.AddString(CString("char")); m_cboDataType.AddString(CString("signed - 16")); m_cboDataType.AddString(CString("unsigned - 16")); m_cboDataType.AddString(CString("float - 32")); m_cboDataType.AddString(CString("float - 32 reverse")); m_cboDataType.AddString(CString("double - 64")); m_cboDataType.AddString(CString("double - 64 reverse")); m_cboDataType.SetCurSel(1); //associe la variable m_readVacuum à la ressource IDC_LIST2 m_readVacuum = (CListCtrl*)GetDlgItem (IDC_LIST2); // m_readVacuum->SetExtendedStyle(LVS_REPORT | LVS_EX_FULLROWSELECT); //ajout des titres m_readVacuum->InsertColumn(0,_T("Name"),LVCFMT_CENTER,50); m_readVacuum->InsertColumn(1,_T("value(mbar)"),LVCFMT_CENTER,100); m_readVacuum->SetBkColor(RGB(202,202,255)); //nb de lignes // m_readVacuum->SetItemCount(12); //init tableau for (int i=0;i < 12;i++) { str.Format(TEXT("V%d"), i+1); // Insert the item, select every other item. m_readVacuum->InsertItem(LVIF_TEXT|LVIF_STATE, i, str, (i%2)==0 ? LVIS_SELECTED : 0, LVIS_SELECTED,0, 0); m_readVacuum->SetItemText(i,1,"0"); } //associe la variable m_readCondParam à la ressource IDC_LIST3 m_readCondParam = (CListCtrl*)GetDlgItem (IDC_LIST3); // m_readCondParam->SetExtendedStyle(LVS_REPORT | LVS_EX_FULLROWSELECT); //ajout des titres m_readCondParam->InsertColumn(0,_T("step number"),LVCFMT_CENTER,40); m_readCondParam->InsertColumn(1,_T("Pi_min"),LVCFMT_CENTER,50); m_readCondParam->InsertColumn(1,_T("Pi_max"),LVCFMT_CENTER,50); m_readCondParam->InsertColumn(1,_T("Tn_max"),LVCFMT_CENTER,50); m_readCondParam->InsertColumn(1,_T("Tp_max"),LVCFMT_CENTER,50); m_readCondParam->InsertColumn(1,_T("Ln(us)"),LVCFMT_CENTER,50); //init tableau for (int i=0;i < 12;i++) { str.Format(TEXT("%d"), i+1); // Insert the item, select every other item. m_readCondParam->InsertItem(LVIF_TEXT|LVIF_STATE, i, str, (i%2)==0 ? LVIS_SELECTED : 0, LVIS_SELECTED,0, 0); } } void CModbucfgView::StartWork() { SCODE sc = ::CoInitializeEx(NULL,COINIT_MULTITHREADED); //SCODE sc = ::CoInitializeEx(NULL,COINIT_APARTMENTTHREADED); if (FAILED(sc)) { // warn about non-NULL success codes TRACE1("Warning: OleInitialize returned scode = %x",sc); } m_dwCount=0; m_dwSum=0; m_dwErrors=0; } void CModbucfgView::DoWork() { ldiv_t div_result; float fUpdateSpeed; DWORD dwTime; CString str; WORD nError; static int iFunction=0; int iNumLoops=10; fUpdateSpeed=0.0; if ((m_cboReadFunctions.GetCurSel()>=LOOP_BACK_TEST)&& (m_cboReadFunctions.GetCurSel()<=READ_INPUT_STATUS)){ m_dwCount++; // nError=ExecuteReadFunction(m_cboReadFunctions.GetCurSel(),dwTime,str); nError=ExecuteReadFunction(iFunction++,dwTime,str); if (iFunction==6)iFunction=0; m_dwSum +=dwTime; div_result = ldiv(m_dwCount,iNumLoops); if (CModbus::ERR_OK!=nError){ m_dwErrors++; } if (0==div_result.rem){ fUpdateSpeed=(float)(iNumLoops*1000)/(float)m_dwSum; m_dwSum=0; } else { fUpdateSpeed=(float)(1*1000)/(float)dwTime; } m_staError.SetWindowText(str); str.Format("%d Errors=%d %4.2f(Up./s) ",m_dwCount,m_dwErrors,fUpdateSpeed); m_statStatus.SetWindowText(str); } } void CModbucfgView::EndWork() { ::CoUninitialize(); } void CModbucfgView::OnchkEnablePoll() { CString sText; DWORD dwInterval=0; m_edtInterval.GetWindowText(sText); dwInterval=DWORD(atol(sText)); // if (dwInterval>10000) { if ((dwInterval>10000) || (dwInterval<200)) { AfxMessageBox("Max. is 10000 ms and Min. is 200 ms"); dwInterval=10000; sText.Format("%d",dwInterval); m_edtInterval.SetWindowText(sText); return; } if (0!=m_butPollEnable.GetCheck()) { if (!IsBusy()) { CreateThread(0,0,NULL,dwInterval); } m_butPollEnable.SetCheck(1); } else { Stop(); } } WORD CModbucfgView::ExecuteReadFunction(int iFunction,DWORD& dwTime, CString& rErrorMessage) { CModbus* pModbus; CShortArray aValues; CByteArray abCoilValues; CFloatArray afValues; CDblArray adValues; CString str; CString sAux; WORD nError; int i; BOOL bRegisters; DWORD dwStart; CString sKey; CConnection* pConnection =NULL; BYTE byDevice; WORD wQuant; WORD wAddr; int nIndex; int nPreviusCount; int iDataType; CListCtrl* vacuum = (CListCtrl*)GetDlgItem (IDC_LIST2); CListCtrl* parameters = (CListCtrl*)GetDlgItem (IDC_LIST3); i=m_cboConnections.GetCurSel(); if (i<0) { return 0; } else { m_cboConnections.GetLBText(i,sKey); if (gConnections.Lookup(sKey,pConnection)) { pModbus=pConnection->m_pModbus; } else { ASSERT(FALSE); return 0; } } m_edtDevice.GetWindowText(str); byDevice=BYTE(atoi(str)); switch (iFunction) { case 0: //coils : case READ_OUTPUT_STATUS wQuant=13; abCoilValues.SetSize(wQuant); wAddr=3000; nError=pModbus->ReadOutputStatus(byDevice,wAddr,wQuant, abCoilValues); str.Format("%d",abCoilValues[0]); m_readEil.SetWindowText(str); str.Format("%d",abCoilValues[1]); m_readStat_C_1.SetWindowText(str); str.Format("%d",abCoilValues[2]); m_readStat_C_2.SetWindowText(str); str.Format("%d",abCoilValues[3]); m_readStat_C_3.SetWindowText(str); str.Format("%d",abCoilValues[4]); m_readStat_C_4.SetWindowText(str); str.Format("%d",abCoilValues[5]); m_readStat_C_5.SetWindowText(str); str.Format("%d",abCoilValues[6]); m_readStat_C_6.SetWindowText(str); str.Format("%d",abCoilValues[7]); m_readStat_C_7.SetWindowText(str); str.Format("%d",abCoilValues[8]); m_readStat_C_8.SetWindowText(str); str.Format("%d",abCoilValues[9]); m_readStat_C_9.SetWindowText(str); str.Format("%d",abCoilValues[10]); m_readStat_C_10.SetWindowText(str); str.Format("%d",abCoilValues[11]); m_readStat_C_11.SetWindowText(str); str.Format("%d",abCoilValues[12]); m_readStat_C_12.SetWindowText(str); break; case 1: //holdings : case READ_OUTPUT_REGISTERS: // iDataType = DATA_UNSIGNED_16; wQuant=125; aValues.SetSize(wQuant); wAddr=2000; nError=pModbus->ReadOutputRegisters(byDevice,wAddr,wQuant, aValues); str.Format("%d",aValues[0]); m_readSVd.SetWindowText(str); str.Format("%d",aValues[1]); m_readSVfin.SetWindowText(str); str.Format("%d",aValues[2]); m_readSV1.SetWindowText(str); str.Format("%d",aValues[3]); m_readSV2.SetWindowText(str); str.Format("%d",aValues[4]); m_readdtp.SetWindowText(str); str.Format("%d",aValues[5]); m_readdt.SetWindowText(str); str.Format("%d",aValues[20]); m_readSVil.SetWindowText(str); str.Format("%d",aValues[25]); m_readNbal_max.SetWindowText(str); str.Format("%d",aValues[26]); m_readFr.SetWindowText(str); str.Format("%d",aValues[27]); m_readN_cur.SetWindowText(str); str.Format("%d",aValues[30]); m_readNil.SetWindowText(str); str.Format("%d",aValues[31]); m_readNil_stat.SetWindowText(str); str.Format("%d",aValues[34]); m_readN_last.SetWindowText(str); str.Format("%d",aValues[37]); m_readV_cur.SetWindowText(str); str.Format("%d",(aValues[40]<<16)+aValues[41]);//2 mots de 16 bits m_readTimer.SetWindowText(str); str.Format("%d",aValues[42]); m_readNbal.SetWindowText(str); str.Format("%d",aValues[47]); m_readN_Seqcond.SetWindowText(str); str.Format("%d",aValues[48]); m_readMAP.SetWindowText(str); str.Format("%d",aValues[50]); m_readNum_C1a.SetWindowText(str); str.Format("%d",aValues[51]); m_readNum_C1b.SetWindowText(str); str.Format("%d",aValues[52]); m_readNum_C2a.SetWindowText(str); str.Format("%d",aValues[53]); m_readNum_C2b.SetWindowText(str); str.Format("%d",aValues[54]); m_readNum_C3a.SetWindowText(str); str.Format("%d",aValues[55]); m_readNum_C3b.SetWindowText(str); str.Format("%d",aValues[56]); m_readNum_C4a.SetWindowText(str); str.Format("%d",aValues[57]); m_readNum_C4b.SetWindowText(str); str.Format("%d",(aValues[58]<<16)+aValues[59]);//2 mots de 16 bits m_readTemp_cond_1.SetWindowText(str); str.Format("%d",(aValues[60]<<16)+aValues[61]);//2 mots de 16 bits m_readTemp_cond_2.SetWindowText(str); str.Format("%d",(aValues[62]<<16)+aValues[63]);//2 mots de 16 bits m_readTemp_cond_3.SetWindowText(str); str.Format("%d",(aValues[64]<<16)+aValues[65]);//2 mots de 16 bits m_readTemp_cond_4.SetWindowText(str); str.Format("%d",(aValues[66]<<16)+aValues[67]);//2 mots de 16 bits m_readTemp_cond_5.SetWindowText(str); str.Format("%d",(aValues[68]<<16)+aValues[69]);//2 mots de 16 bits m_readTemp_cond_6.SetWindowText(str); str.Format("%d",(aValues[70]<<16)+aValues[71]);//2 mots de 16 bits m_readTemp_cond_7.SetWindowText(str); str.Format("%d",(aValues[72]<<16)+aValues[73]);//2 mots de 16 bits m_readTemp_cond_8.SetWindowText(str); str.Format("%d",(aValues[74]<<16)+aValues[75]);//2 mots de 16 bits m_readTemp_cond_9.SetWindowText(str); str.Format("%d",(aValues[76]<<16)+aValues[77]);//2 mots de 16 bits m_readTemp_cond_10.SetWindowText(str); str.Format("%d",(aValues[78]<<16)+aValues[79]);//2 mots de 16 bits m_readTemp_cond_11.SetWindowText(str); str.Format("%d",(aValues[80]<<16)+aValues[81]);//2 mots de 16 bits m_readTemp_cond_12.SetWindowText(str); break; case 2: //holdings : case READ_OUTPUT_REGISTERS: // iDataType = DATA_FLOAT; wQuant=17; afValues.SetSize(wQuant); wAddr=2006; nError=pModbus->ReadOutputRegisters(byDevice,wAddr,wQuant, afValues); str.Format("%g",afValues[0]); m_readdP.SetWindowText(str); str.Format("%g",afValues[1]); m_readdPsecu.SetWindowText(str); str.Format("%g",afValues[13]); m_readP_last.SetWindowText(str); str.Format("%g",afValues[16]); m_readPic.SetWindowText(str); break; case 3: //holdings : case READ_OUTPUT_REGISTERS: // iDataType = DATA_FLOAT; wQuant=24; afValues.SetSize(wQuant); wAddr=2021; nError=pModbus->ReadOutputRegisters(byDevice,wAddr,wQuant, afValues); str.Format("%g",afValues[0]); m_readSleil.SetWindowText(str); str.Format("%g",afValues[1]); m_readSTc.SetWindowText(str); str.Format("%g",afValues[7]); m_readdPil.SetWindowText(str); str.Format("%g",afValues[11]); m_readP_cde.SetWindowText(str); str.Format("%g",afValues[12]); m_readPp.SetWindowText(str); break; case 4: //holdings : case READ_OUTPUT_REGISTERS: // iDataType = DATA_FLOAT; wQuant=24; afValues.SetSize(wQuant); wAddr=/*2108*/2116; nError=pModbus->ReadOutputRegisters(byDevice,wAddr,wQuant, afValues); //Pi_max for (int i=0;i < 12;i++) { str.Format("%g",afValues[i]); parameters->SetItemText(i,4,str); } //Pi_min for (int i=12;i < 24;i++) { str.Format("%g",afValues[i]); parameters->SetItemText(i-12,5,str); } break; case 5: //holdings : case READ_OUTPUT_REGISTERS: // iDataType = DATA_UNSIGNED_16; wQuant=125; aValues.SetSize(wQuant); wAddr=2080; nError=pModbus->ReadOutputRegisters(byDevice,wAddr,wQuant, aValues); //Ln for (int i=0;i < 12;i++) { str.Format("%d",aValues[i]); parameters->SetItemText(i,1,str); } //Tn_max for (int i=12;i < 24;i++) { str.Format("%d",aValues[i]); parameters->SetItemText(i-12,3,str); } //Tp_max : 12 mots de 16 bits ???? for (int i=24;i < 36;i++) { str.Format("%d",aValues[i]); parameters->SetItemText(i-24,2,str); } //vacuum for (int i=90;i < 102;i++) { str.Format("%d",aValues[i]); vacuum->SetItemText(i-90,1,str); } break; } rErrorMessage=pModbus->ErrorMessage(nError); return nError; } void CModbucfgView::OnChangeEditInterval() { CString sText; DWORD dwInterval=0; m_edtInterval.GetWindowText(sText); dwInterval=DWORD(atol(sText)); // if (dwInterval>10000) { // AfxMessageBox("Max. Interval is 10000 ms"); if ((dwInterval>10000) || (dwInterval<200)) { AfxMessageBox("Max. is 10000 ms and Min. is 200 ms"); dwInterval=10000; sText.Format("%d",dwInterval); m_edtInterval.SetWindowText(sText); return; } SetCycleTime(int(dwInterval)); } void CModbucfgView::OnCmdWrite() { BYTE byDevice=0; WORD wValue=0; WORD wAddr=0; CModbus* pModbus=GetConnection(); WORD nError=CModbus::ERR_OK; CString strValue; CString sVal; CWaitCursor WaitCursor; double dValue=0.0; WORD wQuant, wIndex; if (NULL==pModbus) { return; } m_edtValue.GetWindowText(strValue); sVal= strValue; wValue = (WORD)atoi(strValue); m_edtDevice.GetWindowText(strValue); byDevice = (BYTE)atoi(strValue); m_edtWriteAddr.GetWindowText(strValue); wAddr = (WORD)atoi(strValue); m_edtQuant2.GetWindowText(strValue); wQuant=(BYTE)(atoi(strValue)); m_edtIndex.GetWindowText(strValue); wIndex=(BYTE)(atoi(strValue)); switch (m_cboWriteFunctions.GetCurSel()) { case PRESET_SINGLE_REGISTER: switch(m_cboDataType.GetCurSel()) { case DATA_CHAR: sVal.TrimLeft(); if (sVal.GetLength()>0) { nError=pModbus->PresetSingleRegister(byDevice,wAddr,WORD(sVal[0])); } break; case DATA_SIGNED_16: case DATA_UNSIGNED_16: if (sVal.GetLength()>0) { nError=pModbus->PresetSingleRegister(byDevice,wAddr,WORD(atoi(sVal))); } break; case DATA_FLOAT: nError=pModbus->PresetSingleRegister(byDevice,wAddr,float(atof(sVal))); break; case DATA_FLOAT_REVERSE: nError=pModbus->PresetSingleRegister(byDevice,wAddr,float(atof(sVal)),CModbus::REAL_REVERSE); break; case DATA_DOUBLE: nError=pModbus->PresetSingleRegister(byDevice,wAddr,double(atof(sVal))); break; case DATA_DOUBLE_REVERSE: nError=pModbus->PresetSingleRegister(byDevice,wAddr,double(atof(sVal)),CModbus::REAL_REVERSE); break; } if(nError!=CModbus::ERR_OK){ WaitCursor.Restore(); AfxMessageBox(pModbus->ErrorMessage(nError)); } break; case FORCE_SINGLE_COIL: nError=pModbus->ForceSingleCoil(byDevice,wAddr,(BOOL)wValue); if(nError!=CModbus::ERR_OK){ WaitCursor.Restore(); AfxMessageBox(pModbus->ErrorMessage(nError)); } break; case WRITE_MULTIPLE_REGISTERS: { //controle spin CSpinButtonCtrl* pSpin=(CSpinButtonCtrl*)GetDlgItem(IDC_SPIN2); switch(m_cboDataType.GetCurSel()) { case DATA_CHAR: sVal.TrimLeft(); if (sVal.GetLength()>0) { m_sValueMultiple.SetAt(wIndex,wValue); nError=pModbus->PresetMultipleRegisters(byDevice,wAddr,wQuant,m_sValueMultiple); } break; case DATA_SIGNED_16: case DATA_UNSIGNED_16: if (sVal.GetLength()>0) { m_wValueMultiple.SetAt(wIndex,wValue); nError=pModbus->PresetMultipleRegisters(byDevice,wAddr,wQuant,m_wValueMultiple); } break; case DATA_FLOAT: m_fValueMultiple.SetAt(wIndex,wValue); nError=pModbus->PresetMultipleRegisters(byDevice,wAddr,wQuant,m_fValueMultiple); break; case DATA_FLOAT_REVERSE: m_fValueMultiple.SetAt(wIndex,wValue); nError=pModbus->PresetMultipleRegisters(byDevice,wAddr,wQuant,m_fValueMultiple,CModbus::REAL_REVERSE); break; case DATA_DOUBLE: m_dValueMultiple.SetAt(wIndex,wValue); nError=pModbus->PresetMultipleRegisters(byDevice,wAddr,wQuant,m_dValueMultiple); break; case DATA_DOUBLE_REVERSE: m_dValueMultiple.SetAt(wIndex,wValue); nError=pModbus->PresetMultipleRegisters(byDevice,wAddr,wQuant,m_dValueMultiple,CModbus::REAL_REVERSE); break; } if(nError!=CModbus::ERR_OK){ WaitCursor.Restore(); AfxMessageBox(pModbus->ErrorMessage(nError)); } } break; case WRITE_MULTIPLE_COILS: { //controle spin CSpinButtonCtrl* pSpin=(CSpinButtonCtrl*)GetDlgItem(IDC_SPIN2); // pSpin->SetRange(0,100);//plage du control : 0-100 m_bValueMultiple.SetAt(wIndex,((wValue!=0)?1:0)); nError=pModbus->ForceMultipleCoils(byDevice,wAddr,wQuant,m_bValueMultiple); if(nError!=CModbus::ERR_OK){ WaitCursor.Restore(); AfxMessageBox(pModbus->ErrorMessage(nError)); } } break; } } CModbus* CModbucfgView::GetConnection() { int i; CModbus* pModbus=NULL; CConnection* pConnection=NULL; CString sKey; i=m_cboConnections.GetCurSel(); if (i<0) { ASSERT(FALSE); pModbus=NULL; } else { m_cboConnections.GetLBText(i,sKey); if (gConnections.Lookup(sKey,pConnection)) { pModbus=pConnection->m_pModbus; } else { ASSERT(FALSE); pModbus=NULL; } } return pModbus; } void CModbucfgView::OnCbnSelchangeCboReadFunction() { // TODO : ajoutez ici le code de votre gestionnaire de notification de contrôle } void CModbucfgView::OnCbnSelchangeCboWriteFunction() { // TODO : ajoutez ici le code de votre gestionnaire de notification de contrôle } void CModbucfgView::OnAppMemMap() { // TODO : ajoutez ici le code de votre gestionnaire de commande AfxMessageBox(_T("modbus memory map : \n\n -holding registers adr:0x2000 qty:300\n-coils adr:0x3000 qty:100\n-discrete inputs adr:0x1000 qty:4\n-input registers adr:0x4000 qty:4")); } void CModbucfgView::OnEnChangeEditQuant() { // TODO : S'il s'agit d'un contrôle RICHEDIT, le contrôle // n'enverra la notification que si vous substituez la fonction __super::OnInitDialog() // et l'appel CRichEditCtrl().SetEventMask() // par l'indicateur ENM_CHANGE assorti de l'opérateur OR dans le masque. // TODO : Ajoutez ici le code de votre gestionnaire de notification de contrôle } void CModbucfgView::OnEnChangeEditAddr() { // TODO : S'il s'agit d'un contrôle RICHEDIT, le contrôle // n'enverra la notification que si vous substituez la fonction __super::OnInitDialog() // et l'appel CRichEditCtrl().SetEventMask() // par l'indicateur ENM_CHANGE assorti de l'opérateur OR dans le masque. // TODO : Ajoutez ici le code de votre gestionnaire de notification de contrôle } void CModbucfgView::OnEnChangeEditQuant2() { // TODO : S'il s'agit d'un contrôle RICHEDIT, le contrôle // n'enverra la notification que si vous substituez la fonction __super::OnInitDialog() // et l'appel CRichEditCtrl().SetEventMask() // par l'indicateur ENM_CHANGE assorti de l'opérateur OR dans le masque. // TODO : Ajoutez ici le code de votre gestionnaire de notification de contrôle } void CModbucfgView::OnLbnSelchangeList5() { // TODO : ajoutez ici le code de votre gestionnaire de notification de contrôle } void CModbucfgView::OnLbnSelchangeLstValues() { // TODO : ajoutez ici le code de votre gestionnaire de notification de contrôle } void CModbucfgView::OnEnChangeEditAddrWri() { // TODO : S'il s'agit d'un contrôle RICHEDIT, le contrôle // n'enverra la notification que si vous substituez la fonction __super::OnInitDialog() // et l'appel CRichEditCtrl().SetEventMask() // par l'indicateur ENM_CHANGE assorti de l'opérateur OR dans le masque. // TODO : Ajoutez ici le code de votre gestionnaire de notification de contrôle } void CModbucfgView::OnEnChangeEditValue() { // TODO : S'il s'agit d'un contrôle RICHEDIT, le contrôle // n'enverra la notification que si vous substituez la fonction __super::OnInitDialog() // et l'appel CRichEditCtrl().SetEventMask() // par l'indicateur ENM_CHANGE assorti de l'opérateur OR dans le masque. // TODO : Ajoutez ici le code de votre gestionnaire de notification de contrôle } void CModbucfgView::OnVScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar) { // TODO : ajoutez ici le code de votre gestionnaire de messages et/ou les paramètres par défaut des appels if (nSBCode == SB_ENDSCROLL) { return ;//rejeter les messages non validess } //treiter uniquement les messagse de défilement de IDC_SPIN2) if (pScrollBar->GetDlgCtrlID()==IDC_SPIN2) { CString strValue; strValue.Format("%d",(int)nPos); ((CSpinButtonCtrl*)pScrollBar)->GetBuddy()->SetWindowText(strValue); } __super::OnVScroll(nSBCode, nPos, pScrollBar); } void CModbucfgView::OnCmdRead() { ldiv_t div_result; float fUpdateSpeed; DWORD dwTime; CString str; WORD nError; int iNumLoops=10; fUpdateSpeed=0.0; if ((m_cboReadFunctions.GetCurSel()>=LOOP_BACK_TEST)&& (m_cboReadFunctions.GetCurSel()<=READ_INPUT_STATUS)){ m_dwCount++; nError=ExecuteCmdReadFunction(m_cboReadFunctions.GetCurSel(),dwTime,str); m_dwSum +=dwTime; div_result = ldiv(m_dwCount,iNumLoops); if (CModbus::ERR_OK!=nError){ m_dwErrors++; } if (0==div_result.rem){ fUpdateSpeed=(float)(iNumLoops*1000)/(float)m_dwSum; m_dwSum=0; } else { fUpdateSpeed=(float)(1*1000)/(float)dwTime; } m_staError.SetWindowText(str); str.Format("%d Errors=%d %4.2f(Up./s) ",m_dwCount,m_dwErrors,fUpdateSpeed); m_statStatus.SetWindowText(str); } } WORD CModbucfgView::ExecuteCmdReadFunction(int iFunction,DWORD& dwTime, CString& rErrorMessage) { CModbus* pModbus; CShortArray aValues; CByteArray abCoilValues; CFloatArray afValues; CDblArray adValues; CString str; CString sAux; WORD nError; int i; BOOL bRegisters; DWORD dwStart; CString sKey; CConnection* pConnection =NULL; BYTE byDevice; WORD wQuant; WORD wAddr; int nIndex; int nPreviusCount; int iDataType; i=m_cboConnections.GetCurSel(); iDataType= m_cboDataType.GetCurSel(); if (i<0) { return 0; } else { m_cboConnections.GetLBText(i,sKey); if (gConnections.Lookup(sKey,pConnection)) { pModbus=pConnection->m_pModbus; } else { ASSERT(FALSE); return 0; } } m_edtDevice.GetWindowText(str); byDevice=BYTE(atoi(str)); m_edtQuant.GetWindowText(str); wQuant=BYTE(atoi(str)); m_edtReadAddr.GetWindowText(str); wAddr=WORD(atoi(str)); switch (iFunction) { case LOOP_BACK_TEST: dwStart=::timeGetTime(); nError=pModbus->LoopbackTest(byDevice); dwTime=::timeGetTime()-dwStart; str=""; bRegisters=FALSE; break; case READ_OUTPUT_REGISTERS: dwStart=::timeGetTime(); switch (iDataType) { case DATA_CHAR: case DATA_SIGNED_16: case DATA_UNSIGNED_16: aValues.SetSize(wQuant); nError=pModbus->ReadOutputRegisters(byDevice,wAddr,wQuant, aValues); break; case DATA_FLOAT: afValues.SetSize(wQuant); nError=pModbus->ReadOutputRegisters(byDevice,wAddr,wQuant, afValues); break; case DATA_FLOAT_REVERSE: afValues.SetSize(wQuant); nError=pModbus->ReadOutputRegisters(byDevice,wAddr,wQuant, afValues,CModbus::REAL_REVERSE); break; case DATA_DOUBLE: adValues.SetSize(wQuant); nError=pModbus->ReadOutputRegisters(byDevice,wAddr,wQuant, adValues); break; case DATA_DOUBLE_REVERSE: adValues.SetSize(wQuant); nError=pModbus->ReadOutputRegisters(byDevice,wAddr,wQuant, adValues,CModbus::REAL_REVERSE); break; } dwTime=::timeGetTime()-dwStart; bRegisters=TRUE; break; case READ_INPUT_REGISTERS: dwStart=::timeGetTime(); switch (iDataType) { case DATA_CHAR: case DATA_SIGNED_16: case DATA_UNSIGNED_16: aValues.SetSize(wQuant); nError=pModbus->ReadInputRegisters(byDevice,wAddr,wQuant, aValues); break; case DATA_FLOAT: afValues.SetSize(wQuant); nError=pModbus->ReadInputRegisters(byDevice,wAddr,wQuant, afValues); break; case DATA_FLOAT_REVERSE: afValues.SetSize(wQuant); nError=pModbus->ReadInputRegisters(byDevice,wAddr,wQuant, afValues,CModbus::REAL_REVERSE); break; case DATA_DOUBLE: adValues.SetSize(wQuant); nError=pModbus->ReadInputRegisters(byDevice,wAddr,wQuant, adValues); break; case DATA_DOUBLE_REVERSE: adValues.SetSize(wQuant); nError=pModbus->ReadInputRegisters(byDevice,wAddr,wQuant, adValues,CModbus::REAL_REVERSE); break; } dwTime=::timeGetTime()-dwStart; bRegisters=TRUE; break; case READ_OUTPUT_STATUS: dwStart=::timeGetTime(); abCoilValues.SetSize(wQuant); nError=pModbus->ReadOutputStatus(byDevice,wAddr,wQuant, abCoilValues); dwTime=::timeGetTime()-dwStart; bRegisters=FALSE; break; case READ_INPUT_STATUS: dwStart=::timeGetTime(); abCoilValues.SetSize(wQuant); nError=pModbus->ReadInputStatus(byDevice,wAddr,wQuant, abCoilValues); dwTime=::timeGetTime()-dwStart; bRegisters=FALSE; break; } nIndex=m_lstValues.GetCurSel(); nPreviusCount=m_lstValues.GetCount(); m_lstValues.SetRedraw(FALSE); if (bRegisters) { for(i=0;iwQuant) { for (i=wQuant;i0)&&(nIndexErrorMessage(nError); return nError; } void CModbucfgView::OnEnChangeEdit16() { BYTE byDevice=0; WORD wAddr=2023; CModbus* pModbus=GetConnection(); WORD nError=CModbus::ERR_OK; CString str, sVal; CWaitCursor WaitCursor; if (pModbus==NULL) return; m_edtDevice.GetWindowText(str); byDevice = (BYTE)atoi(str); GetDlgItem(IDC_EDIT16)->GetWindowText(sVal); AfxMessageBox("CModbucfgView::OnEnChangeEdit16()"); //case DATA_FLOAT: nError=pModbus->PresetSingleRegister(byDevice,wAddr,float(atof(sVal))); if(nError!=CModbus::ERR_OK){ WaitCursor.Restore(); AfxMessageBox(pModbus->ErrorMessage(nError)); } } void CModbucfgView::OnBnClickedButton1() { CString OpenFilter; OpenFilter = "Text File (*.txt)|*.txt||"; //créer l'instance avec le constructeur CFileDialog FileOpenDialog( TRUE,//ouverture de la boite de dialogue NULL, NULL, OFN_FILEMUSTEXIST|OFN_HIDEREADONLY|OFN_PATHMUSTEXIST, OpenFilter, // filtre AfxGetMainWnd()); // la fenetre parent if(FileOpenDialog.DoModal()==IDOK)//affichage {// ouverture de fichier avec la structure suivante : //SVil Sleil STc Nbal_max Fr N_cur N_Seqcond Num_C(8x) unsigned int wTmpBuf; float fTmpBuf; CWordArray writeParamInit_120; CFloatArray writeParamInit_121; writeParamInit_120.SetSize(100);//pr les adresses modbus writeParamInit_121.SetSize(100); CString str; FILE* pFile = fopen (FileOpenDialog.GetPathName(), "r"); if(pFile == NULL) return; /* ptr au debut du fichier*/ fseek( pFile, 0L, SEEK_SET ); /* lecture a artir du fichier*/ fscanf(pFile,"%d ",&wTmpBuf); writeParamInit_120.SetAtGrow(0,wTmpBuf);//SVil fscanf(pFile,"%f ",&fTmpBuf); writeParamInit_121.SetAtGrow(0,fTmpBuf);//Sleil fscanf(pFile,"%f ",&fTmpBuf); writeParamInit_121.SetAtGrow(1,fTmpBuf);//STc for (int i=3;i<14;i++){//nb de mots ds le fichier fscanf(pFile,"%d ",&wTmpBuf); if (i<5) writeParamInit_120.SetAtGrow(i+2,wTmpBuf);//Nbal_max/Fr else if (i==5) writeParamInit_120.SetAtGrow(i+22,wTmpBuf);//NSeq_cond else if (i>5) writeParamInit_120.SetAtGrow(i+24,wTmpBuf);//8xNum_C } fclose(pFile); str.Format("SVil=%d, Sleil=%f NSeqcond=%d",writeParamInit_120[0],writeParamInit_121[0],writeParamInit_120[27]); AfxMessageBox(str); //copie des buffers m_wValueMultiple.Copy( writeParamInit_120 ); m_fValueMultiple.Copy( writeParamInit_121 ); } } void CModbucfgView::OnBnClickedButton2() { BYTE byDevice=0; WORD wAddr=0; CString strValue; CWaitCursor WaitCursor; WORD wQuant; m_edtDevice.GetWindowText(strValue); byDevice = (BYTE)atoi(strValue); // case DATA_UNSIGNED_16: CModbus* pModbus=GetConnection(); WORD nError=CModbus::ERR_OK; if (NULL==pModbus) { return; } wAddr = 2020; wQuant=38; nError=pModbus->PresetMultipleRegisters(byDevice,wAddr,wQuant,m_wValueMultiple); // case DATA_FLOAT: pModbus=GetConnection(); if (NULL==pModbus) { return; } wAddr = 2021; wQuant=2; nError=pModbus->PresetMultipleRegisters(byDevice,wAddr,wQuant,m_fValueMultiple); if(nError!=CModbus::ERR_OK){ WaitCursor.Restore(); AfxMessageBox(pModbus->ErrorMessage(nError)); } }