Hello everyone! I am Xiao Wang, a veteran in the field of industrial automation for over ten years. Today, I would like to share some insights from my experience in developing a recipe control system using the Siemens S7-1500 PLC. Over the years, I have handled dozens of recipe projects, learned from my mistakes, and I hope to provide some help to those of you who are on this path.
Why Choose S7-1500 for Recipe Control?
I remember when I first got involved with automatic recipe systems, I was still using the S7-300 series. As project complexity increased and control precision requirements rose, I gradually shifted to the S7-1500. Why? Mainly because of the following advantages:
- Fast computation speed, with CPU instruction processing efficiency several times that of S7-300
 - Supports floating-point operations, which are particularly important for ratio calculations in the recipe process
 - Flexible modular design, allowing for I/O expansion based on different recipe scales
 - The TIA Portal programming environment is user-friendly, especially in supporting visual programming for recipe processes
 
If you are also hesitating about which PLC to choose for recipe control, my suggestion is: for small to medium systems, the S7-1200 is sufficient; for high precision requirements or large systems, the S7-1500 is a better choice.
Key Points in Hardware Configuration
The selection of hardware for the recipe system is crucial to its success. I once underestimated project requirements and chose a standard CPU instead of a high-performance version, resulting in memory bottlenecks during later expansions. Therefore, I have summarized the following key points:
CPU Selection
- Standard applications: CPU 1513-1 PN is sufficient for general recipe tasks
 - High precision applications: It is recommended to use CPU 1516-3 PN/DP, which has stronger computing capabilities
 - Complex applications with multiple recipes: CPU 1518-4 PN/DP, with larger memory to store more recipes
 
I/O Module Configuration
- Analog input card: SM 531 for receiving weight sensor signals
 - Analog output card: SM 532 for controlling proportional valves or frequency converters
 - Digital I/O: for controlling components such as solenoid valves and motors
 
Communication Expansion
- PROFINET interface: to connect HMI, upper computers, or other devices
 - PROFIBUS-DP: for communication with field devices such as frequency converters and servos
 
Tip: My personal experience is to reserve 30% more I/O points, so that later expansions are not chaotic.
Core Algorithm Design for Recipe Control
When it comes to recipe control, the core is actually “precision”. Without sufficient precision, everything is in vain. I made mistakes in early projects by using simple switch control, resulting in inter-batch errors as high as 5%, which left customers very dissatisfied.
Application of PID Control Principle
In the recipe process, I mainly used PID closed-loop control, which is especially suitable for liquid recipes:
// PID controller parameter settings
"PID_Compact_1".SetpointLimitHigh := 100.0;  // Upper limit of setpoint
"PID_Compact_1".SetpointLimitLow := 0.0;     // Lower limit of setpoint
"PID_Compact_1".InputLimitHigh := 100.0;     // Upper limit of input value  
"PID_Compact_1".InputLimitLow := 0.0;        // Lower limit of input value
"PID_Compact_1".Setpoint := #Target_Weight;  // Set target weight
// Calculate output value
#PID_Output := "PID_Compact_1".Output;
However, it is important to note that tuning PID parameters is a technical task. My usual approach is:
- First set Ki and Kd to 0, adjust Kp until the system has slight oscillations
 - Slowly increase Ki until static error is eliminated
 - Fine-tune Kd as needed to improve dynamic response
 
Two-Stage Control Strategy
For powder materials, I prefer to use a “fast-slow” two-stage control:
IF #Current_Weight < (#Target_Weight - #Slow_Threshold) THEN
    // Fast feeding
    #Fast_Valve := TRUE;
    #Slow_Valve := TRUE;
ELSIF #Current_Weight < #Target_Weight THEN
    // Slow feeding
    #Fast_Valve := FALSE;
    #Slow_Valve := TRUE;
ELSE
    // Stop feeding
    #Fast_Valve := FALSE;
    #Slow_Valve := FALSE;
