사용자 도구

사이트 도구

English

cublocapp:an32009:index

AN32009 - PID 제어

PID제어 데모 프로그램입니다. 이 프로그램을 실행시켜보기 위해서는 StampPlot 라는 프로그램이 필요합니다.

미국 유저가 작성한 소스라서 설명이 온통 영어네요. ㅠ

AD420 DA칩을 써서, PID 제어 출력 결과를 0~5V로 출력하는 프로그램입니다. 화면에 StampPlot를 띄우고 RS232C를 연결해서 추적과정을 볼 수 있게 해 놓았습니다.

StampPlot 다운 받기

pid_demo.zip

' ==============================================================================================================
'File: Cubloc_CB2xx_PID_Voltage_R1.cul 
'Purpose: Demonstrates PID Close Loop Voltage Control on the CB220 / CB280 / CB290 PLCs.
'                      A simple Real Time Operating System using TimeSlice on the CB2xx PLCs.
'                      "Analog Process Functions" used in PID control.
'                      Floating math routines in PID control.
'                      Proper "safety" programming in PID process control.
'                      PID design and engineering hints.
'                      PID Basics.
'                           
'============================================================================
'This PID Voltage Demo outputs a voltage from a voltage DAC onto the A/D input
'for feedback indication. The process speed is very fast. This application can
'expanded and be used in power supply designs. 
'=============================================================================
'                          
'Author:                     Unknown
'E-mail: 
'Started:                    10/05/2005
'Updated:                    10/05/2005
'Revision:                   R1.0B - Beta - Prototype - NOT FINAL!!!! 
'Device used with test code: CB280 with Study Board 1
'Devices that can be used:   CB2xx 
'Code Tested:                Yes - OK
'
'CUBLOC Version:             1.2F 
'Date:                       10/26/2005 
'CUBLOC Studio:              1.2F 
'
'
'                       
'===============================================================================================================
'
'                                                [Code Revisions]
'Rev. 1.0B 10/24/05 (Beta)     
'
'
'===============================================================================================================
' Disclaimer ***** Disclaimer ******* Disclaimer ******* Disclaimer ******** Disclaimer ******** Disclaimer
'
' If you use this prototype PID algorithm and your house burns down, your dog dies and your wife and children
' become homeless or worst yet, you destroy all your Cubloc CB2xx equipment, do not hold me responsible for your actions!!!
'        
' Disclaimer ***** Disclaimer ******* Disclaimer ******* Disclaimer ******** Disclaimer ******** Disclaimer
'===============================================================================================================
'
'                                     [PID Demo "Close Loop" Lighting Control]
'
'                                   
'
' Process:                 Power
' Process Driver:          CB2xx AD420 0-5 VDC (Voltage DAC) driving CB2xx Analog Input AD(2) P26
' Process Sensor:          Voltage           
' Process Feedback:        DAC               
' Process Speed:           Fast           
'  
' Calibration:             No calibration is needed on the feedback and on the precison current DAC AD420.
'                                    
' Feedback Sensor Range:   0 - 5 VDC       
'
'===============================================================================================================
'
'                                    [Wiring Diagram between CB2xx & AD420 ]
'                                         [*See spec sheet for details]
'
'                                                -----   ------
'                                               /     |  |     |
'                                              |       --      |
'                                              |  AD420ANZ-32  |
'                                              |      U1       |
'                        C3            NC------| 1          24 |------NC 
'                       0.1 uf                 |               |         ***** Warning - Do not connect to 5VDC***        
'              To Gnd o--| |------------o------| 2 VLL  Vcc 23 |------o--------o----o- *****Connect to +24 VDC Vcc***** 
'                                              |               |               |    |        
'                                    NC o------| 3 Fault    22 |------NC 0.01uf|    | 0.1 uf 
'                                              |               |         C1    |   ___    
'                  Gnd *-----------------------| 4 Rng #1   21 |------o--| |---o   ___ C4
'                        [0-5VDC Select]       |               |         C2    |    |
'                  Gnd *-----------------------| 5 Rng #2   20 |------o--| |---o    | 
'                                              |               |         0.01uf   ----- To Gnd
'                                    NC o------| 6 CLr  Bst 19 |------NC           ---     
'                                              |               |                      
'                        To CB2XX P12   o------| 7 Lch Iout 18 |------NC  
'                                              |               |                                                              
'                        To CB2XX P15   o------| 8 Clock    17 |------o [Driver 0-5VDC) To CB2xx P25 AD(2) [Feedback]                                 
'                                              |               |                                                 
'                        To CB2XX P11   o------| 9 Data     16 |------NC                                                 
'                                              |               |                      
'                                        ------| 10     Rin 15 |------o            
'                                              |               |      | Jumper                           
'                                  To Gnd------| 11 Gnd Rout14 |------o pins      
'                                              |               |        14-15    
'                                      NC------| 12         13 |------NC         
'                                              |               |                         
'                                               --------------  
'                                    Standard Configuration for 0-5VDC output   
'                                              NC = No Connect
'                                      (Fault and Clear usage is optional)
'
'
'
'    Digikey Parts:      
'             1 C1 0.01uf NPO Cap    399-1976-ND  $1.11
'             1 C2 0.01uf NPO Cap    399-1976-ND  $1.11
'             1 C3 0.1uf Cap         399-2143-ND  $0.16
'             1 C4 0.1uf Cap         399-2143-ND  $0.16                          
'             1 U1 16 Bit DAC     AD420ANZ-32-ND $18.98
'                                          
'   
'
'   * Notes: Check spec sheet for PCB layout considerations, grounding & components.
'            Other range options include 4-20 ma, 0-24ma , 0-20ma, 0-10VDC, +-5 VDC & +-10 VDC - see spec sheet.  
'            To "industrialize" this device opto-isolators are needed between the CB2xx and the AD420.
'            Connect both the +24VDC Ground and the 5 VDC grounds together BUT NOT THE AD420 VCC +24 VDC TO 5 VDC! - see spec sheet. 
'            Zero and Span pots can be added for additional output adjustment. (See spec sheet)
'             
'
'    Additional Equipment:
'         1 Cubloc Study Board 1 - For easy prototyping of circuits
'         1 Cubloc USB to RS232 cable for plotting PID variables
'         1 +24 VDC 0.5 amp regulated power supply (Fused)
'
'    
'                    
'   
'
'==================================================================================================================       
'==================================================================================================================
'
'                                    [Program Operation / Description / PID Crash Course]
'
'==================================================================================================================
'
' PID (Proportional, Integral & Derivative) The most dreaded three letter word in PLC Control!
'
' PID is complex because a person would need to know software, hardware interfacing, and process control.
' 
' The reason why PID is not common in small microprocessors is the "floating point overhead" and instruction speed.
' Cubloc CB2xx PLC series has both floating point math and instruction speed of 36,000 instructions/second. 
'
' PID control mimics an electrical opamp.
'
' PID Control is a "close loop system" e.g. a feedback is provided to the control loop to monitor the process being
' controlled.
'
' Considerable expertise is required to properly design a system to avoid oscillations or sluggish responses.
' This PID algorithm compares the feedback from the process sensor and the setpoint to determine the appropriate
' analog 0-100% output variable. This output could drive PWM (Pulse Width Modulation) 0-5 VDC output or a DAC normally
' 4-20 ma. or 0-10 VDC. Typical driven outputs could connect to thermal, motion, lighting, flow and power.
' The controller drive is automatically adjusted until the measured sensor signal matches the desired setpoint.
' 
' The CB220 or CB2xx sends a setpoint signal to the PID subroutine. The PID subroutine then calls the PID function,
' which is made up of three elements: the Proportional, Integral, and Derivative routines. The Proportional routine
' creates an output signal proportional to the difference (error) between the measurement taken and the setpoint. 
' The Integral routine produces an output proportional to the length and amount of time the error signal is present.
' The Derivative routine creates an output signal proportional to the rate of change of the error signal.
'
' The input transducer generates an output signal from the process being controlled and feeds the measured value to 
' the PID subroutine. Analog inputs (4-20ma) are normally used to acquire the feedback signal. The difference between
' the setpoint generated by the CB2xx PLC and the measure value coming from the input transducer is the Error signal.
' Some sort of correcting device such as a motor control, valve control, or amplifier takes the error signal and 
' uses it to control the correction sent to the process being controlled.  
'
' Possible processes for PID control/simulation are:
'  
' [Process]   [Driver]     [Speed]    [Sensor]       [Sensor Feedback]
'   Power      Bridge       Fast        Voltage       Voltage to A/D
'   Motion    Amplifier     Fast       Position       Encoder,frequency(magnetic pickup,Hall effect pickup)
'   Thermal   FET (PWM)   Very Slow   Temperature     RTD,Thermocuple,Thermistor,
'                                                     Solid State Temp.Sensor (LM34,AD590,AD592)  
'  Lighting    Triac        Slow       Intensity      Digital Light Sensor TSL230, Cadmium Sulfide PhotoCell
'   Flow       Buffer       Fast        Rate          Turbine flowmeter/counter
'
'==================================================================================================================
'
' 
'  Just having the PID algorithm software is not enough. Careful thought is needed in designing the control loop around
'  the process - NOT the other way around!
'
'  Items to consider when designing and engineering a "closed PID Loop" for control:
'    
'  #1. Is the control loop "control action" forward or reverse acting?
'      This Voltage PID control action is forward acting - an increase in the control output will increase the feedback 
'      voltage.  
'
'  #2. Range of feedback sensor? 
'      Too small of range will cause the control loop to become unstable and untunable. 
'      Extreme care should be taken to have the proper range for the process feedback.  
'
'  #3. Will the control output driver work properly with the process e.g. Pulse Width Modulation? / Voltage? / Current?
'      PWM is well suited for heating control and other slow processes. For precision "non pulsing" control you need 
'      a true precision current/voltage output DAC.
'      The smooth output from the 16 Bit AD420 current DAC is well suited for this application.
'        
'  #4. Is the driver output failsafe? 
'      This Voltage control is failsafe because if the output wire is opened or the driver fails the voltage source will
'      not function and goes to a safe condition as oppose to "100% full control action"
'
'  #5. How will the calibration be performed on the control loop driver and feedback?
'      No calibration is needed for this PID voltage close control loop demo.
'      Note: The output 16 bit precison current DAC has the option of being trimmed with a zero and span pots.            
'
'  #6. How will you filter the feedback signal?
'      Analog feedback signals are easier to filter than a "counter input" signal.
'      No filtering is required for this application.   
'
'  #7. How fast of integral scan rate do you need? 
'      In this Voltage PID control, the control action is fast, so the scan rate can also be fast.
'      The fixed scan time, for this control, is 40ms or PID update time of 25 times per second. This process 
'      scan rate can even run at a much faster rate.
'
'  #8. How will you view the process to tune it with the "P" "I" variables? 
'      I took care of that - a plotting interface to the FREE StampPlotPro version 3.6 was designed into Comm 1. 
'      The feedback, setpoint, error and control outputs are all visible at the same time. This software will work 
'      for ten minutes and will quit. Just close the window out and restart the program via icon or buy the license for $20. 
'      (Have the icon on your window handy)
'      Note: When using PWM, the control action is so fast that you cannot see it "all" in the plotting software.   
'
'
'  #9. How fast is the process feedback? 
'      Don't violate Nyquest therom. The sample rate of the process feedback should be 2x.
'      For example, if you are reading RPM and the hertz feedback is 365 hz for 8000 rpms then the integral scan time
'      should be 2 x 365 = 730 hz or 1/730hz = 1.3ms.   
'      
' #10. How will you read the feedback - by Analog? or by Digital? 
'      Analogs can be scanned and filtered easily. 
'      Digital counter inputs (Counter 0 or 1 inputs) are hard to filter in a fixed scanned timeslice RTOS.
'
' #11. On a feedback sensor failure what should you do to the control output?
'      You should disable the control output to zero. (No control output @ 0%) 
'      Safety is the TOP PRIORITY in any PID close control loop design.
'      
' #12. On a mis-tuned or faulty control loop how will you know if there is a problem?
'      Use the deviation error setpoint along with the error flag LED.
'
' #13. What is PID windup?
'      The PID checks the difference between the feedback and setpoint and multiplies the "P" gain of this error for
'      the control output. The intregral resets or reads this PID calculation every 40ms times the "I" tuning variable.
'      This sum error plus the gain error is added together for the control output signal. If the control loop is 
'      un-responsive, mis-tuned or have a hardware failure, the control output will try increase the control output
'      to bring the feedback and setpoint equal. This sum error will keep increasing in value (single = +3.402823E+38)
'      until it sees the feedback signal equal the setpoint. Since this delay is dependent on the scan rate, the 
'      response would be erratic or sluggest or hard to tune. 
'
' #14. How do you slow down the output PID control action?
'      Decrease the "P" gain value and / or 
'      Decrease the "I" integral value.
'      Note: Warning ... The above PID tuning parameters all interact with each other!!!!!            
'
' #15. How do you increase the output PID control action?
'      Increase the "P" gain value and / or 
'      Increase the "I" integral value.
'      Note: Warning ... The above PID tuning parameters all interact with each other!!!!! 
'                 
'==================================================================================================================
'******************************************************************************************************************
' If you do not have a clear understanding of the PID basics above, please do not continue! Crack open some PID books. 
' If you do, please call the fire department and put them "on standby" and, please do, continue on.
'******************************************************************************************************************
'==================================================================================================================
'
' The operation of the PID close loop Voltage Control has only has two commands "Voltage_Feedback via AD(2)" 
' and "gosub PID1" 
' The rest of the code supports these two commands.(3.906k flash & 423 bytes ram) You set the voltage setpoint from
' 0  - 100%. The software will read the feedback voltage, then computes the error and then outputs
' a 0-5 VDC output to bring the process in control (Voltage setpoint = Feedback Voltage). The PID will
' only control when there is an error between the setpoint and feedback, if the feedback is above the setpoint there
' will be no control output. (0%)  
'
' Start your testing by adjusting the setpoint (~line 832) up / down. Check the response by plotting the PID variables.
'
' 
' The tuning is simple, just adjust the "P" or "I" constants.
' (Do not adjust the 'D" The D is the rate of change which in most PID control applications is not used.)
' Check for overshoot, slow response or too fast of control response using the plotting software. This process is very 
' slow and very forgiving when tuning the "P" And "I" terms. The key in PID tuning is to make the output control action
' output smooth (not erratic) yet responsive to setpoint step changes. 
' After going thru all the possible combinations, you will become THE PID EXPERT!
'
'==================================================================================================================
'
' Suggested Do's and Do Nots
'
' Do read every line of this code to form a complete understanding on how the PID controller works.
' Do extensive PID plotting to anaylize the PID process.
' Do connect the grounds from both the protoboard and the external power supply.
' Do be careful in modifying this code.
' Do use RTOS timeclass 1 or 2 for the basic debug command not timeclass 0. 
'    (adds delays, timeclass overruns, and tuning problems)
' Do the test "4 channel analog plot" from the website to make sure the plotting software will work.
' Do connect the timeclass LEDs and PID error LEDs for troubleshooting.
' Do try changing the plotting variables for different PID values. ~ line # 576.
' Do try making multiple copies of this original program for different PID testing values.   
' 
' Do not combine the 5VDC from the protoboard and external 24 VDC regulated FUSED power supply!
' Do not add any code that delays the timing of the two gosub main routines in the 40ms timeclass 0.
' Do not edit the PID macro (using notepad) for the plotting software unless you know what you are doing.
'  
'==================================================================================================================
'==================================================================================================================
'==================================================================================================================
'
'                                             [Beginning of Basic/Ladder Code]
'
'
'==================================================================================================================
'
'                                             [Device Set]
'
Const Device = CB280  ' Set Device
'==================================================================================================================
'
'==================================================================================================================
'
'                                             [Device Ram Clear]
'  
Ramclear              ' Clear All Ram variables on power up
'==================================================================================================================
'
'                                             [Basic / Ladder Debugging]
' 
Set Debug Off        ' Disable all basic debug commands in basic code (Ladder monitor power flow enable)
'Set Debug On         ' Enable  all basic debug commands in basic code (Ladder monitor power flow disable)
                      ' Ladder monitor and basic debug cannot be used at the same time!
                      ' Choose one or the other
