Electrically speaking, the PT1 filter acts as a low-pass filter.
For continuous damping, the output of the last operation (outValue) must be stored and used for the next operation. This leads to a result history of 1 value which is enough to damp the input. The functions utilize a conversion of the 2byte input to 4byte to gain precision for division operations.
uint16 dampPT1( uint16 inValue,
uint16* outValue,
const uint16 riseFactor,
const uint16 fallFactor)
{
if(outValue == NULL)
{
return;
}
// Transformation of input to 32 bit internal format to gain precision and add remainder
uint32 calcValue = (((uint32) inValue) << 16) + 32768;
if (*outValue < calcValue)
{
if (m_riseFactor == 0)
{
*outValue = calcValue;
}
else
{
calcValue -= m_dampBuffer;
calcValue /= m_riseFactor;
if (calcValue == 0)
{
calcValue = 1;
}
*outValue += calcValue;
}
}
else
{
if (outValue > calcValue)
{
if (fallFactor == 0)
{
*outValue = calcValue;
}
else
{
calcValue = *outValue - calcValue;
calcValue /= fallFactor;
if (calcValue == 0)
{
calcValue = 1;
}
*outValue -= calcValue;
}
}
}
return (uint16) ((*outValue) >> 16);
}
uint16 dampLimitPT1(uint16 inValue,
uint16* outValue,
const uint16 riseFactor,
const uint16 fallFactor,
const uint16 riseLimit, const uint16 fallLimit)
{
if(outValue == NULL)
{
return;
}
// Transformation of input to 32 bit internal format to gain precision and add remainder
uint32 calcValue = (((uint32) inValue) << 16) + 32768;
// Check if characteristic is rising or falling
if (*outValue < calcValue)
{
// Calculate differnce between old and new value
calcValue -= *outValue;
if (riseFactor != 0)
{
// division of the difference by k
calcValue /= (uint32) riseFactor;
}
else
{
// do nothing here
}
// Check if limit reached
if ((riseLimit != 0xFFFF) && (calcValue > ((uint32) riseLimit << 16)))
{
// Limit reached, set Delta to the maximum
calcValue = ((uint32) riseLimit << 16);
}
*outValue += calcValue;
}
else
{
// Calculate differnce between old and new value
calcValue -= *outValue;
if (fallFactor != 0)
{
// division of the difference by k
calcValue /= (uint32) fallFactor;
}
else
{
// do nothing here
}
// Check if limit reached
if ((fallLimit != 0xFFFF) && calcValue > ((uint32) fallLimit << 16))
{
// Limit reached, set Delta to the maximum
calcValue = ((uint32) fallLimit << 16);
}
*outValue -= calcValue;
}
return (uint16) (*outValue >> 16);
}
uint16 dampPT2(uint16 inValue,
uint16* bufferPT1,
uint16* bufferPT2,
const uint16 riseFactor,
const uint16 fallFactor)
{
// perform PT1 limited damping on a PT1 damped input
// first damping is configured using rising factor,
// second damping is configured using falling factor
return dampPT1(
dampPT1(inValue, bufferPT1, riseFactor, riseFactor),
bufferPT2, fallFactor, fallFactor);
}
uint16 dampLimitPT2( uint16 inValue,
uint16* bufferPT1,
uint16* bufferPT2,
const uint16 riseFactor,
const uint16 fallFactor,
const uint16 riseLimit,
const uint16 fallLimit)
{
// perform PT1 limited damping on a PT1 damped input
// first damping is configured using rising factor,
// second damping is configured using falling factor and the limits
return dampLimitPT1(
dampPT1(inValue, bufferPT1, riseFactor, riseFactor),
bufferPT2, fallFactor, fallFactor, riseLimit, fallLimit);
}