END_IF;
My experience is to set the slow threshold to 10%-15% of the target value, which balances efficiency and precision.
Weight Signal Processing Techniques
The core of the recipe system is weight accuracy, and signal processing is key to ensuring weight accuracy.
Implementation of Filtering Algorithm
Weight signals are often disturbed by vibrations, so I used moving average filtering:
// 10-point moving average filtering
#Sum := #Sum - #Weight_Buffer[#Index];  // Subtract the oldest data
#Weight_Buffer[#Index] := #Raw_Weight;  // Save the current reading
#Sum := #Sum + #Raw_Weight;             // Add the new reading
#Index := (#Index + 1) MOD 10;          // Update index
#Filtered_Weight := #Sum / 10.0;        // Calculate average
For high-speed recipes, I reduce the number of sampling points to improve response speed; for situations requiring high stability, I increase the number of sampling points.
Zero Drift Compensation
Zero drift is a common issue in weighing systems. I added automatic calibration logic:
// Automatic zero calibration (only when unloaded and stable)
IF #System_Idle AND ABS(#Raw_Weight) < #Stability_Threshold THEN
    #Zero_Offset := #Raw_Weight;
END_IF;
// Reading compensation
#Actual_Weight := #Filtered_Weight - #Zero_Offset;
Tip: It is recommended to perform a zero calibration each time the system is powered on, after long-term operation, or when there are significant temperature changes.
Multi-Material Coordinated Recipe Solutions
When dealing with multi-material recipes, the order and timing of the recipe directly affect production efficiency. I once worked on a mixing system with 15 raw materials, and if I simply followed the order, the cycle took as long as 40 minutes. Later, I optimized the strategy and reduced it to 12 minutes.
Parallel Recipe Strategy
For materials that do not interfere with each other, parallel recipes can be used:
// Determine if materials can be added in parallel
IF #Material_A_Ready AND NOT #Material_B_Conflict THEN
    #Start_Material_A := TRUE;
END_IF;
IF #Material_B_Ready AND NOT #Material_A_Conflict THEN
    #Start_Material_B := TRUE;
END_IF;
Suggestion: Establish a material conflict matrix to clarify which materials can be added in parallel and which must be added in sequence.
Recipe Management Solutions
Create a structured recipe data block:
// Recipe data block structure
"Recipe_DB".Recipe[#Recipe_Index].Material_ID[1] := 101;
"Recipe_DB".Recipe[#Recipe_Index].Weight[1] := 50.5;
"Recipe_DB".Recipe[#Recipe_Index].Tolerance[1] := 0.2;
I usually design a recipe editor interface that allows operators to create and modify recipes themselves, greatly enhancing system flexibility.
Sharing Practical Application Cases
Last year, I was responsible for a fully automatic recipe system for food additives, which included 8 types of powdered raw materials and 4 types of liquid raw materials. This project had several challenges:
- Powder materials tend to clump, affecting flowability
 - Liquid raw materials have different viscosities, leading to significant differences in flow characteristics
 - The customer required a recipe accuracy of ±0.1%
 
How Did I Solve It?
For the powder material issue, I designed a feedback adaptive control:
// Adaptive flow control
#Expected_Flow_Rate := #Standard_Flow_Rate;
// Adjust parameters based on actual flow
IF #Actual_Flow_Rate < (#Expected_Flow_Rate * 0.8) THEN
    // Detect blockage, activate vibrator
    #Vibrator := TRUE;
    // Lower expected flow to adapt
    #Expected_Flow_Rate := #Actual_Flow_Rate * 1.2;
END_IF;
For liquid raw materials, I calibrated the flow characteristic curve for each material separately and stored it in a data block for reference.
After these optimizations, the system operated stably, achieving a recipe accuracy of ±0.08%, and the customer was very satisfied.
Debugging Tips and Troubleshooting
The debugging phase is often the most troublesome. I have a habit: every project must have a “debug data block” that contains all key variables for real-time monitoring:
// Debug data block
"Debug_DB".Current_Step := #Step;
"Debug_DB".Target_Weight := #Target_Weight;
"Debug_DB".Actual_Weight := #Actual_Weight;
"Debug_DB".Valve_Status := #Valve_Output;
"Debug_DB".Error_Code := #Error_Code;
Common Problems and Solutions
- Unstable recipe: Check the weight sensor signal, enhance filtering; check mechanical vibration sources
 - Recipe overshoot: Reduce the Ki parameter in PID; increase the proportion of the slow stage
 - Communication interruption: Check PROFINET network connections; confirm device IP configuration
 - Large inter-batch error: This may be a residue issue; add an automatic cleaning program
 
Tip: Before each debugging session, verify the weighing system with a known weight to ensure basic accuracy.