'==================================================================================================================
'
'==================================================================================================================
'
'                                             [Basic Variables Defines]
'
'=============================Timeslice===========================================================================
'
' 
' PID control needs a constant fixed scan rate to update the PID calculations. Tuning would be impossible if the 
' basic program was to "run free". Any additions or deletions to the code size would alter the tuning constants for
' the PID calcuation. That is why this Timeslice RTOS was created.
'
' With the Timeslice code you can do the following:
' #1 Execute any number of tasks at regular intervals. (e.g. every 40 ms / 100ms / 500 ms)
' #2 You can choose the frequency of executing each task by altering the Time_Class_x_Counter_Max.
' #3 You can choose the order of execution by having the most important task first in the interrupt service routine.
' #4 You can have the slow, infrequent tasks run in the background in the CB2xx "Main Do / Loop".
'
' Basic command "On Timer Gosub Tick_Interrupt" will trigger a 40ms interrupt service routine.
' There are three intervals in this program but only two should be adjusted in the constant table. 40ms
' is the minimum for the first / time class 0 interval. The other are multiples of 40 ms. e.g. 100ms and 500ms.
' The counters in the interrupt service routine, when they reach their Time_Class_x_Counter_Max, will run the 
' code provided by the user. The slowest task runs in the background in the Basic "Main Do /Loop". 
' Diagnostic flags in the Ladder program indicate the time class execution - infrequent tasks will show nothing unless
' you fill lots of code into them. You eyes cannot see at 10ms in the Ladder monitoring mode but you will see 'hits'     
'  
' Hints in CB2xx Timeslicing: 
' Put the fastest code in Time Class 0 (40ms) - code that will be executed every 40ms.
' Put other "medium" user code into Time Class 1 (100ms) 
' Put other user code into the Basic Main Do/Loop. (500ms) Code like math code that does not need the fast execution.
' Put user executing code in proper order - code like "read digital inputs", "read analog inputs", "PID*", 
' "write digital outputs", "write analog outputs".
'
'*************************************************************************************************************     
' DO NOT OVERRUN / OVERFLOW THE TIME CLASSES! ALL Time Classes (all 3) ALL USER CODE WILL HAVE TO RUN WITHIN 40ms! 
' At 36,000 Basic Instructions/sec this means about ONLY 1440 Basic instructions! (1000ms/40ms = 25  36,000/25 = 1440)
' Note: You can change the interrupt time to vary the number of instructions executed per interrupt time.
' Note: Use no pauses or delays in code!
'************************************************************************************************************* 
 
 
Time_Class_0_Counter                           Var     Integer
Time_Class_1_Counter                           Var     Integer
Time_Class_2_Counter                           Var     Integer
 
