144 lines
3.3 KiB
C++
144 lines
3.3 KiB
C++
/*
|
|
* ModbusAnalogWideValue.cpp
|
|
*
|
|
* Created on: 17 àïð. 2023 ã.
|
|
* Author: titov
|
|
*/
|
|
|
|
#include "ModbusAnalogWideValue.hh"
|
|
|
|
#include <cstring>
|
|
#include <math.h>
|
|
|
|
bool driver::modbus::ModbusAnalogWideValue::extract() {
|
|
|
|
using namespace std;
|
|
|
|
float value = tech_value.get();
|
|
|
|
if( isnan(value) )
|
|
|
|
memcpy( data, &nan_out_of_range, sizeof(uint32_t) );
|
|
|
|
else {
|
|
|
|
float temp = value * read_coeff + read_offset;
|
|
if( temp < down_limit || temp > up_limit ) {
|
|
|
|
memcpy( data, &nan_out_of_range, sizeof(uint32_t) );
|
|
|
|
} else {
|
|
if( format_signed ) {
|
|
|
|
int32_t signed_reg = rintf(temp);
|
|
memcpy( data, &signed_reg, sizeof(int32_t) );
|
|
|
|
} else {
|
|
|
|
uint32_t unsigned_input = rintf(temp);
|
|
memcpy( data, &unsigned_input, sizeof(uint32_t) );
|
|
|
|
}
|
|
}
|
|
}
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
bool driver::modbus::ModbusAnalogWideValue::update() {
|
|
|
|
if( format_signed ) {
|
|
|
|
int32_t signed_input;
|
|
memcpy( &signed_input, data, sizeof(int32_t) );
|
|
|
|
if( signed_input >= down_limit and signed_input <= up_limit ) {
|
|
|
|
tech_value.set( signed_input * write_coeff + write_offset );
|
|
|
|
return true;
|
|
|
|
} else
|
|
return false;
|
|
|
|
} else {
|
|
|
|
uint32_t unsigned_input;
|
|
memcpy( &unsigned_input, data, sizeof(uint32_t) );
|
|
|
|
if( unsigned_input >= down_limit and unsigned_input <= up_limit ) {
|
|
|
|
tech_value.set( unsigned_input * write_coeff + write_offset );
|
|
|
|
return true;
|
|
|
|
} else
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
driver::modbus::ModbusAnalogWideValue::Status driver::modbus::ModbusAnalogWideValue::PartShower::read(
|
|
uint16_t & reg ) {
|
|
|
|
if( self.extract() ) {
|
|
|
|
reg = *data;
|
|
|
|
return Done;
|
|
|
|
} else
|
|
return Failure;
|
|
|
|
}
|
|
|
|
driver::modbus::ModbusAnalogWideValue::Status driver::modbus::ModbusAnalogWideValue::PartShower::write(
|
|
uint16_t reg ) {
|
|
|
|
*data = reg;
|
|
|
|
return Done;
|
|
|
|
}
|
|
|
|
driver::modbus::ModbusAnalogWideValue::PartUpdater::Status driver::modbus::ModbusAnalogWideValue::PartUpdater::read(
|
|
uint16_t & reg ) {
|
|
|
|
reg = *data;
|
|
|
|
return Done;
|
|
|
|
}
|
|
|
|
driver::modbus::ModbusAnalogWideValue::PartUpdater::Status driver::modbus::ModbusAnalogWideValue::PartUpdater::write(
|
|
uint16_t reg ) {
|
|
|
|
return *data = reg, self.update() ? Done : Failure;
|
|
|
|
}
|
|
|
|
driver::modbus::ModbusAnalogWideValue::ModbusAnalogWideValue(
|
|
systemic::IValueType<float> &value, float write_coeff,
|
|
float write_offset, float read_coeff, float read_offset, bool sign,
|
|
float up_limit, float down_limit, uint32_t nan_register,
|
|
WordSequence sequnece) : tech_value(value),
|
|
format_signed(sign), nan_out_of_range(nan_register),
|
|
down_limit(down_limit), up_limit(up_limit),
|
|
write_coeff(write_coeff), write_offset(write_offset), read_coeff(read_coeff), read_offset(read_offset),
|
|
one( *this, sequnece == LowFirstHighSecond ? &data[1] : &data[0] ),
|
|
two( *this, sequnece == HighFirstLowSecond ? &data[1] : &data[0] ) {}
|
|
|
|
driver::modbus::IModBusDispatch & driver::modbus::ModbusAnalogWideValue::first() {
|
|
|
|
return one;
|
|
|
|
}
|
|
|
|
driver::modbus::IModBusDispatch & driver::modbus::ModbusAnalogWideValue::second() {
|
|
|
|
return two;
|
|
|
|
}
|