MotorControlModuleSDFM_TMS3.../Projects/EFC_Communication/UMLibrary/driver/ModbusAnalogWideValue.cpp
2024-06-07 11:12:56 +03:00

144 lines
3.3 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/*
* 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;
}