Time_Class_0_Enable                            Var     Byte
Time_Class_1_Enable                            Var     Byte
Time_Class_2_Enable                            Var     Byte
 
Time_Class_2_Run                               Var     Byte
'
'==============================PID1================================================================================
'
LastError1                                     Var     Single    'Error[-1]
PrevError1                                     Var     Single    'Error[-2]
SumError1                                      Var     Single    'SumError + Error (Sum of Errors)
 
dError1                                        Var     Single    'LastError - PrevError
Error1                                         Var     Single    'Error = Setpoint - PID Feedback
 
 
PIDOutput1                                     Var     Single    'PID Calc Output 0-100%
Feedback1                                      Var     Single    'PID Feedback - Input from process sensor
'                                                                'PID Feedback Scaled to 0-100% from process transducer 
'                                                                 eng. units range. See scaled feedback below.
Fwd_Actuator1                                  Var     Single    'Actuator Output - Forward Acting Control 0-100%
Rev_Actuator1                                  Var     Single    'Actuator Output - Reverse Acting Control 100-0% 
Scale_Feedback1                                Var     Single    'Calc from feedbact range to 0-100% - to PID input    
Setpoint1                                      Var     Single    'Process setpoint scaled  to 0-100% - to PID input    
Scale_Setpoint1                                Var     Single    'Calc from setpoint range to 0-100% - to PID input
Scale_Setpointx1                               Var     Single    'Setpoint scaled going to PID calc function
PID_Output_Raw1                                Var     Single    'PID calculation - not clamped or limited to 0-100% 
 
