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;
}