Knowledge Base Nr: 00231 modbustcp.cpp - http://www.swe-kaiser.de
Downloads:
Linux: Modbus/TCP mit FieldTalk Master Protocol Pack-Toolkit gekapselt in C++-Klasse
//http://www.focus-sw.com
//lib für linux und win32
extern "C"
{
int MBConnect(const char* lpszHostIP);
int MBDisconnect();
int MBRead(int nAddr);
int MBWrite(int nAddr, int nValue);
int MBZeroAll(int nMaxWords);
int MBSetBit(int nDIOBitNo, int nValue);
int MBGetFirstBit(int nMaxWords);
}
class CModBusTCP
{
public:
CModBusTCP();
virtual ~CModBusTCP();
int Connect(const char* lpszHostIP);
int Disconnect();
int Read(int nAddr, short* nValue, int nWordCount);
int Write(int nAddr, short* pnValue, int nWordCount);
protected:
private:
MbusTcpMasterProtocol m_mbusProtocol;
};
////////////////////////////
//sample
int main()
{
CModBusTCP mb;
signal(SIGINT, Exithandler);
int nErr = 0;
const char* lpszConnect = "153.95.169.235";
nErr = mb.Connect(lpszConnect);
LOG("MAIN: Connect(%s) nErr=%d", lpszConnect, nErr);
for (int n=0; n<256; n++)
{
int nAddrRead = 1;
int nAddrWrite = 1;
short nValue = 0;
int nWordCount = 1;
nErr = mb.Read(nAddrRead, &nValue, nWordCount);
LOG("MAIN: Read(%d, %p, %d) : nErr=%d => val: 0x%04X", nAddrRead, &nValue, nWordCount, nErr, nValue);
nValue = n;
nErr = mb.Write(nAddrWrite, &nValue, nWordCount);
LOG("MAIN: Write(%d, %d) : nErr=%d", nAddrWrite, &nValue, nErr);
usleep(DELAY_MS*1000); //us
}
nErr = mb.Disconnect();
LOG("MAIN: Disconnect() nErr=%d", nErr);
LOG("MAIN: return=%d\n", nErr);
return nErr;
}
///////////////////////////////////////
//cpp interface
static void sig_alarm_handler(int sig_nr);
static jmp_buf g_progzust_timeout;
int CModBusTCP::Connect(const char* lpszHostIP)
{
TRACE("CModBusTCP::Connect(%s)", lpszHostIP);
int nTimeout = 500;
int nRetry = 0;
int nDelay = 0;
m_mbusProtocol.setTimeout(nTimeout);
m_mbusProtocol.setRetryCnt(nRetry);
m_mbusProtocol.setPollDelay(nDelay);
int nResult = m_mbusProtocol.openProtocol(lpszHostIP);
if (nResult != FTALK_SUCCESS)
{
TRACE("ERROR: openProtocol(%s)!", getBusProtocolErrorText(nResult));
return -1;
}
nTimeout = m_mbusProtocol.getTimeout();
nRetry = m_mbusProtocol.getRetryCnt();
nDelay = m_mbusProtocol.getPollDelay();
LOG("INFO: getTimeout:%d getRetryCnt:%d getPollDelay:%d!", nTimeout, nRetry, nDelay);
return 0;
}
int CModBusTCP::Disconnect()
{
TRACE("CModBusTCP::Disconnect()");
m_mbusProtocol.closeProtocol();
return 0;
}
static void sig_alarm_handler(int sig_nr)
{
LOG("ERROR: sig_alarm_handler() called!");
longjmp(g_progzust_timeout, 1);
}
int CModBusTCP::Read(int nAddr, short* pnValue, int nWordCount)
{
TRACE("CModBusTCP::Read(%d, %p, %d)", nAddr, pnValue, nWordCount);
if (signal(SIGALRM, sig_alarm_handler) == SIG_ERR)
{
LOG("ERROR: signal(SIGALARM, sig_alarm_handler) failed!");
return -11;
}
if (setjmp(g_progzust_timeout) != 0)
{
LOG("ERROR: Timeout CModBusTCP::Read(%d, %p, %d)?!", nAddr, pnValue, nWordCount);
return -12;
}
alarm(1);
int nResult = m_mbusProtocol.readMultipleRegisters(1, nAddr, pnValue, nWordCount);
alarm(0);
if (nResult != FTALK_SUCCESS)
{
LOG("ERROR: %s!", getBusProtocolErrorText(nResult));
return -1;
}
for (int i=0; i < nWordCount; i++)
TRACE("[%d]: %d\n", nAddr+i, *(pnValue+i));
return 0;
}
int CModBusTCP::Write(int nAddr, short* pnValue, int nWordCount)
{
TRACE("CModBusTCP::Write(%d, %p, %d)", nAddr, pnValue, nWordCount);
for (int i=0; i < nWordCount; i++)
TRACE("[%d]: %hd\n", nAddr+i, *(pnValue+i));
if (signal(SIGALRM, sig_alarm_handler) == SIG_ERR)
{
LOG("ERROR: signal(SIGALARM, sig_alarm_handler) failed!");
return -11;
}
if (setjmp(g_progzust_timeout) != 0)
{
LOG("ERROR: Timeout CModBusTCP::Write(%d, %p, %d)?!", nAddr, pnValue, nWordCount);
return -12;
}
alarm(1);
int nResult = m_mbusProtocol.writeMultipleRegisters(1, nAddr, pnValue, nWordCount);
alarm(0);
if (nResult != FTALK_SUCCESS)
{
LOG("ERROR: %s!", getBusProtocolErrorText(nResult));
return -1;
}
return 0;
}