在PLC的程序中,添加如下變量
intCount AT %Q*: DINT; 可讀
intVarIn AT %I* : DINT:=0; 可寫
PLCVar : DINT:=0; 可讀可寫
上位機HMI程序(參考InfoSys中的例子)
1.聲明變量:
//===========================
long nErr, nPort;
AmsAddr Addr;
PAmsAddr pAddr;
ULONG lHdlVarR,lHdlVarW;
int nData;
CString strTmp;
ULONG hNotification;
AdsNotificationAttrib adsNotificationAttrib;
//===========================
2.初始化變量和屬性
//========================================================
pAddr = &Addr;
nData = 0;
// Open communication port for local PLC (Run-time system 1)
nPort = AdsPortOpen();
nErr = AdsGetLocalAddress(pAddr); //獲取本地的AmsNetId 和 Port
if (nErr)
{
MessageBox("Error: AdsGetLocalAddress: ");
return 0;
}
pAddr->port = AMSPORT_R0_PLC_RTS1; //Port爲第一個PLC任務
// Specify attributes of the notification
adsNotificationAttrib.cbLength = 16; //讀取數據長度
adsNotificationAttrib.nTransMode = ADSTRANS_SERVERONCHA; //當變化是響應回調函數
adsNotificationAttrib.nMaxDelay = 1000000; // 100ms
adsNotificationAttrib.nCycleTime = 1000000; // 100ms
3.獲取變量的句柄
// Fetch handle for an <szVar> PLC variable
char szVarR[]= {"MAIN.intCount"}; //讀
nErr = AdsSyncReadWriteReq(pAddr, ADSIGRP_SYM_HNDBYNAME, 0x0,
sizeof(lHdlVarR), &lHdlVarR, sizeof(szVarR), szVarR);
char szVarW[]= {"MAIN.intVarIn"}; //寫
nErr = AdsSyncReadWriteReq(pAddr, ADSIGRP_SYM_HNDBYNAME, 0x0,
sizeof(lHdlVarW), &lHdlVarW, sizeof(szVarW), szVarW);
4.通過上述的句柄就可以實現對PLC中的數據進行讀寫 或 設置“事件驅動”的方式獲取數據
4.1讀數據
nErr = AdsSyncReadReq( pAddr, ADSIGRP_SYM_VALBYHND, lHdlVarR, sizeof(nData), &nData );
if (nErr)
MessageBox("Fehler: AdsSyncReadReq: ");
else
strTmp.Format("%d", nData) ;
m_strSysData="Fehler: AdsSyncReadReq: " + strTmp;
4.2寫數據
UpdateData();
nData=atoi(m_strWriteData);
nErr = AdsSyncWriteReq(pAddr, ADSIGRP_SYM_VALBYHND, lHdlVarW, sizeof(nData), &nData);
if (nErr)
MessageBox("Error: AdsSyncWriteReq: ");
4.3啓動“事件驅動”
1)聲明回調函數
void __stdcall SymbolChanged(AmsAddr*, AdsNotificationHeader*, unsigned long);
2)啓動“事件驅動”
nErr = AdsSyncAddDeviceNotificationReq(pAddr, ADSIGRP_SYM_VALBYHND,
lHdlVarR, &adsNotificationAttrib,
SymbolChanged, NULL, &hNotification);
if (nErr)
{
MessageBox("Error: AdsSyncAddDeviceNotificationReq: ");
return;
}
//================以下爲回調函數部分========================
void __stdcall SymbolChanged(AmsAddr* pAddr, AdsNotificationHeader* pNotification, ULONG hUser)
{
CString strDataFromNotify,strTmp;
CEx02Dlg *dlg=(CEx02Dlg *)AfxGetMainWnd();
strDataFromNotify=""; strTmp="";
// Output value of the variable
strTmp.Format("Value:%d/n", *(int *)pNotification->data); //data中的數據爲地址
strDataFromNotify+=strTmp;
strTmp.Format("Notification:%d/n",pNotification->hNotification);
strDataFromNotify+=strTmp;
strTmp.Format("SampleSize:%d/n",pNotification->cbSampleSize);
strDataFromNotify+=strTmp;
strTmp.Format("hUser:%d/n",hUser);
strDataFromNotify+=strTmp;
dlg->m_strNtyData=strDataFromNotify;
dlg->SetDlgItemText(IDC_STATIC_Data2,strDataFromNotify); //更新CEX02類中的窗體
}
4.4關閉“事件驅動”
nErr = AdsSyncDelDeviceNotificationReq(pAddr, hNotification);
if (nErr)
{
MessageBox("Error: AdsSyncDelDeviceNotificationReq: ");
return;
}
5.關閉端口
nErr = AdsPortClose();
if (nErr)
MessageBox("Error: AdsPortClose: ");
以上是對int型變量進行讀寫的簡單實驗。