Proportion1s                                   Var     Single    'Limited Proportion1 value between  0.0 - 1.0
Integral1s                                     Var     Single    'Limited Integral1   value between  0.0 - 1.0
Derivative1s                                   Var     Single    'Limited Derivative1 value between  0.0 - 1.0
 
Proportion1x                                   Var     Single    'Limited Proportion1 value between  0.0 - 1.0
Integral1x                                     Var     Single    'Limited Integral1   value between  0.0 - 1.0
Derivative1x                                   Var     Single    'Limited Derivative1 value between  0.0 - 1.0
 
PID1_Deviation_Error                           Var     Single    'Deviation Error % from PID
PID1_Error                                     Var     Single    'PID1 Deviation Error Flag 1 = True
PID1_Control_Enable                            Var     Single    'Enable PID control output enable = 1
PID1_Control_Output                            Var     Single    
 
Plot_Value                                     Var     String *15'String with 15 chars for plotting	
 
PID1_LB_Test                                   Var     String    'PID loop back test variable
 
Voltage_Feedback                               Var     Single    'DAC 0-5 VDC feedback
 
Data_AD420                                     Var     Integer   'AD420 0-20 VDC
Data_AD420x                                    Var     Integer
 
 
 
 
'=================================================================================================================
'
'                                           [Basic Constants Defines]
'
'======================================Timeslice==================================================================
'
Const Time_Class_0_Counter_Max      = 1        '40  ms (1   x 40ms) MINIMUM TASK SPEED - DO NOT CHANGE!
Const Time_Class_1_Counter_Max      = 2        '80  ms (2   x 40ms) Adjustable by user.
Const Time_Class_2_Counter_Max      = 2.5      '100 ms (2.5 x 40ms) Adjustable by user.
'
'=================================================================================================================
'
'
'
'===================================[PID Tuning Values - Adjustable] =============================================
'=================================================================================================================
'
Const Proportion1  =  0.1   '[Default 0.1] Use within range between > 0.0 - 1 
' 0.1 = 10% gain   [Error = Setpoint - Feedback]   [Error * Proportion] is added to output.
'The Proportional routine creates an output signal proportional to the difference (Error) between the measurement 
'taken and the setpoint. 
'Note: The larger the Proportion number the larger the gain! (1 = 100% and .1 = 10%)
' 
Const Integral1    =  0.01   '[Default 0.01 @ 25/sec] Use within range between > 0.0 - 1  
'                          (.01 = .01 x times the SumError @ 40ms)
'                          Usable Range --> .999( 0.999 x sumerror) to .001(0.001 x sumerror) (0.1 = 10% Integral)
'Integral routine produces an output proportional to the length and amount of time the Error signal is present.                            
'Note: The larger the Integral number, the larger the output signal number. (Integral * SumError)
'Note: Changing the 40ms scan time will change the integral (Sum error) Please retune all PID parameters.     
'       
Const Derivative1  =  0.0  '[Default 0] Keep at  0.  This adjustment stays at zero because "PI" of PID is normally only used in control.                      
'Derivative routine creates an output signal proportional to the "Rate Of Change" of the Error signal.
'(dError = LastError - PrevError) (Derivative * dError)
 
'Note: Warning ... The above PID tuning parameters all interact with each other!!!!! (Even the PWM frequency)
 
Const PID1_Deviation_Error_Setpoint = 3.0 'Deviation Error Setpoint in % -> ABS(Setpoint - Feedback)
 
'================================================================================================================
'================================================================================================================
'
Const TC0_LED              = 0             'Time Class 0 LED Indicator - Please hook up.
Const TC1_LED              = 1             'Time Class 1 LED Indicator - Please hook up.
Const TC2_LED              = 2             'Time Class 2 LED Indicator - Please hook up.
 
Const PID1_Error_LED       = 4             'PID Error (Deviation alarm) and sensor failure combined. Please hook up.
 
Const Voltage_Input        = 26            'Analog 2 for voltage feedback 
 
Const Plot_Delay           = 20            'Delay for Plotting (You might need to increase this if there are setup problems)
 
Const AD420_Clock          = 15                              
Const AD420_Clear          = 14            'Optional - needed only in failsafe control                       
Const AD420_Fault          = 13            'Optional - needed only in failsafe control                            
Const AD420_Latch          = 12  
Const AD420_Data           = 11   
'
Const MSBFIRST_Mode_1      =  1            'Shiftout mode for AD420
 
 
 
'===================================================================================================================
'
'                                        [Constant Array Defines - Program Flash
'
'
'===================================================================================================================
' 
'                                             [Ladder Assignments For Pins]
' [Alias(s) for Ladder - Do not modify]
 
'Diagnostic Indicators from Timeslice
Alias M504 = Test_TC1 'TC0 M Output
Alias M505 = TC0      'TC0 Indication
 
Alias M506 = Test_TC0 'TC1 M Output
Alias M507 = TC1      'TC1 Indication
 
Alias M508 = Test_TC2 'TC2 M Output
Alias M509 = TC2      'TC2 Indication
 
Alias M510 = Test_Int 'Interrupt Indication 
Alias M511 = Int      'Int. M Output
 
 
'
'
'===================================================================================================================
'
'                                            [Start Ladder]
Set Ladder On      'Set Ladder On 
'
'===================================================================================================================
 
 
 
'===================================================================================================================
'===================================================================================================================
'===================================================================================================================
'
'                                           [Start Of Basic Code]
'
' Cycle RTOS Timeclass LED indicators on power-up
High TC0_LED  
High TC1_LED  
High TC2_LED
High PID1_Error_LED   
Pause 1000
Low  TC0_LED
Low  TC1_LED
Low  TC2_LED
Low PID1_Error_LED 
 
 
Gosub Timeslice_Init      ' Timeslice Init
 
Gosub PID1_Init           ' Init PID variables
 
Gosub Study_Board_Init    ' Init Study board 
 
Gosub Plot_Init           ' Initilize serial port #1 for plotting.
 
Gosub AD420_Init
 
'===================================================================================================================
'
'                                            [40 ms Interrupt using Timer]
'
On Timer(4) Gosub Tick_Interrupt  ' 4 x 10ms
 
'===================================================================================================================
 
Do  'Main Basic Loop
 
If Time_Class_2_Run = 1 Then
 Time_Class_2_Run = 0
'
' User Code - Runs in background every 100ms - can be changed.
'
'======================================[Time Class 2 User Code @100ms]=============================================
'==================================================================================================================
'==================================================================================================================
'Debug "Code Executing Time Class 2 at 100ms",cr
 
 
 
 
 
 
'================================================================================================================
'
'                               [Four channel PID plot --> Stamp Plot Pro ver 3.6]
'
 
If Bfree(1,1) > 30 Then     'Check Comm 1 buffer
 
Pause Plot_Delay
Plot_Value = Float Scale_Setpoint1
Putstr 1,"!ACHN 0,", Plot_Value
Putstr 1,","
Putstr 1,"(BLUE)",CR
 
Pause Plot_Delay
Plot_Value = Float Scale_Feedback1
Putstr 1,"!ACHN 1,", Plot_Value
Putstr 1,","
Putstr 1,"(GREEN)",CR
 
Pause Plot_Delay
Plot_Value = Float Error1 'Sumerror1
Putstr 1,"!ACHN 2,", Plot_Value
Putstr 1,","
Putstr 1,"(Black)",CR 
 
Pause Plot_Delay
Plot_Value = Float Fwd_Actuator1 'Data_AD420  
Putstr 1,"!ACHN 3,", Plot_Value
Putstr 1,","
Putstr 1,"(Red)",CR
Pause Plot_Delay
 
End If
 
 
'==================================================================================================================
'==================================================================================================================
'==================================================================================================================
Reverse TC2_LED
 _M(509) = 0 'TC2 Ladder Indicator	
' Debug " Time Class 2 - 500 ms",cr
 End If
 
Loop  ' Loop forever
'==================================================================================================================
'==================================================================================================================
'
'                                                    [End of Basic Code]
'
'==================================================================================================================
'==================================================================================================================
'
'                                [Interrupt Service Routine 40 ms @ 1520 Instructions]
'
Tick_Interrupt:
 
_M(511) = 1  'Interrupt started flag - for ladder
 
'============
'TIME CLASS 0
'============
Incr Time_Class_0_Counter 
 
If Time_Class_0_Counter >= Time_Class_0_Counter_Max Then  'This task executes every 20 ms
_M(505) = 1 'TC0 Ladder Indicator
Time_Class_0_Counter = 0
	If Time_Class_0_Enable = 1 Then
	' Do high freq task in 10 ms - do not adjust below 10ms.
    ' Insert User Code Here!
'
'=============================================[Time Class 0 User Code @ 40ms]====================================
'================================================================================================================
'================================================================================================================
'Debug "Code Executing Time Class 0 at 40ms",cr
 
'Gosub Get_Analogs-always get input analogs for PID before PID calculation!
 
Voltage_Feedback = Adin(2) 'has x 10 amp 
Voltage_Feedback = Voltage_Feedback * 0.048828125 
 
Gosub PID1         ' Calculate PID from PID Tuning constants and fixed input variables.
 
 
'=================================================================================================================
'=================================================================================================================	
'=================================================================================================================
	  Reverse TC0_LED
      _M(505) = 0 'TC0 Ladder Indicator
     'Debug " Time Class 0 - 10 ms",cr
	End If
End If
 
'============
'TIME CLASS 1
'============
Incr Time_Class_1_Counter 
 
If Time_Class_1_Counter >= Time_Class_1_Counter_Max Then  'This task executes every 100 ms
_M(507) = 1 'TC1 Ladder Indicator
Time_Class_1_Counter = 0
	If Time_Class_1_Enable = 1 Then 
	' Do medium freq task in 100 ms
	' Insert User Code Here!
'
'======================================[Time Class 1 User Code @80ms]===========================================
'================================================================================================================
'================================================================================================================	
'Debug "Code Executing Time Class 1 at 80ms",cr
 
 
'Debug Float voltage_feedback, " vf",cr
 
 
 
 
'================================================================================================================
'================================================================================================================	
'================================================================================================================
	 Reverse TC1_LED
	 _M(507) = 0 'TC1 Ladder Indicator
	'Debug " Time Class 1 - 100 ms",cr
	End If
End If
 
'============
'TIME CLASS 2
'============
Incr Time_Class_2_Counter 
 
If Time_Class_2_Counter >= Time_Class_2_Counter_Max Then  'This task executes every 100 ms
_M(509) = 1	'TC2 Ladder Indicator
Time_Class_2_Counter = 0
	If Time_Class_2_Enable = 1 Then
	' Do slow freq task in 500 ms - using code placed in the Main Do/Loop
	' Do not insert any code here!
	 Time_Class_2_Run = 1 'Enable Time Class 2 code in Main Do/Loop
	End If
End If
_M(511) = 0  'Interrupt finished flag- for ladder
 
Return 'End of interrupt
 
'=================================================================================================================
'
'                                       [Beginning Of Basic Subroutines]
'
'=================================================================================================================                          
'
Study_Board_Init:
'
Low TC0_LED 'high = LED on
Low TC1_LED
Low TC2_LED
Low PID1_Error_LED 
 
Input Voltage_Input
 
Return
'
'
'================================================[Timeslice Init]===================================================
Timeslice_Init:  'Init timeslice variables
 
Time_Class_0_Counter        = 0
Time_Class_1_Counter        = 0
Time_Class_2_Counter        = 0
 
Time_Class_0_Enable         = 1
Time_Class_1_Enable         = 1
Time_Class_2_Enable         = 1
 
Time_Class_2_Run            = 0
Return
'
'=================================================================================================================
'
'===============================================[PID Init]==========================================================
PID1_Init:
 
dError1                     = 0
Error1                      = 0
 
LastError1                  = 0                    
PrevError1                  = 0                                  
SumError1                   = 0
 
PID1_Deviation_Error        = 0
PID1_Error                  = 0
PID1_Control_Enable         = 1
 
Return
 
'================================================================================================================
'
PID1_Reset:
 
dError1                     = 0
Error1                      = 0
 
LastError1                  = 0                    
PrevError1                  = 0                                  
SumError1                   = 0
 
PID1_Deviation_Error        = 0
PID1_Error                  = 0
 
Return
'
'=================================================================================================================
'
'                                        [AD420 Initialization]
'
'=================================================================================================================
'
'
AD420_Init:
Low   AD420_Clock  'Keep low during DAC updates                            
Low   AD420_Clear  'Keep low for normal operation.                        
Input AD420_Fault  'Low = True = current loop broken or opened. (10 Kohm - Pulled high by hardware)                            
Low   AD420_Latch  'Keep low during serial loading
Low   AD420_Data   'SPI Data input.                        
Return
'
'================================================================================================================
'
'
'=================================================================================================================
'
'
Output_AD420_Data:
 
'16 bit precision DAC range (0 -65535)
Low       AD420_Clock 'Keep clock low
Low       AD420_Latch 'Keep latch low                                     
Shiftout  AD420_Clock, AD420_Data, MSBFIRST_Mode_1, Data_AD420, 16
Low       AD420_Clock 'Keep clock low
Pause 1
High      AD420_Latch 'Latch Data to AD420                                        
Pause 1
Low       AD420_Latch 'Bring latch low                             
Return
'
'================================================================================================================
 
'================================================================================================================
'
'                                              [PID1 Subroutine General Notes]
'
' The PID1 subroutine below has the following:
'
' #1. All inputs and outputs to / from the PID are scaled from 0-100 %.
' #2. The feedback from the sensor (in this case a fixed number 0-5VDC) is re-scaled to 0-100% for PID
' #3. The setpoint for the PID is rescaled to 0-100% for PID.
' #4. Both feedback and setpoint are "clamped" and "limited" (For safety protection)
' #5. All PID "tuning constants" are "clamped" or "limited" between 0-1 (For safety protection and operator malfunction)
' #6. The PID Output is "clamped" or "limited" between 0-100%
' #7. There is a control enable bit to enable the output control. In case of "downscale" or "upscale" sensor burnout
'     this enable/disable bit can prevent the PID output from controlling. (PID output equal to 0) There is no reason
'     to control on a bad sensor input!
'     Note: The logic is programmed in for this demo.
' #8. There is a PID error flag to indicate that the PID control loop is not tuned properly or just the failure
'     of the control loop to make the feedback match the setpoint.(external problems in control loop e.g. wiring, bad
'     actuators etc.) This "deviation setpoint error" is adjustable in constants. (Set at 3%)
' #9. The control output is from 0-100% for the forward actuator. If a heater was connected to this output, the
'     more control e.g. 25,50,75 - 100% will cause the heater control to produce more heat directly proportional to
'     the PID output signal. This is called "forward acting" control. Let's say that there was a device connected
'     at full control e.g. 100% that the temperature decreased. This control action is call "reverse acting control"
'     You have both options to choose from for the main actuator control output. ([0-5vdc or 5-0vdc using PWM] or 
'     [4-20ma or 20-4 ma using a milliamp DAC] or [0-10VDC or 10 VDC-0 using a voltage DAC]
'     Keep in mind that a control output failure due to a driver problem, open wire etc. SHOULD cause the actuator
'     to control less - not run wide open! e.g. Make it failsafe!
'#10. The code is modular. Replacing the suffix with a 2 instead of 1 will create another PID.
' 
' Note: It's very important in a scan based RTOS to First read the "analogs in" (setpoint & feedback), Second do the PID 
'       calculations and Third output the signal to the Pwm, Dac/4-20ma last.
'
'         
'=================================================================================================================
'
'                                              [PID1 Subroutine]
PID1:
Feedback1 =  Voltage_Feedback  '0 - 50 (0-5 VDC)   'PID1_LB_Test 
 
Scale_Feedback1 = ScaleX (Feedback1,0,50,0,100)    'Scale Feedback to range of 0-5VDC to PID range of 0 - 100%
Scale_Feedback1 = Limit_100(Scale_Feedback1)       'Limit Feedback between 0-100% 
 
Setpoint1 = 50 ' The setpoint of 50% = .50 of 5VDC = 2.5 VDC   Max range is 100%
 
Scale_Setpoint1 = ScaleX (Setpoint1,0,100,0,100)   'Scale Setpoint from range 0-100 to PID range of 0 - 100%
Scale_Setpoint1 = Limit_100(Scale_Setpoint1)       'Limit Setpoint between 0-100% 
 
Proportion1s = Proportion1                         'From constant table
Integral1s   = Integral1                           'From constant table
Derivative1s = Derivative1                         'From constant table 
 
Proportion1x = Limit_1(Proportion1s)               'Limit Proportion between 0 - 1 
Integral1x   = Limit_1(Integral1s)                 'Limit Integral   between 0 - 1 
Derivative1x = Limit_1(Derivative1s)               'Limit Deviation  between 0 - 1
 
 
'====================================================================================================================== 
PIDOutput1 = PIDCalc1(Proportion1x,Integral1x,Derivative1x,Scale_Setpoint1,Scale_Feedback1) 'Calculate PID - Top Secret
'======================================================================================================================
'
PID_Output_Raw1 = PIDOutput1
 
If Feedback1 >= 10000000000.0 Then         ' PID shutdown setpoint - Not used 
PID1_Control_Enable = 0   
High PID1_Error_LED
End If 
 
If PID1_Control_Enable = 1 Then
Fwd_Actuator1 = PIDOutput1                 ' Output to actuator
Fwd_Actuator1 = Limit_100(Fwd_Actuator1)   ' Clamp or Limit PID_Output between 0-100% - Forward Acting Control
 
 
'===============================================================================================================
'Integral anti-windup code 
'This occurs when the control output trys to correct and goes to maximum and stays there. The PID loop
'then keeps integrating the sumerror when the feedback is below the setpoint. (Winds-up)
 
If Fwd_Actuator1  = 0 Then Gosub PID1_Reset  'Prevents windup on the low end. (Please Keep)
'If PID1_Control_Output >= (65535) Then Gosub PID1_Reset 'Prevents windup on the top end. (optional) 
'Enabling the above statement will prevent any error indication during plotting. 
 
'================================================================================================================
 
 
 
 Rev_Actuator1 = (100 - Fwd_Actuator1)        ' Compute reverse acting control output - 100%-0%
Else
 Fwd_Actuator1 = 0                            ' Output zero to actuator when PID1_Control_Enable = 0 
 Fwd_Actuator1 = Limit_100(Fwd_Actuator1)     ' Clamp or Limit PID_Output between 0-100% - Forward Acting Control 
 Rev_Actuator1 = (100 - Fwd_Actuator1)        ' Compute reverse acting control output - 100%-0% 
End If
 
 
PID1_Deviation_Error = Abs(Scale_Setpoint1 - Scale_Feedback1)
 
If PID1_Deviation_Error >= PID1_Deviation_Error_Setpoint Then
PID1_Error = 1
High PID1_Error_LED 'PID deviation error - LED on 
Else
PID1_Error = 0
Low PID1_Error_LED  'No PID deviation error - LED off  
End If 
 
 
Data_AD420x = ScaleX (Fwd_Actuator1,0,100,0,65535) 
Data_AD420 = Data_AD420x
 
'Data_AD420 = 0  'Output test for AD420 (range 0 - 65535 = 0 - 5 VDC) 
 
Gosub Output_AD420_Data
 
'==========================================PID Internal Loopback Test======================================================= 
'PID1_LB_Test = ScaleX (Fwd_Actuator1,0,100,0,50) 'loopback test 
'===========================================================================================================================
 
 
 
Return 'End of PID1 Subroutine
 
 
'==========================================================================================================
'
'==========================================Stamp Plot Lite / Pro Init======================================
Plot_Init: 
 
Opencom 1,19200,3,64,64 ' Set comm 1 to 19,200, 8 N 1 - make sure StampPlot_Lite'Pro has the same settings. 
Bclr 1,1 ' xmit buf clr
Pause 1000
Return
'
'=================================================================================================================
'
 
'=================================================================================================================
'=================================================================================================================
End   'End of all programs
'=================================================================================================================
'=================================================================================================================
 
 
'=================================================================================================================
'
'                                                  [Functions]
'
'=================================================================================================================
'
'
'
'=============================[Top Secret --> PID1 Function <--Top Secret]========================================
 
 
Function PIDCalc1 (Proportion1 As Single,Integral1 As Single,Derivative1 As Single,Setpointx1 As Single,PIDFeedback1 As Single) As Single
 
' All variables are zero'd on program init
' 
Error1     = Setpointx1 - PIDFeedback1
SumError1  = SumError1 + Error1
dError1    = LastError1 - PrevError1
PrevError1 = LastError1
LastError1 = Error1
 
PIDCalc1 = (Proportion1 * Error1) + (Integral1 * SumError1) + (Derivative1 * dError1)
 
End Function
'
'================================================================================================================
 
 
'===============================================================================================================
 
Function Limit_100(Value_100 As Single) As Single
'Rev. 1.0b
'Keeps the variable between 0 - 100 %
 
Dim Limit_Low_x  As Single
Dim Limit_High_x As Single
 
Limit_Low_x = 0
Limit_High_x = 100
 
If Value_100 <  Limit_Low_x  Then 
Limit_100 = Limit_Low_x
Exit Function
End If
 
If Value_100 >  Limit_High_x Then
Limit_100 = Limit_High_x
Exit Function
End If
 
If Value_100 <= Limit_High_x Or Value_100 >= Limit_Low_x Then
Limit_100 = Value_100
Exit Function
End If
End Function
'
'===============================================================================================================
'
'===============================================================================================================
 
Function Limit_1(Value_1 As Single) As Single
'Rev. 1.0b
'Keeps the variable between 0 - 100 %
 
Dim Limit_Low_x  As Single
Dim Limit_High_x As Single
 
Limit_Low_x = 0
Limit_High_x = 1
 
If Value_1 <  Limit_Low_x  Then 
Limit_1 = Limit_Low_x
Exit Function
End If
 
If Value_1 >  Limit_High_x Then
Limit_1 = Limit_High_x
Exit Function
End If
 
If Value_1 <= Limit_High_x Or Value_1 >= Limit_Low_x Then
Limit_1 = Value_1
Exit Function
End If
End Function
'
'===============================================================================================================
 
 
 
'===============================================================================================================
'
Function ScaleX (ScaleY As Single,Ylow As Single,Yhigh As Single,Xlow As Single, Xhigh As Single) As Single
'Rev. 1.0b
'y = mx + b - basic linear formula - the change in x will be proportional to the change in y
'x  = (Y-Yl)/(Yh-Yl)*(Xh-Xl)+Xl
'This formula works better than a ratio or proportion equation. It can even compute on negative range values. 
 
'ScaleY  = y units Input parameter value
'    yl  = y units Low value
'    yh  = y units High value
'ScaleX  = x units Value to solve for 
'    xl  = x units Low value
'    xh  = x units High value
'
'Example: x = ScaleY (5,0,10,50,100)
'         x = 75 
ScaleX = (ScaleY-Ylow)/(Yhigh-Ylow)*(Xhigh-Xlow)+Xlow
End Function
'
'==============================================================================================================
 
'
'==============================================================================================================
'
'End of functions
'
'==============================================================================================================

좀더 심플하게 만든 PID예제 프로그램

Const Device = CB280
 
LastError1  Var     Single    'Error[-1]
PrevError1  Var     Single    'Error[-2]
SumError1   Var     Single    'SumError + Error (Sum of Errors)
dError1     Var     Single    'LastError - PrevError
Error1      Var     Single    'Error = Setpoint - PID Feedback
 
Dim adv As Integer	
Dim advf As Single	
Dim pidv As Single
 
Ramclear
 
Do
	adv = Adin(0)
	advf = adv
	pidv = PIDcalc1(0.01, 0.1, 0.0, 1000.0, advf)	
	Debug "Ad : ",Dec adv
	Debug " ----  PID cal : " , Float pidv,Cr
	Wait 100
Loop
 
 
 
End
 
Function PIDCalc1 (Proportion1 As Single,Integral1 As Single,Derivative1 As Single,Setpointx1 As Single,PIDFeedback1 As Single) As Single
 
' All variables are zero'd on program init.
' 
Error1     = Setpointx1 - PIDFeedback1
SumError1  = SumError1 + Error1
dError1    = LastError1 - PrevError1
PrevError1 = LastError1
LastError1 = Error1
 
PIDCalc1 = (Proportion1 * Error1) + (Integral1 * SumError1) + (Derivative1 * dError1)
 
End Function

큐블록 어플리케이션 노트

cublocapp/an32009/index.txt · 마지막으로 수정됨: 2017/10/24 12:48 저자 Comfile Technology