Commit 5d5064d2 authored by Pavel Vainerman's avatar Pavel Vainerman

(IOBase): подправил обработку для DI и DO, чтобы они могли иметь

только значения "1" или "0".
parent 5b3f66b1
......@@ -107,12 +107,12 @@
<item id="1025" mb="1" mbtype="rtu" mbaddr="0x01" mbreg="39" mbfunc="0x0F" iotype="DO" name="TestWrite0F_2" textname="Тестовый регистр для 0x0F"/>
<item id="1026" mb="1" mbtype="rtu" mbaddr="0x01" mbreg="40" mbfunc="0x0F" iotype="DO" name="TestWrite0F_3" textname="Тестовый регистр для 0x0F"/>
<!-- <item id="1027" mb="1" mbtype="rtu" mbaddr="0x01" mbreg="41" mbfunc="0x10" vtype="F2" iotype="AO" name="TestWrite10_F2" textname="Тестовый регистр для 0x10"/> -->
<!-- <item id="1028" mb="1" mbtype="rtu" mbaddr="0x01" mbreg="45" mbfunc="0x10" vtype="F4" iotype="AO" name="TestWrite10_F4" textname="Тестовый регистр для 0x10"/> -->
<!--
<item id="1027" mb="1" mbtype="rtu" mbaddr="0x01" mbreg="41" mbfunc="0x10" vtype="F2" iotype="AO" name="TestWrite10_F2" textname="Тестовый регистр для 0x10"/>
<item id="1028" mb="1" mbtype="rtu" mbaddr="0x01" mbreg="45" mbfunc="0x10" vtype="F4" iotype="AO" name="TestWrite10_F4" textname="Тестовый регистр для 0x10"/>
-->
<item id="1027" mb="1" mbtype="rtu" mbaddr="0x01" mbreg="41" mbfunc="0x10" vtype="F2" iotype="AO" name="TestWrite1027_F2" precision="1" textname="F2: Тестовый регистр для 0x10"/>
-->
<item id="1028" mb="2" mbtype="rtu" mbaddr="0x01" mbreg="47" mbfunc="0x03" vtype="F2" iotype="DI" name="TestWrite1028_F2" textname="F2: Тестовый регистр для 0x10"/>
<item id="10000" iotype="DI" name="TestMode_S" textname="Тестовый датчик"/>
......
......@@ -12,10 +12,11 @@ cd -
--mbtcp-name MBTCPMaster1 \
--smemory-id SharedMemory \
--mbtcp-filter-field mb \
--mbtcp-filter-value 1 \
--mbtcp-filter-value 2 \
--mbtcp-gateway-iaddr localhost \
--mbtcp-gateway-port 20048 \
--mbtcp-polltime 50 --mbtcp-recv-timeout 500
#--mbtcp-log-add-levels any
#--mbtcp-default-mbinit-ok 1
#--dlog-add-levels any
......
......@@ -599,7 +599,7 @@ TEST_CASE("MBTCPMaster: 0x66 (file transfer)", "[modbus][0x66][mbmaster][mbtcpma
WARN("Test of '0x66'..not yet.. ");
}
// -----------------------------------------------------------------------------
#if 0
#if 1
TEST_CASE("MBTCPMaster: 0x10 (F2)", "[modbus][0x10][F2][mbmaster][mbtcpmaster]")
{
InitTest();
......@@ -662,3 +662,21 @@ TEST_CASE("MBTCPMaster: FasAO -> FasAI", "[modbus][float]")
}
#endif
// -----------------------------------------------------------------------------
TEST_CASE("MBTCPMaster: F2 to DI", "[modbus][ftodi]")
{
InitTest();
CHECK( ui->isExist(mbID) );
mbs->setReply(10);
msleep(polltime + 200);
REQUIRE( ui->getValue(1028) == 1 );
mbs->setReply(0);
msleep(polltime + 200);
REQUIRE( ui->getValue(1028) == 0 );
mbs->setReply(10);
msleep(polltime + 200);
REQUIRE( ui->getValue(1028) == 1 );
}
// -----------------------------------------------------------------------------
......@@ -176,63 +176,69 @@ bool IOBase::check_front( bool val )
// -----------------------------------------------------------------------------
void IOBase::processingAsAI( IOBase* it, long val, const std::shared_ptr<SMInterface>& shm, bool force )
{
// проверка на обрыв
if( it->check_channel_break(val) )
{
uniset_rwmutex_wrlock lock(it->val_lock);
it->value = ChannelBreakValue;
shm->localSetUndefinedState(it->ioit, true, it->si.id);
return;
}
// проверка зависимости
if( !it->check_depend(shm) )
val = it->d_off_value;
if( it->stype == UniversalIO::DI || it->stype == UniversalIO::DO )
val = (val ? 1.0 : 0.0);
else
{
if( !it->nofilter && it->df.size() > 1 )
// проверка на обрыв
if( it->check_channel_break(val) )
{
if( it->f_median )
val = it->df.median(val);
else if( it->f_filter_iir )
val = it->df.filterIIR(val);
else if( it->f_ls )
val = it->df.leastsqr(val);
else
val = it->df.filterRC(val);
uniset_rwmutex_wrlock lock(it->val_lock);
it->value = ChannelBreakValue;
shm->localSetUndefinedState(it->ioit, true, it->si.id);
return;
}
if( !it->rawdata )
// проверка зависимости
if( !it->check_depend(shm) )
val = it->d_off_value;
else
{
if( it->cdiagram ) // задана специальная калибровочная диаграмма
if( !it->nofilter && it->df.size() > 1 )
{
if( it->craw != val )
{
it->craw = val;
val = it->cdiagram->getValue(val, it->calcrop);
it->cprev = val;
}
if( it->f_median )
val = it->df.median(val);
else if( it->f_filter_iir )
val = it->df.filterIIR(val);
else if( it->f_ls )
val = it->df.leastsqr(val);
else
val = it->cprev; // просто передаём предыдущее значение
val = it->df.filterRC(val);
}
else
if( !it->rawdata )
{
IOController_i::CalibrateInfo* cal( &(it->cal) );
if( it->cdiagram ) // задана специальная калибровочная диаграмма
{
if( it->craw != val )
{
it->craw = val;
val = it->cdiagram->getValue(val, it->calcrop);
it->cprev = val;
}
else
val = it->cprev; // просто передаём предыдущее значение
}
else
{
IOController_i::CalibrateInfo* cal( &(it->cal) );
if( cal->maxRaw != cal->minRaw ) // задана обычная калибровка
val = UniSetTypes::lcalibrate(val, cal->minRaw, cal->maxRaw, cal->minCal, cal->maxCal, it->calcrop);
if( cal->maxRaw != cal->minRaw ) // задана обычная калибровка
val = UniSetTypes::lcalibrate(val, cal->minRaw, cal->maxRaw, cal->minCal, cal->maxCal, it->calcrop);
}
if( !it->noprecision && it->cal.precision > 0 )
val *= lround(pow10(it->cal.precision));
}
} // end of 'check_depend'
if( !it->noprecision && it->cal.precision > 0 )
val *= lround(pow10(it->cal.precision));
}
} // end of 'check_depend'
}
// если предыдущее значение "обрыв",
// то сбрасываем признак
{
uniset_rwmutex_wrlock lock(it->val_lock);
// если предыдущее значение "обрыв",
// то сбрасываем признак
if( it->value == ChannelBreakValue )
shm->localSetUndefinedState(it->ioit, false, it->si.id);
......@@ -248,51 +254,56 @@ void IOBase::processingFasAI( IOBase* it, float fval, const std::shared_ptr<SMIn
{
long val = lroundf(fval);
if( it->rawdata )
{
val = 0;
memcpy(&val, &fval, std::min(sizeof(val), sizeof(fval)));
}
else if( it->cal.precision > 0 && !it->noprecision )
val = lroundf( fval * pow10(it->cal.precision) );
// проверка на обрыв
if( it->check_channel_break(val) )
{
uniset_rwmutex_wrlock lock(it->val_lock);
it->value = ChannelBreakValue;
shm->localSetUndefinedState(it->ioit, true, it->si.id);
return;
}
// проверка зависимости
if( !it->check_depend(shm) )
val = it->d_off_value;
if( it->stype == UniversalIO::DI || it->stype == UniversalIO::DO )
val = (fval!=0 ? 1.0 : 0.0);
else
{
// Читаем с использованием фильтра...
if( !it->nofilter )
if( it->rawdata )
{
if( it->df.size() > 1 )
it->df.add(val);
val = 0;
memcpy(&val, &fval, std::min(sizeof(val), sizeof(fval)));
}
else if( it->cal.precision > 0 && !it->noprecision )
val = lroundf( fval * pow10(it->cal.precision) );
val = it->df.filterRC(val);
// проверка на обрыв
if( it->check_channel_break(val) )
{
uniset_rwmutex_wrlock lock(it->val_lock);
it->value = ChannelBreakValue;
shm->localSetUndefinedState(it->ioit, true, it->si.id);
return;
}
if( !it->rawdata )
// проверка зависимости
if( !it->check_depend(shm) )
val = it->d_off_value;
else
{
IOController_i::CalibrateInfo* cal( &(it->cal) );
// Читаем с использованием фильтра...
if( !it->nofilter )
{
if( it->df.size() > 1 )
it->df.add(val);
val = it->df.filterRC(val);
}
if( cal->maxRaw != cal->minRaw ) // задана обычная калибровка
val = UniSetTypes::lcalibrate(val, cal->minRaw, cal->maxRaw, cal->minCal, cal->maxCal, it->calcrop);
if( !it->rawdata )
{
IOController_i::CalibrateInfo* cal( &(it->cal) );
if( cal->maxRaw != cal->minRaw ) // задана обычная калибровка
val = UniSetTypes::lcalibrate(val, cal->minRaw, cal->maxRaw, cal->minCal, cal->maxCal, it->calcrop);
}
}
}
// если предыдущее значение "обрыв",
// то сбрасываем признак
{
uniset_rwmutex_wrlock lock(it->val_lock);
// если предыдущее значение "обрыв",
// то сбрасываем признак
if( it->value == ChannelBreakValue )
shm->localSetUndefinedState(it->ioit, false, it->si.id);
......@@ -433,6 +444,8 @@ float IOBase::processingFasAO( IOBase* it, const std::shared_ptr<SMInterface>& s
if( !it->noprecision && it->cal.precision > 0 )
return ( fval / pow10(it->cal.precision) );
}
else // if( it->stype == UniversalIO::DI || it->stype == UniversalIO::DO )
fval = val ? 1.0 : 0.0;
return fval;
}
......
......@@ -483,6 +483,24 @@ TEST_CASE("[IOBase::calibration]: asDI, asDO", "[iobase][di][do][extensions]")
}
}
// -----------------------------------------------------------------------------
TEST_CASE("[IOBase]: FasAI to DI", "[iobase][floatToDI]")
{
CHECK( uniset_conf() != nullptr );
IOBase ib;
CHECK( init_iobase(&ib, "FasDI_S") );
float f=23.23;
IOBase::processingFasAI(&ib, f, shm, true);
CHECK(shm->getValue(121) == 1 );
f = 0;
IOBase::processingFasAI(&ib, f, shm, true);
CHECK(shm->getValue(121) == 0 );
}
// -----------------------------------------------------------------------------
TEST_CASE("IOBase with SM", "[iobase][extensions]")
{
WARN("IOBase with SM: Not all tests implemented!");
......
......@@ -270,6 +270,7 @@
<!-- FasAO -> FasAI -->
<item id="119" iotype="AI" name="FasAI_S" textname="FasAI" precision="1"/>
<item id="120" iotype="AI" name="FasAO_S" textname="FasAO" precsision="1"/>
<item id="121" iotype="DI" name="FasDI_S" textname="FasDI"/>
</sensors>
......
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