Join us today!

PLC Analog Input Sc...
 
Notifications
Clear all

PLC Analog Input Scaling

7 Posts
3 Users
7 Reactions
10.8 K Views
twinControls
Posts: 114
Admin
Topic starter
(@twincontrols)
Member
Joined: 2 years ago

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: 

normalizedOut

 

Next, the scaling formula will be applied using the normalized value and the output range that has been determined.

scaledOut

 

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: 

analogScaledOut

 

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.

 

 

 

Reply
6 Replies
5 Replies
runtimevictor
(@runtimevictor)
Joined: 2 years ago

Estimable Member
Posts: 156

@twincontrols ,

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...

FC AnalogScaling With OutputError
Reply
twinControls
Admin
(@twincontrols)
Joined: 2 years ago

Member
Posts: 114

@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. 

Reply
runtimevictor
(@runtimevictor)
Joined: 2 years ago

Estimable Member
Posts: 156

@twincontrols ,

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...

Reply
twinControls
Admin
(@twincontrols)
Joined: 2 years ago

Member
Posts: 114

@runtimevictor That'd be nice! Or you can add Implicit Division Check in your project 🙂 

Implicit Monitoring

Reply
runtimevictor
(@runtimevictor)
Joined: 2 years ago

Estimable Member
Posts: 156

@twincontrols ,

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...

Reply
Posts: 6
(@fisothemes)
Active Member
Joined: 1 year ago

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

 

Reply
Share: