Commit 8744a63f authored by Pavel Vainerman's avatar Pavel Vainerman

(IOBase): ввёл флаг rawdata, для работы с VTypes::F4 "без преобразования",

а так же для отключения "одним махом".. Calibraction,precision и т.п.
parent 30790f2d
...@@ -1882,16 +1882,6 @@ bool MBExchange::initRSProperty( RSProperty& p, UniXML_iterator& it ) ...@@ -1882,16 +1882,6 @@ bool MBExchange::initRSProperty( RSProperty& p, UniXML_iterator& it )
return true; return true;
} }
if( IOBase::initIntProp(it,"rawdata",prefix,false) )
{
p.cal.minRaw = 0;
p.cal.maxRaw = 0;
p.cal.minCal = 0;
p.cal.maxCal = 0;
p.cal.precision = 0;
p.cdiagram = 0;
}
string sbit(IOBase::initProp(it,"nbit",prefix,false)); string sbit(IOBase::initProp(it,"nbit",prefix,false));
if( !sbit.empty() ) if( !sbit.empty() )
{ {
......
...@@ -812,16 +812,6 @@ bool MBSlave::initItem( UniXML_iterator& it ) ...@@ -812,16 +812,6 @@ bool MBSlave::initItem( UniXML_iterator& it )
if( !IOBase::initItem( static_cast<IOBase*>(&p),it,shm,prop_prefix,false,&dlog,myname) ) if( !IOBase::initItem( static_cast<IOBase*>(&p),it,shm,prop_prefix,false,&dlog,myname) )
return false; return false;
if( IOBase::initIntProp(it,"rawdata",prefix,false) )
{
p.cal.minRaw = 0;
p.cal.maxRaw = 0;
p.cal.minCal = 0;
p.cal.maxCal = 0;
p.cal.precision = 0;
p.cdiagram = 0;
}
if( mbregFromID ) if( mbregFromID )
p.mbreg = p.si.id; p.mbreg = p.si.id;
else else
......
...@@ -50,12 +50,14 @@ class MBSlave: ...@@ -50,12 +50,14 @@ class MBSlave:
AccessMode amode; AccessMode amode;
VTypes::VType vtype; /*!< type of value */ VTypes::VType vtype; /*!< type of value */
int wnum; /*!< номер слова (для типов с размеров больше 2х байт */ int wnum; /*!< номер слова (для типов с размеров больше 2х байт */
bool rawdata; /*!< флаг, что в SM просто сохраняются 4-байта (актуально для типа F4)*/
IOProperty(): IOProperty():
mbreg(0), mbreg(0),
amode(amRW), amode(amRW),
vtype(VTypes::vtUnknown), vtype(VTypes::vtUnknown),
wnum(0) wnum(0),
rawdata(false)
{} {}
friend std::ostream& operator<<( std::ostream& os, IOProperty& p ); friend std::ostream& operator<<( std::ostream& os, IOProperty& p );
......
...@@ -146,6 +146,7 @@ ...@@ -146,6 +146,7 @@
<item id="2009" default="250000" precision="5" mbs="1" mbreg="114" iotype="AI" vtype="F4" name="TestVtype9" textname="Тестовый регистр для проверки vtype"/> <item id="2009" default="250000" precision="5" mbs="1" mbreg="114" iotype="AI" vtype="F4" name="TestVtype9" textname="Тестовый регистр для проверки vtype"/>
<item default="-100" id="2011" mbs="1" mbreg="118" iotype="AI" vtype="signed" name="TestVtype11" textname="Тестовый регистр для проверки vtype"/> <item default="-100" id="2011" mbs="1" mbreg="118" iotype="AI" vtype="signed" name="TestVtype11" textname="Тестовый регистр для проверки vtype"/>
<item default="65534" id="2012" mbs="1" mbreg="119" iotype="AI" vtype="unsigned" name="TestVtype12" textname="Тестовый регистр для проверки vtype"/> <item default="65534" id="2012" mbs="1" mbreg="119" iotype="AI" vtype="unsigned" name="TestVtype12" textname="Тестовый регистр для проверки vtype"/>
<item id="2013" rawdata="1" mbs="1" mbreg="120" iotype="AI" vtype="F4" name="TestVtype9" textname="Тестовый регистр для проверки vtype"/>
<item id="10000" iotype="DI" name="TestMode_S" textname="Тестовый датчик"/> <item id="10000" iotype="DI" name="TestMode_S" textname="Тестовый датчик"/>
......
...@@ -629,7 +629,7 @@ static void test_write10_U2r( unsigned int val ) ...@@ -629,7 +629,7 @@ static void test_write10_U2r( unsigned int val )
REQUIRE( ret.quant == U2r::wsize() ); REQUIRE( ret.quant == U2r::wsize() );
REQUIRE( (unsigned int)ui->getValue(2004) == val ); REQUIRE( (unsigned int)ui->getValue(2004) == val );
} }
static void test_write10_F2( float val ) static void test_write10_F2( const float& val )
{ {
using namespace VTypes; using namespace VTypes;
ModbusRTU::ModbusData tREG = 110; ModbusRTU::ModbusData tREG = 110;
...@@ -649,7 +649,7 @@ static void test_write10_F2( float val ) ...@@ -649,7 +649,7 @@ static void test_write10_F2( float val )
REQUIRE( fval == val ); REQUIRE( fval == val );
} }
static void test_write10_F2r( float val ) static void test_write10_F2r( const float& val )
{ {
using namespace VTypes; using namespace VTypes;
ModbusRTU::ModbusData tREG = 112; ModbusRTU::ModbusData tREG = 112;
...@@ -670,6 +670,53 @@ static void test_write10_F2r( float val ) ...@@ -670,6 +670,53 @@ static void test_write10_F2r( float val )
REQUIRE( fval == val ); REQUIRE( fval == val );
} }
static void test_write10_F4raw( const float& val )
{
using namespace VTypes;
ModbusRTU::ModbusData tREG = 120;
ModbusRTU::WriteOutputMessage msg(slaveaddr,tREG);
F4 tmp(val);
msg.addData( tmp.raw.v[0] );
msg.addData( tmp.raw.v[1] );
msg.addData( tmp.raw.v[2] );
msg.addData( tmp.raw.v[3] );
ModbusRTU::WriteOutputRetMessage ret = mb->write10(msg);
REQUIRE( ret.start == tREG );
REQUIRE( ret.quant == F4::wsize() );
IOController_i::SensorInfo si;
si.id = 2013;
si.node = conf->getLocalNode();
long raw = ui->getValue(si.id);
float fval = 0;
memcpy( &fval,&raw,std::min(sizeof(fval),sizeof(raw)) );
REQUIRE( fval == val );
}
static void test_write10_F4prec( const float& val )
{
using namespace VTypes;
ModbusRTU::ModbusData tREG = 114;
ModbusRTU::WriteOutputMessage msg(slaveaddr,tREG);
F4 tmp(val);
msg.addData( tmp.raw.v[0] );
msg.addData( tmp.raw.v[1] );
msg.addData( tmp.raw.v[2] );
msg.addData( tmp.raw.v[3] );
ModbusRTU::WriteOutputRetMessage ret = mb->write10(msg);
REQUIRE( ret.start == tREG );
REQUIRE( ret.quant == F4::wsize() );
IOController_i::SensorInfo si;
si.id = 2009;
si.node = conf->getLocalNode();
IOController_i::CalibrateInfo cal = ui->getCalibrateInfo(si);
float fval = (float)ui->getValue(si.id) / pow10(cal.precision);
REQUIRE( fval == val );
}
TEST_CASE("Write(0x10): vtypes..","[modbus][mbslave][mbtcpslave]") TEST_CASE("Write(0x10): vtypes..","[modbus][mbslave][mbtcpslave]")
{ {
using namespace VTypes; using namespace VTypes;
...@@ -711,8 +758,17 @@ TEST_CASE("Write(0x10): vtypes..","[modbus][mbslave][mbtcpslave]") ...@@ -711,8 +758,17 @@ TEST_CASE("Write(0x10): vtypes..","[modbus][mbslave][mbtcpslave]")
test_write10_F2r(0); test_write10_F2r(0);
test_write10_F2r(100000.23); test_write10_F2r(100000.23);
} }
SECTION("Test: write vtype 'F4'") SECTION("Test: write vtype 'F4'(raw)")
{
test_write10_F4raw(numeric_limits<float>::max());
test_write10_F4raw(0);
test_write10_F4raw(numeric_limits<float>::min());
}
SECTION("Test: write vtype 'F4'(precision)")
{ {
test_write10_F4prec(15.55555);
test_write10_F4prec(0);
test_write10_F4prec(-15.00001);
} }
} }
...@@ -746,3 +802,8 @@ TEST_CASE("(0x66): file transfer") ...@@ -746,3 +802,8 @@ TEST_CASE("(0x66): file transfer")
} }
#endif #endif
TEST_CASE("access mode","[modbus][mbslvae][mbtcpslave]")
{
}
\ No newline at end of file
...@@ -49,7 +49,8 @@ static const int NoSafety = -1; ...@@ -49,7 +49,8 @@ static const int NoSafety = -1;
front(false), front(false),
front_type(ftUnknown), front_type(ftUnknown),
front_prev_state(false), front_prev_state(false),
front_state(false) front_state(false),
rawdata(false)
{ {
si.id = UniSetTypes::DefaultObjectId; si.id = UniSetTypes::DefaultObjectId;
si.node = UniSetTypes::DefaultObjectId; si.node = UniSetTypes::DefaultObjectId;
...@@ -119,6 +120,8 @@ static const int NoSafety = -1; ...@@ -119,6 +120,8 @@ static const int NoSafety = -1;
bool front_prev_state; bool front_prev_state;
bool front_state; bool front_state;
bool rawdata; // флаг для сохранения данный в таком виде в каком они пришли (4байта просто копируются в long). Актуально для Vtypes::F4.
IOController::IOStateList::iterator ioit; IOController::IOStateList::iterator ioit;
UniSetTypes::uniset_rwmutex val_lock; /*!< блокировка на время "работы" со значением */ UniSetTypes::uniset_rwmutex val_lock; /*!< блокировка на время "работы" со значением */
......
...@@ -50,7 +50,7 @@ namespace VTypes ...@@ -50,7 +50,7 @@ namespace VTypes
// конструкторы на разные случаи... // конструкторы на разные случаи...
F2(){ memset(raw.v,0,sizeof(raw.v)); } F2(){ memset(raw.v,0,sizeof(raw.v)); }
F2( float f ){ raw.val = f; } F2( const float& f ){ raw.val = f; }
F2( const ModbusRTU::ModbusData* data, int size ) F2( const ModbusRTU::ModbusData* data, int size )
{ {
for( int i=0; i<wsize() && i<size; i++ ) for( int i=0; i<wsize() && i<size; i++ )
...@@ -80,7 +80,7 @@ namespace VTypes ...@@ -80,7 +80,7 @@ namespace VTypes
// конструкторы на разные случаи... // конструкторы на разные случаи...
F2r(){} F2r(){}
F2r( float f ):F2(f) F2r( const float& f ):F2(f)
{ {
raw_backorder = raw; raw_backorder = raw;
std::swap(raw_backorder.v[0],raw_backorder.v[1]); std::swap(raw_backorder.v[0],raw_backorder.v[1]);
...@@ -112,7 +112,7 @@ namespace VTypes ...@@ -112,7 +112,7 @@ namespace VTypes
// конструкторы на разные случаи... // конструкторы на разные случаи...
F4(){ memset(raw.v,0,sizeof(raw.v)); } F4(){ memset(raw.v,0,sizeof(raw.v)); }
F4( float f ){ raw.val = f; } F4( const float& f ){ raw.val = f; }
F4( const ModbusRTU::ModbusData* data, int size ) F4( const ModbusRTU::ModbusData* data, int size )
{ {
for( int i=0; i<wsize() && i<size; i++ ) for( int i=0; i<wsize() && i<size; i++ )
...@@ -150,7 +150,7 @@ namespace VTypes ...@@ -150,7 +150,7 @@ namespace VTypes
Byte(){ raw.w = 0; } Byte(){ raw.w = 0; }
Byte( unsigned char b1, unsigned char b2 ){ raw.b[0]=b1; raw.b[1]=b2; } Byte( unsigned char b1, unsigned char b2 ){ raw.b[0]=b1; raw.b[1]=b2; }
Byte( const long val ) Byte( const long& val )
{ {
raw.w = val; raw.w = val;
} }
...@@ -182,7 +182,7 @@ namespace VTypes ...@@ -182,7 +182,7 @@ namespace VTypes
// конструкторы на разные случаи... // конструкторы на разные случаи...
Unsigned():raw(0){} Unsigned():raw(0){}
Unsigned( const long val ) Unsigned( const long& val )
{ {
raw = val; raw = val;
} }
...@@ -212,7 +212,7 @@ namespace VTypes ...@@ -212,7 +212,7 @@ namespace VTypes
// конструкторы на разные случаи... // конструкторы на разные случаи...
Signed():raw(0){} Signed():raw(0){}
Signed( const long val ) Signed( const long& val )
{ {
raw = val; raw = val;
} }
...@@ -275,7 +275,7 @@ namespace VTypes ...@@ -275,7 +275,7 @@ namespace VTypes
public: public:
I2r(){} I2r(){}
I2r( int v ):I2(v) I2r( const int v ):I2(v)
{ {
raw_backorder = raw; raw_backorder = raw;
std::swap(raw_backorder.v[0],raw_backorder.v[1]); std::swap(raw_backorder.v[0],raw_backorder.v[1]);
......
...@@ -136,6 +136,8 @@ void IOBase::processingAsAI( IOBase* it, long val, SMInterface* shm, bool force ...@@ -136,6 +136,8 @@ void IOBase::processingAsAI( IOBase* it, long val, SMInterface* shm, bool force
val = it->df.filterRC(val); val = it->df.filterRC(val);
} }
if( !it->rawdata )
{
if( it->cdiagram ) // задана специальная калибровочная диаграмма if( it->cdiagram ) // задана специальная калибровочная диаграмма
{ {
if( it->craw != val ) if( it->craw != val )
...@@ -156,7 +158,7 @@ void IOBase::processingAsAI( IOBase* it, long val, SMInterface* shm, bool force ...@@ -156,7 +158,7 @@ void IOBase::processingAsAI( IOBase* it, long val, SMInterface* shm, bool force
if( !it->noprecision && it->cal.precision > 0 ) if( !it->noprecision && it->cal.precision > 0 )
val *= lround(pow10(it->cal.precision)); val *= lround(pow10(it->cal.precision));
}
// если предыдущее значение "обрыв", // если предыдущее значение "обрыв",
// то сбрасываем признак // то сбрасываем признак
{ {
...@@ -176,7 +178,12 @@ void IOBase::processingFasAI( IOBase* it, float fval, SMInterface* shm, bool for ...@@ -176,7 +178,12 @@ void IOBase::processingFasAI( IOBase* it, float fval, SMInterface* shm, bool for
{ {
long val = lroundf(fval); long val = lroundf(fval);
if( it->cal.precision > 0 ) if( it->rawdata )
{
val = 0;
memcpy(&val,&fval, std::min(sizeof(val),sizeof(fval)));
}
else if( it->cal.precision > 0 )
val = lroundf( fval * pow10(it->cal.precision) ); val = lroundf( fval * pow10(it->cal.precision) );
// проверка на обрыв // проверка на обрыв
...@@ -199,10 +206,13 @@ void IOBase::processingFasAI( IOBase* it, float fval, SMInterface* shm, bool for ...@@ -199,10 +206,13 @@ void IOBase::processingFasAI( IOBase* it, float fval, SMInterface* shm, bool for
val = it->df.filterRC(val); val = it->df.filterRC(val);
} }
if( !it->rawdata )
{
IOController_i::CalibrateInfo* cal( &(it->cal) ); IOController_i::CalibrateInfo* cal( &(it->cal) );
if( cal->maxRaw!=cal->minRaw ) // задана обычная калибровка if( cal->maxRaw!=cal->minRaw ) // задана обычная калибровка
val = UniSetTypes::lcalibrate(val,cal->minRaw,cal->maxRaw,cal->minCal,cal->maxCal,true); val = UniSetTypes::lcalibrate(val,cal->minRaw,cal->maxRaw,cal->minCal,cal->maxCal,true);
} }
}
// если предыдущее значение "обрыв", // если предыдущее значение "обрыв",
// то сбрасываем признак // то сбрасываем признак
...@@ -252,6 +262,9 @@ long IOBase::processingAsAO( IOBase* it, SMInterface* shm, bool force ) ...@@ -252,6 +262,9 @@ long IOBase::processingAsAO( IOBase* it, SMInterface* shm, bool force )
it->value = val; it->value = val;
} }
if( it->rawdata )
return val;
if( it->stype == UniversalIO::AO || if( it->stype == UniversalIO::AO ||
it->stype == UniversalIO::AI ) it->stype == UniversalIO::AI )
{ {
...@@ -309,6 +322,13 @@ float IOBase::processingFasAO( IOBase* it, SMInterface* shm, bool force ) ...@@ -309,6 +322,13 @@ float IOBase::processingFasAO( IOBase* it, SMInterface* shm, bool force )
it->value = val; it->value = val;
} }
if( it->rawdata )
{
float fval=0;
memcpy(&fval,&val, std::min(sizeof(val),sizeof(fval)));
return fval;
}
if( it->stype == UniversalIO::AO || if( it->stype == UniversalIO::AO ||
it->stype == UniversalIO::AI ) it->stype == UniversalIO::AI )
{ {
...@@ -437,6 +457,7 @@ bool IOBase::initItem( IOBase* b, UniXML_iterator& it, SMInterface* shm, const s ...@@ -437,6 +457,7 @@ bool IOBase::initItem( IOBase* b, UniXML_iterator& it, SMInterface* shm, const s
b->noprecision = initIntProp(it,"noprecision",prefix,init_prefix_only); b->noprecision = initIntProp(it,"noprecision",prefix,init_prefix_only);
b->value = b->defval; b->value = b->defval;
b->breaklim = initIntProp(it,"breaklim",prefix,init_prefix_only); b->breaklim = initIntProp(it,"breaklim",prefix,init_prefix_only);
b->rawdata = initIntProp(it,"rawdata",prefix,init_prefix_only);
long msec = initIntProp(it,"debouncedelay",prefix,init_prefix_only, UniSetTimer::WaitUpTime); long msec = initIntProp(it,"debouncedelay",prefix,init_prefix_only, UniSetTimer::WaitUpTime);
b->ptDebounce.setTiming(msec); b->ptDebounce.setTiming(msec);
......
...@@ -197,23 +197,41 @@ TEST_CASE("VTypes: F4","[vtypes][F4]") ...@@ -197,23 +197,41 @@ TEST_CASE("VTypes: F4","[vtypes][F4]")
} }
SECTION("'float' constructor") SECTION("'float' constructor")
{ {
{
F4 v( numeric_limits<float>::max() ); F4 v( numeric_limits<float>::max() );
REQUIRE( (float)v == numeric_limits<float>::max() ); REQUIRE( (float)v == numeric_limits<float>::max() );
} }
{
F4 v( numeric_limits<float>::min() );
REQUIRE( (float)v == numeric_limits<float>::min() );
}
}
SECTION("Modbus constructor") SECTION("Modbus constructor")
{ {
float f = 2^32; {
float f = numeric_limits<float>::max();
ModbusRTU::ModbusData data[4]; ModbusRTU::ModbusData data[4];
memcpy(data,&f,sizeof(data)); memcpy(data,&f,sizeof(data));
F4 v1(data,4); F4 v1(data,4);
REQUIRE( (float)v1 == f ); REQUIRE( (float)v1 == f );
}
{
float f = numeric_limits<float>::max();
ModbusRTU::ModbusData data5[5]; ModbusRTU::ModbusData data5[5];
memset(data5,0,sizeof(data5)); memset(data5,0,sizeof(data5));
memcpy(data5,&f,4*sizeof(ModbusRTU::ModbusData)); memcpy(data5,&f,4*sizeof(ModbusRTU::ModbusData));
F4 v2(data5,5); F4 v2(data5,5);
REQUIRE( (float)v2 == f ); REQUIRE( (float)v2 == f );
} }
{
float f = numeric_limits<float>::min();
ModbusRTU::ModbusData data[4];
memcpy(data,&f,sizeof(data));
F4 v1(data,4);
REQUIRE( (float)v1 == f );
}
}
} }
TEST_CASE("VTypes: Byte","[vtypes][byte]") TEST_CASE("VTypes: Byte","[vtypes][byte]")
......
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