Join us today!
PLC Analog Input Scaling
Scaling values has numerous applications and aids in aligning output values with their real-world counterparts. Although a majority of scaling is linear, the real-world changes are often not so straightforward. Computers have a different understanding of numbers compared to humans. For example, physical quantities like temperature, pressure, and distance are easily comprehended with units like degrees Celsius, pounds per square inch, or meters. When these values are fed into a digital system through sensors, they must be transformed or scaled into a usable, comprehensible form. Scaling involves mapping a range of analog input values to a corresponding range of limit values, allowing the PLC to measure and interpret the analog signal as a numerical value within a defined range. This process is important for ensuring accurate and reliable measurement and control of analog signals in industrial automation systems.
Let's talk about the two categories of analog signals: voltage and current. The mathematical principles behind the scaling process are identical, regardless of the type of analog input/output used. The choice between a voltage or current I/O depends on the features of the system being controlled. A standard current signal operates within a range of 4 to 20 milliamperes. The lower limit of 4 mA indicates that the sensor still produces an output even when the physical quantity being measured is at its minimum value. On the other hand, the lower limit of a voltage signal is 0 volts and there is no definite way to determine if the 0 volts reading is due to a faulty connection or an actual measurement from the sensor.
Now, let's examine the formula for scaling the analog value. The formula for PLC analog input scaling is as follows:
Scaled Value = ((Current Analog Value - Analog Input Min) / (Analog Input Max- Analog Input Min)) * (Max Output - Min Output) +Min Output
Where:
- Current Analog Value: The current analog input value.
- Analog Input Min: The minimum value of the analog input range.
- Analog Input Max: The maximum value of the analog input range.
- Min Output: The minimum value of the desired output range.
- Max Output : The maximum value of the desired output range.
- Scaled Value: The resulting value after scaling the analog input.
The first part of this formula is called normalizing the analog input. It is used to adjust the value of an analog input to a linear scale by mapping it to a specific range. The MIN and MAX analog parameters are used to set the limits of the value range that will be used in the scaling process. The result, stored as a floating-point number, is calculated based on the location of the value being normalized within the defined value range. If the value being normalized is equal to the minimum value, the OUT output will be equal to "0.0". If the value being normalized is equal to the maximum value, the OUT output will be equal to "1.0".
Normalizing formula can be seen below:
Next, the scaling formula will be applied using the normalized value and the output range that has been determined.
Now that we have the formula, we can create a function block in TwinCAT to implement the analog input scaling. Create a function block called FB_AnalogScale and add the code below:
FUNCTION_BLOCK FB_AnalogScale VAR_INPUT iEnable : BOOL; iCurrentAnalogValue : REAL; iMaxAnalogValue : REAL; iMinAnalogValue : REAL; iMaxLimit : REAL; iMinLimit : REAL; END_VAR VAR_OUTPUT qScaledValue : REAL; END_VAR VAR fNormalizedValue : REAL; fScaledValue : REAL; END_VAR
//Init Variables fScaledValue := 0; fNormalizedValue := 0; qScaledValue := 0; //Check input enable IF NOT iEnable THEN RETURN; END_IF //Normalize the analog input IF iCurrentAnalogValue < iMinAnalogValue THEN fNormalizedValue := 0; ELSIF iCurrentAnalogValue > iMaxAnalogValue THEN fNormalizedValue := 1; ELSE fNormalizedValue := (iCurrentAnalogValue - iMinAnalogValue) / (iMaxAnalogValue - iMinAnalogValue); END_IF //Scale the output fScaledValue := fNormalizedValue * (iMaxLimit - iMinLimit) + iMinLimit; //Write outputs qScaledValue := fScaledValue;
Let's give some input values to this function block and test our implementation:
In the example above, we set the desired output range from 200 to 1000. When the analog input value is 16384, we can see that the scaled output is 600 since we set the analog range from 0 to 32767.
You can check the datasheet of your analog input card to determine the minimum and maximum analog reading values.
In case you want to say thank you !)
We'd be very grateful if you could share this community with your colleagues and friends. You can also buy us a coffee to keep us fueled 😊 This is the best way to say thank you to this project and support your community.
twinControls - https://twincontrols.com/
Hello,
thanks for the article 😉 , to improve the code you can make a bit of error..., 🧐
in this way before carrying out the conversion it is checked if it can be done and a bit of error is obtained... ☕
attached image...
https://github.com/runtimevic
https://github.com/TcMotion
https://www.youtube.com/playlist?list=PLEfi_hUmmSjFpfdJ6yw3B9yj7dWHYkHmQ
https://github.com/VisualPLC
@runtimevictor Hello, Thank you for the improvement idea! I have modified the code as below:
//Normalize the analog input IF iCurrentAnalogValue < iMinAnalogValue THEN fNormalizedValue := 0; ELSIF iCurrentAnalogValue > iMaxAnalogValue THEN fNormalizedValue := 1; ELSE fNormalizedValue := (iCurrentAnalogValue - iMinAnalogValue) / (iMaxAnalogValue - iMinAnalogValue); END_IF
Instead of raising an error flag, if the current analog value is lower than min analog reading, we can use 0 for the normalized value and if the current analog value is higher than max analog reading, we can use 1 for the normalized value.
In case you want to say thank you !)
We'd be very grateful if you could share this community with your colleagues and friends. You can also buy us a coffee to keep us fueled 😊 This is the best way to say thank you to this project and support your community.
twinControls - https://twincontrols.com/
I would improve it even more, think that if the divisor is 0,
when dividing it by 0 it will give you an error, I would also take this into account,
that if what you are going to divide is zero,
do not perform the division so that there is no error and give as a result 0...
https://github.com/runtimevic
https://github.com/TcMotion
https://www.youtube.com/playlist?list=PLEfi_hUmmSjFpfdJ6yw3B9yj7dWHYkHmQ
https://github.com/VisualPLC
@runtimevictor That'd be nice! Or you can add Implicit Division Check in your project 🙂
In case you want to say thank you !)
We'd be very grateful if you could share this community with your colleagues and friends. You can also buy us a coffee to keep us fueled 😊 This is the best way to say thank you to this project and support your community.
twinControls - https://twincontrols.com/
I seem to remember that they explained to me that the implicit monitoring checks consume a lot of resources, but I don't know exactly how much so that adding them could affect the cycle...., or it is minimal and with the CPUs that are getting better every time it is insignificant...
I honestly don't know how much it affects...
https://github.com/runtimevic
https://github.com/TcMotion
https://www.youtube.com/playlist?list=PLEfi_hUmmSjFpfdJ6yw3B9yj7dWHYkHmQ
https://github.com/VisualPLC
Nice post.
I just wanted to add that this is essentally linear interpolation commonly referred to as lerp.
Here's a simplified equation.
lerp(a, b, t) = a + (b-a)*t where: a = start b = end c = percentage
For example, the halfway mark between 50 and 100 is :
lerp(50,100, 0.5) = 75
The neat thing about this is that you dont have to scale 4-20mA. Just scale the resolution.
Suppose youre scaling a 4-20mA signal for a 0-100mBar pressure transducer connected to an analogue input card that reads 32,768 level. Simpy do
Pressure = lerp(0, 100, (x/32767)) where: x = I/O link variable.
If you want the reading in Ampere then:
Current = lerp(4, 20, (x/32767))
If you want to map the current to the pressure range then:
Pressure = lerp(0, 100, ß) where: ß = (x-4) / (20-4) x = 4-20mA input
lerp is commonly used in animation and nicely leads to Bézier curves.
Here's a good video on Lerp and Bézier curves: https://youtu.be/aVwxzDHniEw
- 17 Forums
- 267 Topics
- 942 Posts
- 0 Online
- 722 Members