/* * ModbusAnalogValue.cpp * * Created on: 19 мар. 2021 г. * Author: titov */ #include "ModbusAnalogValue.hh" #include "../math/math_inc.hh" #include driver::modbus::ModbusAnalogValue::ModbusAnalogValue( systemic::IValueType & value, float write_coeff, float write_offset, float read_coeff, float read_offset, bool sign, float up_limit, float down_limit, uint16_t nan_register ) : 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) {} driver::modbus::ModbusAnalogValue::Status driver::modbus::ModbusAnalogValue::read( uint16_t & reg ) { using namespace std; float value = tech_value.get(); if( isnan(value) ) reg = nan_out_of_range; else { float temp = value * read_coeff + read_offset; if( temp < down_limit || temp > up_limit ) { reg = nan_out_of_range; } else { if( format_signed ) { int16_t signed_reg = rintf(temp); std::memcpy( ®, &signed_reg, sizeof(reg) ); } else { reg = rintf(temp); } } } return Done; } driver::modbus::ModbusAnalogValue::Status driver::modbus::ModbusAnalogValue::write( uint16_t input ) { if( format_signed ) { int16_t signed_input; std::memcpy( &signed_input, &input, sizeof(input) ); if( signed_input >= down_limit and signed_input <= up_limit ) { tech_value.set( signed_input * write_coeff + write_offset ); return Done; } else return Failure; } else { if( input >= down_limit and input <= up_limit ) { tech_value.set( input * write_coeff + write_offset ); return Done; } else return Failure; } }