Commit 26209421 authored by Pavel Vainerman's avatar Pavel Vainerman

fixed minor bugs in Modbus

parent 618b749e
......@@ -2,4 +2,4 @@
ulimit -Sc 1000000
uniset-start.sh -f ./uniset-mysql-dbserver --confile test.xml --unideb-add-levels info,crit,warn,level9,system
uniset-start.sh -f ./uniset-mysql-dbserver --confile test.xml --name DBServer --unideb-add-levels info,crit,warn,level9,system
......@@ -48,9 +48,9 @@ MBTCPServer::MBTCPServer( ModbusAddr myaddr, const string inetaddr, int port, bo
sslot->connectRemoteService( sigc::mem_fun(this, &MBTCPServer::remoteService) );
sslot->connectFileTransfer( sigc::mem_fun(this, &MBTCPServer::fileTransfer) );
sslot->setRecvTimeout(2000);
sslot->setRecvTimeout(6000);
// sslot->setAfterSendPause(afterSend);
// sslot->setReplyTimeout(replyTimeout);
sslot->setReplyTimeout(10000);
// build file list...
}
......
......@@ -2,6 +2,12 @@
ulimit -Sc 1000000
uniset-start.sh -f ./uniset-simitator --confile test.xml --sid 10,16
#for i in `seq 1 20`;
#do
uniset-start.sh -f ./uniset-simitator --confile test.xml --sid 10,16
#done
wait
#--unideb-add-levels info,crit,warn,level9,system
......@@ -84,7 +84,7 @@
<RSExchange name="RSExchange" speed="38400">
<DeviceList>
<item addr="0x02" speed="9600" respondSensor="RespondRTU_S" timeout="5000" invert="0"/>
<item addr="0x02" force_disconnect="1" speed="9600" respondSensor="RespondRTU_S" timeout="5000" invert="0"/>
</DeviceList>
</RSExchange>
......@@ -112,7 +112,7 @@
<item name="Input1_S" textname=" 1" node="" iotype="DI" priority="Medium" default="1" />
<item name="Input2_S" textname=" 2" node="" iotype="DI" priority="Medium" mbtype="rtu" mbaddr="0x01" mbfunc="0x04" mbreg="0x02" rs="2" />
<item name="Input3_S" textname=" 3" node="" iotype="DI" priority="Medium"
mbtcp="1" tcp_mbtype="rtu" tcp_mbaddr="0x02" tcp_mbfunc="0x04" tcp_mbreg="0x02"/>
mbtcp="1" tcp_mbtype="rtu" tcp_mbaddr="0x02" tcp_mbfunc="0x06" tcp_mbreg="0x02" tcp_preinit="1" />
<item name="Input4_S" textname=" 4" node="" iotype="DI" priority="Medium" mbtype="rtu" mbaddr="0x02" mbfunc="0x04" mbreg="0x02" rs="2" />
<item name="Input5_S" textname=" 5" node="" iotype="DI" priority="Medium" udp="2"/>
<item name="Input6_S" textname=" 6" node="" iotype="DI" priority="Medium" udp="2">
......
......@@ -56,9 +56,9 @@ no_extimer(false)
throw UniSetTypes::SystemError(myname+"(MBMaster): Unknown inet port...(Use: " + tmp +")" );
recv_timeout = conf->getArgPInt("--" + prefix + "-recv-timeout",it.getProp("recv_timeout"), 2000);
recv_timeout = conf->getArgPInt("--" + prefix + "-recv-timeout",it.getProp("recv_timeout"), 50);
int alltout = conf->getArgPInt("--" + prefix + "-all-timeout",it.getProp("all_timeout"), 5000);
int alltout = conf->getArgPInt("--" + prefix + "-all-timeout",it.getProp("all_timeout"), 2000);
ptAllNotRespond.setTiming(alltout);
noQueryOptimization = conf->getArgInt("--" + prefix + "-no-query-optimization",it.getProp("no_query_optimization"));
......@@ -68,7 +68,7 @@ no_extimer(false)
polltime = conf->getArgPInt("--" + prefix + "-polltime",it.getProp("polltime"), 100);
initPause = conf->getArgPInt("--" + prefix + "-initPause",it.getProp("initPause"), 50);
initPause = conf->getArgPInt("--" + prefix + "-initPause",it.getProp("initPause"), 3000);
force = conf->getArgInt("--" + prefix + "-force",it.getProp("force"));
force_out = conf->getArgInt("--" + prefix + "-force-out",it.getProp("force_out"));
......@@ -254,28 +254,31 @@ void MBTCPMaster::poll()
for( MBTCPMaster::RTUDeviceMap::iterator it=rmap.begin(); it!=rmap.end(); ++it )
it->second->resp_real = false;
}
cerr << "*********** mb=NULL " << endl;
updateSM();
return;
}
for( MBTCPMaster::RTUDeviceMap::iterator it1=rmap.begin(); it1!=rmap.end(); ++it1 )
{
RTUDevice* d(it1->second);
mb->setForceDisconnect(d->force_disconnect);
if( dlog.debugging(Debug::INFO) )
dlog[Debug::INFO] << myname << "(poll): ask addr=" << ModbusRTU::addr2str(d->mbaddr)
<< " regs=" << d->regmap.size() << endl;
d->resp_real = false;
d->resp_real = true;
for( MBTCPMaster::RegMap::iterator it=d->regmap.begin(); it!=d->regmap.end(); ++it )
{
try
{
if( d->dtype==MBTCPMaster::dtRTU )
{
if( pollRTU(d,it) )
d->resp_real = true;
// if( pollRTU(d,it) )
// d->resp_real = true;
pollRTU(d,it);
}
}
catch( ModbusRTU::mbException& ex )
......@@ -285,10 +288,13 @@ void MBTCPMaster::poll()
dlog[Debug::CRIT] << myname << "(poll): FAILED ask addr=" << ModbusRTU::addr2str(d->mbaddr)
<< " reg=" << ModbusRTU::dat2str(it->second->mbreg)
<< " -> " << ex << endl;
// d->resp_real = false;
}
}
d->resp_real = false;
if( !d->ask_every_reg )
break;
}
if( it==d->regmap.end() )
break;
}
......@@ -318,14 +324,15 @@ bool MBTCPMaster::pollRTU( RTUDevice* dev, RegMap::iterator& it )
{
RegInfo* p(it->second);
if( dlog.debugging(Debug::INFO) )
if( dlog.debugging(Debug::LEVEL3) )
{
dlog[Debug::INFO] << myname << "(pollRTU): poll "
dlog[Debug::LEVEL3] << myname << "(pollRTU): poll "
<< " mbaddr=" << ModbusRTU::addr2str(dev->mbaddr)
<< " mbreg=" << ModbusRTU::dat2str(p->mbreg)
<< " mboffset=" << p->offset
<< " mbfunc=" << p->mbfunc
<< " q_count=" << p->q_count
<< " mb_init=" << p->mb_init
<< endl;
}
......@@ -336,7 +343,7 @@ bool MBTCPMaster::pollRTU( RTUDevice* dev, RegMap::iterator& it )
<< " IGNORE register..." << endl;
return false;
}
switch( p->mbfunc )
{
case ModbusRTU::fnReadInputRegisters:
......@@ -394,6 +401,15 @@ bool MBTCPMaster::pollRTU( RTUDevice* dev, RegMap::iterator& it )
return false;
}
if( !p->mb_init )
{
// cerr << "******* mb_init: mbreg=" << ModbusRTU::dat2str(p->mbreg) << endl;
ModbusRTU::ReadInputRetMessage ret1 = mb->read04(dev->mbaddr,p->mb_init_mbreg,1);
p->mbval = ret1.data[0];
p->sm_init = true;
return true;
}
// cerr << "**** mbreg=" << ModbusRTU::dat2str(p->mbreg) << " val=" << ModbusRTU::dat2str(p->mbval) << endl;
ModbusRTU::WriteSingleOutputRetMessage ret = mb->write06(dev->mbaddr,p->mbreg+p->offset,p->mbval);
}
......@@ -403,7 +419,21 @@ bool MBTCPMaster::pollRTU( RTUDevice* dev, RegMap::iterator& it )
{
ModbusRTU::WriteOutputMessage msg(dev->mbaddr,p->mbreg+p->offset);
for( int i=0; i<p->q_count; i++,it++ )
{
if( !it->second->mb_init )
{
// cerr << "******* mb_init: mbreg=" << ModbusRTU::dat2str(it->second->mbreg)
// << " mb_init mbreg=" << ModbusRTU::dat2str(it->second->mb_init_mbreg) << endl;
ModbusRTU::ReadOutputRetMessage ret1 = mb->read03(dev->mbaddr,it->second->mb_init_mbreg,1);
// cerr << "******* mb_init: mbreg=" << ModbusRTU::dat2str(it->second->mbreg)
// << " mb_init mbreg=" << ModbusRTU::dat2str(it->second->mb_init_mbreg)
// << " mbval=" << ret1.data[0] << endl;
it->second->mbval = ret1.data[0];
it->second->sm_init = true;
}
msg.addData(it->second->mbval);
}
it--;
ModbusRTU::WriteOutputRetMessage ret = mb->write10(msg);
}
......@@ -418,6 +448,19 @@ bool MBTCPMaster::pollRTU( RTUDevice* dev, RegMap::iterator& it )
return false;
}
if( !p->mb_init )
{
// cerr << "******* mb_init: mbreg=" << ModbusRTU::dat2str(p->mbreg)
// << " init mbreg=" << ModbusRTU::dat2str(p->mb_init_mbreg) << endl;
ModbusRTU::ReadInputStatusRetMessage ret1 = mb->read02(dev->mbaddr,p->mb_init_mbreg,1);
ModbusRTU::DataBits b(ret1.data[0]);
// cerr << "******* mb_init_mbreg=" << ModbusRTU::dat2str(p->mb_init_mbreg)
// << " read val=" << (int)b[0] << endl;
p->mbval = b[0];
p->sm_init = true;
return true;
}
// cerr << "****(coil) mbreg=" << ModbusRTU::dat2str(p->mbreg) << " val=" << ModbusRTU::dat2str(p->mbval) << endl;
ModbusRTU::ForceSingleCoilRetMessage ret = mb->write05(dev->mbaddr,p->mbreg+p->offset,p->mbval);
}
......@@ -425,13 +468,42 @@ bool MBTCPMaster::pollRTU( RTUDevice* dev, RegMap::iterator& it )
case ModbusRTU::fnForceMultipleCoils:
{
ModbusRTU::ForceCoilsMessage msg(dev->mbaddr,p->mbreg+p->offset);
if( !p->mb_init )
{
// every register ask... (for mb_init_mbreg no some)
for( int i=0; i<p->q_count; i++,it++ )
msg.addBit( (it->second->mbval ? true : false) );
{
ModbusRTU::ReadInputStatusRetMessage ret1 = mb->read02(dev->mbaddr,it->second->mb_init_mbreg,1);
ModbusRTU::DataBits b(ret1.data[0]);
it->second->mbval = b[0] ? 1 : 0;
it->second->sm_init = true;
}
/*
// alone query for all register (if mb_init_mbreg ++ )
ModbusRTU::ReadInputStatusRetMessage ret1 = mb->read02(dev->mbaddr,p->mb_init_mbreg,p->q_count);
int m=0;
for( int i=0; i<ret1.bcnt; i++ )
{
ModbusRTU::DataBits b(ret1.data[i]);
for( int k=0;k<ModbusRTU::BitsPerByte && m<p->q_count; k++,it++,m++ )
{
it->second->mbval = b[k] ? 1 : 0;
it->second->sm_init = true;
}
}
*/
p->sm_init = true;
it--;
// cerr << "*********** (write multiple): " << msg << endl;
ModbusRTU::ForceCoilsRetMessage ret = mb->write0F(msg);
return true;
}
ModbusRTU::ForceCoilsMessage msg(dev->mbaddr,p->mbreg+p->offset);
for( int i=0; i<p->q_count; i++,it++ )
msg.addBit( (it->second->mbval ? true : false) );
it--;
// cerr << "*********** (write multiple): " << msg << endl;
ModbusRTU::ForceCoilsRetMessage ret = mb->write0F(msg);
}
break;
......@@ -771,9 +843,13 @@ void MBTCPMaster::sensorInfo( UniSetTypes::SensorMessage* sm )
{
dlog[Debug::INFO] << myname<< "(sensorInfo): si.id=" << sm->id
<< " reg=" << ModbusRTU::dat2str(i->reg->mbreg)
<< " val=" << sm->value << endl;
<< " val=" << sm->value
<< " mb_init=" << i->reg->mb_init << endl;
}
if( !i->reg->mb_init )
continue;
i->value = sm->value;
updateRSProperty( &(*i),true);
return;
......@@ -1075,8 +1151,9 @@ bool MBTCPMaster::initRegInfo( RegInfo* r, UniXML_iterator& it, MBTCPMaster::RT
{
r->dev = dev;
r->mbval = it.getIntProp("default");
r->offset= it.getIntProp("tcp_mboffset");
r->offset = it.getIntProp("tcp_mboffset");
r->mb_init = it.getIntProp("tcp_mbinit");
if( dev->dtype != MBTCPMaster::dtRTU )
{
dlog[Debug::CRIT] << myname << "(initRegInfo): Unknown mbtype='" << dev->dtype
......@@ -1102,6 +1179,19 @@ bool MBTCPMaster::initRegInfo( RegInfo* r, UniXML_iterator& it, MBTCPMaster::RT
r->mbreg = ModbusRTU::str2mbData(sr);
}
{
string sr = it.getProp("tcp_init_mbreg");
if( sr == "-1" )
{
r->mb_init = true; // OFF mb_init
r->sm_init = true;
}
else if( sr.empty() )
r->mb_init_mbreg = r->mbreg;
else
r->mb_init_mbreg = ModbusRTU::str2mbData(sr);
}
r->mbfunc = ModbusRTU::fnUnknown;
string f = it.getProp("tcp_mbfunc");
if( !f.empty() )
......@@ -1242,7 +1332,10 @@ bool MBTCPMaster::initItem( UniXML_iterator& it )
if( p1->rnum > 1 )
{
for( int i=1; i<p1->rnum; i++ )
addReg(dev->regmap,mbreg+i,it,dev,ri);
{
MBTCPMaster::RegInfo* ri1 = addReg(dev->regmap,mbreg+i,it,dev,ri);
ri1->mb_init_mbreg = ri->mb_init_mbreg+i;
}
}
return true;
......@@ -1370,18 +1463,29 @@ bool MBTCPMaster::initDeviceInfo( RTUDeviceMap& m, ModbusRTU::ModbusAddr a, UniX
dlog[Debug::WARN] << myname << "(initDeviceInfo): not found device for addr=" << ModbusRTU::addr2str(a) << endl;
return false;
}
d->second->ask_every_reg = it.getIntProp("ask_every_reg");
d->second->force_disconnect = it.getIntProp("force_disconnect");
dlog[Debug::INFO] << myname << "(initDeviceInfo): add addr=" << ModbusRTU::addr2str(a)
<< " force_disconnect=" << d->second->force_disconnect
<< " ask_every_reg=" << d->second->ask_every_reg << endl;
d->second->resp_id = conf->getSensorID(it.getProp("respondSensor"));
if( d->second->resp_id == DefaultObjectId )
{
dlog[Debug::CRIT] << myname << "(initDeviceInfo): not found ID for noRespondSensor=" << it.getProp("respondSensor") << endl;
return false;
return true;
}
dlog[Debug::INFO] << myname << "(initDeviceInfo): add addr=" << ModbusRTU::addr2str(a) << endl;
int tout = it.getPIntProp("timeout", UniSetTimer::WaitUpTime);
d->second->resp_ptTimeout.setTiming(tout);
d->second->resp_invert = it.getIntProp("invert");
// d->second->no_clean_input = it.getIntProp("no_clean_input");
// dlog[Debug::INFO] << myname << "(initDeviceInfo): add " << d->second << endl;
return true;
}
// -----------------------------------------------------------------------------
......@@ -1512,6 +1616,9 @@ void MBTCPMaster::updateRTU( RegMap::iterator& rit )
RegInfo* r(rit->second);
for( PList::iterator it=r->slst.begin(); it!=r->slst.end(); ++it )
updateRSProperty( &(*it),false );
if( r->sm_init )
r->mb_init = true;
}
// -----------------------------------------------------------------------------
void MBTCPMaster::updateRSProperty( RSProperty* p, bool write_only )
......@@ -1524,8 +1631,16 @@ void MBTCPMaster::updateRSProperty( RSProperty* p, bool write_only )
if( !save && write_only )
return;
if( dlog.debugging(Debug::INFO) )
dlog[Debug::INFO] << "udpateP: sid=" << p->si.id << " mbval=" << r->mbval << endl;
if( dlog.debugging(Debug::LEVEL3) )
dlog[Debug::LEVEL3] << "updateP: sid=" << p->si.id
<< " mbval=" << r->mbval
<< " vtype=" << p->vType
<< " rnum=" << p->rnum
<< " nbit=" << p->nbit
<< " save=" << save
<< " ioype=" << p->stype
<< " mb_init=" << r->mb_init
<< endl;
try
{
......@@ -1534,7 +1649,7 @@ void MBTCPMaster::updateRSProperty( RSProperty* p, bool write_only )
ModbusRTU::DataBits16 b(r->mbval);
if( p->nbit >= 0 )
{
if( save )
if( save && r->mb_init )
{
bool set = IOBase::processingAsDO( p, shm, force_out );
b.set(p->nbit,set);
......@@ -1545,12 +1660,13 @@ void MBTCPMaster::updateRSProperty( RSProperty* p, bool write_only )
bool set = b[p->nbit];
IOBase::processingAsDI( p, set, shm, force );
}
return;
}
if( p->rnum <= 1 )
{
if( save )
if( save && r->mb_init )
{
if( p->stype == UniversalIO::DigitalInput ||
p->stype == UniversalIO::DigitalOutput )
......@@ -1579,7 +1695,7 @@ void MBTCPMaster::updateRSProperty( RSProperty* p, bool write_only )
}
else if( p->vType == VTypes::vtSigned )
{
if( save )
if( save && r->mb_init )
{
if( p->stype == UniversalIO::DigitalInput ||
p->stype == UniversalIO::DigitalOutput )
......@@ -1598,15 +1714,14 @@ void MBTCPMaster::updateRSProperty( RSProperty* p, bool write_only )
}
else
{
long val = (signed short)r->mbval;
IOBase::processingAsAI( p, val, shm, force );
IOBase::processingAsAI( p, (signed short)(r->mbval), shm, force );
}
}
return;
}
else if( p->vType == VTypes::vtUnsigned )
{
if( save )
if( save && r->mb_init )
{
if( p->stype == UniversalIO::DigitalInput ||
p->stype == UniversalIO::DigitalOutput )
......@@ -1625,8 +1740,7 @@ void MBTCPMaster::updateRSProperty( RSProperty* p, bool write_only )
}
else
{
long val = (unsigned short)r->mbval;
IOBase::processingAsAI( p, val, shm, force );
IOBase::processingAsAI( p, (unsigned short)r->mbval, shm, force );
}
}
return;
......@@ -1640,7 +1754,7 @@ void MBTCPMaster::updateRSProperty( RSProperty* p, bool write_only )
return;
}
if( save )
if( save && r->mb_init )
{
long v = IOBase::processingAsAO( p, shm, force_out );
VTypes::Byte b(r->mbval);
......@@ -1658,7 +1772,7 @@ void MBTCPMaster::updateRSProperty( RSProperty* p, bool write_only )
else if( p->vType == VTypes::vtF2 )
{
RegMap::iterator i(p->reg->rit);
if( save )
if( save && r->mb_init )
{
float f = IOBase::processingFasAO( p, shm, force_out );
VTypes::F2 f2(f);
......@@ -1680,7 +1794,7 @@ void MBTCPMaster::updateRSProperty( RSProperty* p, bool write_only )
else if( p->vType == VTypes::vtF4 )
{
RegMap::iterator i(p->reg->rit);
if( save )
if( save && r->mb_init )
{
float f = IOBase::processingFasAO( p, shm, force_out );
VTypes::F4 f4(f);
......
......@@ -175,8 +175,8 @@ class MBTCPMaster:
enum DeviceType
{
dtUnknown, /*!< */
dtRTU /*!< RTU (default) */
dtUnknown, /*!< */
dtRTU /*!< RTU (default) */
};
static DeviceType getDeviceType( const std::string dtype );
......@@ -189,10 +189,10 @@ class MBTCPMaster:
public IOBase
{
// only for RTU
short nbit; /*!< bit number) */
short nbit; /*!< bit number) */
VTypes::VType vType; /*!< type of value */
short rnum; /*!< count of registers */
short nbyte; /*!< byte number (1-2) */
short rnum; /*!< count of registers */
short nbyte; /*!< byte number (1-2) */
RSProperty():
nbit(-1),vType(VTypes::vtUnknown),
......@@ -213,11 +213,12 @@ class MBTCPMaster:
RegInfo():
mbval(0),mbreg(0),mbfunc(ModbusRTU::fnUnknown),
dev(0),offset(0),
q_num(0),q_count(1)
q_num(0),q_count(1),mb_init(false),sm_init(false),
mb_init_mbreg(0)
{}
ModbusRTU::ModbusData mbval;
ModbusRTU::ModbusData mbreg; /*!< */
ModbusRTU::ModbusData mbreg; /*!< */
ModbusRTU::SlaveFunctionCode mbfunc; /*!< / */
PList slst;
......@@ -226,10 +227,13 @@ class MBTCPMaster:
int offset;
// optimization
int q_num; /*! number in query */
int q_num; /*! number in query */
int q_count; /*! count registers for query */
RegMap::iterator rit;
bool mb_init; /*!< init before use */
bool sm_init; /*!< SM init value */
ModbusRTU::ModbusData mb_init_mbreg; /*!< mb_init register */
};
friend std::ostream& operator<<( std::ostream& os, RegInfo& r );
......@@ -243,8 +247,10 @@ class MBTCPMaster:
resp_id(UniSetTypes::DefaultObjectId),
resp_state(false),
resp_invert(false),
resp_real(true),
resp_init(false)
resp_real(false),
resp_init(false),
ask_every_reg(false),
force_disconnect(false)
{
resp_trTimeout.change(false);
}
......@@ -263,6 +269,8 @@ class MBTCPMaster:
bool resp_invert;
bool resp_real;
bool resp_init;
bool ask_every_reg;
bool force_disconnect;
// return TRUE if state changed
bool checkRespond();
......
......@@ -8,7 +8,7 @@ uniset-start.sh -f ./uniset-mbtcpmaster \
--mbtcp-filter-field mbtcp \
--mbtcp-filter-value 1 \
--mbtcp-gateway-iaddr 127.0.0.1 \
--mbtcp-gateway-port 1024 \
--mbtcp-gateway-port 2048 \
--mbtcp-recv-timeout 5000
#--mbtcp-filter-field mbtcp --mbtcp-filter-value 1
......@@ -1727,7 +1727,7 @@ void RTUExchange::updateRSProperty( RSProperty* p, bool write_only )
IOBase::processingAsDI( p, r->mbval, shm, force );
}
else
IOBase::processingAsAI( p, (unsigned short)(r->mbval), shm, force );
IOBase::processingAsAI( p,r->mbval, shm, force );
}
return;
}
......
......@@ -251,7 +251,7 @@ void IONotifyController::askState( const IOController_i::SensorInfo& si,
smsg.sm_tv_usec = li->second.tv_usec;
}
TransportMessage tm(smsg.transport_msg());
TransportMessage tm(smsg.transport_msg());
try
{
ui.send(ci.id, tm, ci.node);
......@@ -1149,7 +1149,7 @@ void IONotifyController::askOutput(const IOController_i::SensorInfo& si,
smsg.sensor_type = type;
smsg.supplier = getId();
TransportMessage tm(smsg.transport_msg());
TransportMessage tm(smsg.transport_msg());
ui.send(ci.id, tm, ci.node);
}
catch(Exception& ex)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment