Stylesheet ../dokuwiki/css/_search.css not found, using ../dokuwiki/css/_search.less instead. Please contact developer of "altronic" template.
Stylesheet ../dokuwiki/css/_admin.css not found, using ../dokuwiki/css/_admin.less instead. Please contact developer of "altronic" template.
Differences
This shows you the differences between two versions of the page.
| Both sides previous revision Previous revision Next revision | Previous revision | ||
|
documents:de4000:de4000script [2022/01/24 16:25] rocky [3. ] |
documents:de4000:de4000script [2022/07/08 13:11] (current) rjackson |
||
|---|---|---|---|
| Line 1: | Line 1: | ||
| - | Scripting Reference Manual | + | =====DE-4000 |
| - | DE-4000 | + | |
| - | Form DE-4000 SRM 06-20 | + | |
| + | There is a delicate balance between providing a system that has capabilities that can be configured through a fixed set of options, and one that can be extended and expanded with custom programming. In designing the DE-4000 control system, the choice was made to provide a system where most applications can be met with simple configuration, | ||
| - | DE-4000 SCRIPTING REFERENCE MANUAL | + | Lua is often referred to as a scripting language. |
| - | + | ||
| - | One overarching capability that allows | + | |
| - | systems and the customer needs of innovation is scripting. A scripting language, | + | |
| - | cleverly named Lua, is embedded into the DE-4000 system. It operates | + | |
| - | mainly meaning that it does not need additional tools to convert | + | |
| - | machine | + | |
| - | runs. Therefore it is an “interpreted” language and runs all of the time when you ask it. | + | |
| Lua comes with a background of being robust, fast, and geared towards embedded | Lua comes with a background of being robust, fast, and geared towards embedded | ||
| applications, | applications, | ||
| Line 52: | Line 45: | ||
| - | ===== - ===== | + | ===== - Select one of the page icons under one of the 4 script options to open editor |
| - | Select one of the page icons under one of the 4 script options to open editor | + | {{: |
| - | ===== - ===== | + | ===== - Scripting can be entered into the editor |
| - | Scripting can be entered into the editor. | + | {{: |
| - | <markdown>### DE4000 | + | |
| + | **Scripting Windows and examples** | ||
| + | |||
| + | **Master Script** | ||
| + | {{: | ||
| + | Primary scripting functions can be written in this section. | ||
| + | |||
| + | **Example: | ||
| + | <code lua> | ||
| + | local suction = get_channel_val(1, | ||
| + | local discharge1 = get_channel_val(1, | ||
| + | diff = discharge1 - suction | ||
| + | set_sVirt(“Difference”, | ||
| + | </ | ||
| + | |||
| + | The first line gets the channel value from Terminal board 1 Input 1 and stores it | ||
| + | in local variable named suction. | ||
| + | The second line gets the channel value from Terminal board 1 Input 3 and stores | ||
| + | it in local variable named discharge1. | ||
| + | The third line takes the discharge1 pressure and subtracts the suction pressure | ||
| + | and stores it in the global variable named diff (NOTE: Any value that you want to | ||
| + | access from another scripting section must be stored in a global variable. This is | ||
| + | used most in calling values into Modbus registers as explained below). | ||
| + | The fourth line copies the value from diff and stores it into the Virtual status | ||
| + | channel named “Difference” This channel can be displayed on the Dashboard. | ||
| + | |||
| + | **Control Script** | ||
| + | {{: | ||
| + | The Control Script section is used to override the default control | ||
| + | strategy found on the Global/ | ||
| + | control script (found in attached appendix) can be copied into this | ||
| + | section and then modified to change the control functionality as well | ||
| + | as add additional control loops beyond the default 2. | ||
| + | |||
| + | {{: | ||
| + | |||
| + | **Modbus Script** | ||
| + | {{: | ||
| + | The Modbus Script section is used to move data into and out of | ||
| + | Modbus registers | ||
| + | |||
| + | {{: | ||
| + | |||
| + | <code lua> | ||
| + | defaultModbus() | ||
| + | set_modbus(300, | ||
| + | </ | ||
| + | |||
| + | The first line pulls in the factory set Modbus mapping | ||
| + | The second line moves the value from the global variable named diff into the | ||
| + | 40300 Modbus Register | ||
| + | |||
| + | ==== - DE-4000 | ||
| + | < | ||
| + | **CUSTOM FUNCTIONS FOR SCRIPTING** | ||
| --- | --- | ||
| Line 308: | Line 355: | ||
| </ | </ | ||
| + | ==== - Master Control Script ==== | ||
| + | |||
| + | {{ : | ||
| + | |||
| + | When you enter a control setup under the Global Control page the code that runs is called MasterControl. | ||
| + | |||
| + | If you wish to modify this functionality you can copy this code into the Control Script editor and{{ : | ||
| + | |||
| + | |||
| + | <file lua [enable_line_numbers=" | ||
| + | local rampRate1 = get_gbl(" | ||
| + | local rampRate2 = get_gbl(" | ||
| + | local dischTerm = tonumber_def(get_gbl(" | ||
| + | local dischChan = tonumber_def(get_gbl(" | ||
| + | local suctTerm = tonumber_def(get_gbl(" | ||
| + | local suctChan = tonumber_def(get_gbl(" | ||
| + | local suctMin = tonumber_def(get_gbl(" | ||
| + | local recycleMin = tonumber_def(get_gbl(" | ||
| + | local recycleMax = tonumber_def(get_gbl(" | ||
| + | local suctSp = tonumber_def(get_gbl(" | ||
| + | local dischMax = tonumber_def(get_gbl(" | ||
| + | local dischSp = tonumber_def(get_gbl(" | ||
| + | local outputTerm = tonumber_def(get_gbl(" | ||
| + | local outputChan = tonumber_def(get_gbl(" | ||
| + | local recycleTerm = tonumber_def(get_gbl(" | ||
| + | local recycleChan = tonumber_def(get_gbl(" | ||
| + | local speedRevAct = tonumber_def(get_gbl(" | ||
| + | local recycleRevAct = tonumber_def(get_gbl(" | ||
| + | local outputLow = tonumber_def(get_gbl(" | ||
| + | local outputLow2 = tonumber_def(get_gbl(" | ||
| + | local outputHigh = tonumber_def(get_gbl(" | ||
| + | local outputHigh2 = tonumber_def(get_gbl(" | ||
| + | local spSuctType = get_gbl(" | ||
| + | local spDischType = get_gbl(" | ||
| + | local suctPIDPFactor = tonumber_def(get_gbl(" | ||
| + | local suctPIDIFactor = tonumber_def(get_gbl(" | ||
| + | local suctPIDDFactor = tonumber_def(get_gbl(" | ||
| + | local dischPIDPFactor = tonumber_def(get_gbl(" | ||
| + | local dischPIDIFactor = tonumber_def(get_gbl(" | ||
| + | local dischPIDDFactor = tonumber_def(get_gbl(" | ||
| + | local recycleCtrl = false | ||
| + | local recycleSuctionRev = false | ||
| + | local recycleDischargeRev = false | ||
| + | if recycleChan > 0 and recycleTerm > 0 then | ||
| + | recycleCtrl = true | ||
| + | end | ||
| + | |||
| + | local dischPct = 100 | ||
| + | local suctPct = 100 | ||
| + | |||
| + | |||
| + | local dischOutput = 0 | ||
| + | local suctOutput = 0 | ||
| + | local rSuctOutput = 0 | ||
| + | local rDischOutput = 0 | ||
| + | local minLoad = 0 | ||
| + | local maxLoad = 100 | ||
| + | local minRecycle = 0 | ||
| + | local maxRecycle = 100 | ||
| + | local speedTarget = get_sGbl(" | ||
| + | local recycleTarget = get_sGbl(" | ||
| + | |||
| + | function map_range(rangeLow, | ||
| + | if input <= rangeLow and input <= rangeHigh then | ||
| + | return 0 | ||
| + | end | ||
| + | if input >= rangeLow and input >= rangeHigh then | ||
| + | return 100 | ||
| + | end | ||
| + | local rangeDiff = math.abs(rangeLow - rangeHigh) | ||
| + | local min = math.min(rangeLow, | ||
| + | local retval = math.abs(input - min) / rangeDiff * 100 | ||
| + | if retval > 100 then retval = 100 end | ||
| + | if retval < 0 then retval = 0 end | ||
| + | return retval | ||
| + | end | ||
| + | |||
| + | local suct = false | ||
| + | local suctVal = 0 | ||
| + | if tonumber_def(get_gbl(" | ||
| + | if suctTerm > 0 and suctChan > 0 then | ||
| + | suctVal = get_channel_val(suctTerm, | ||
| + | suct = true | ||
| + | end | ||
| + | end | ||
| + | |||
| + | |||
| + | if suct then | ||
| + | if spSuctType == " | ||
| + | local suctDiff = suctSp - suctMin | ||
| + | if suctDiff == 0 then suctDiff = 1 end | ||
| + | if suctVal < suctSp then | ||
| + | local suctErr = suctSp - suctVal | ||
| + | suctPct = suctErr / suctDiff | ||
| + | if suctPct > 1 then suctPct = 1 end | ||
| + | if suctPct < 0 then suctPct = 0 end | ||
| + | suctOutput = (1 - suctPct) * 100 | ||
| + | else | ||
| + | suctOutput = 100 | ||
| + | end | ||
| + | else | ||
| + | set_gbl(" | ||
| + | set_gbl(" | ||
| + | set_gbl(" | ||
| + | set_gbl(" | ||
| + | set_gbl(" | ||
| + | set_gbl(" | ||
| + | local suctPidOutput = doPid(" | ||
| + | suctOutput = suctPidOutput | ||
| + | end | ||
| + | else | ||
| + | suctOutput = 100 | ||
| + | end | ||
| + | |||
| + | |||
| + | local disch = false | ||
| + | local dischVal = 0 | ||
| + | if tonumber_def(get_gbl(" | ||
| + | if dischTerm > 0 and dischChan > 0 then | ||
| + | dischVal = get_channel_val(dischTerm, | ||
| + | disch = true | ||
| + | end | ||
| + | end | ||
| + | if disch then | ||
| + | if spDischType == " | ||
| + | local dischDiff = dischMax - dischSp | ||
| + | if dischDiff == 0 then dischDiff = 1 end | ||
| + | if dischVal > dischSp then | ||
| + | local dischErr = dischVal - dischSp | ||
| + | dischPct = dischErr / dischDiff | ||
| + | if dischPct > 1 then dischPct = 1 end | ||
| + | if dischPct < 0 then dischPct = 0 end | ||
| + | dischOutput = (1 - dischPct) * 100 | ||
| + | else | ||
| + | dischOutput = 100 | ||
| + | end | ||
| + | else | ||
| + | set_gbl(" | ||
| + | set_gbl(" | ||
| + | set_gbl(" | ||
| + | set_gbl(" | ||
| + | set_gbl(" | ||
| + | set_gbl(" | ||
| + | set_gbl(" | ||
| + | local dischPidOutput = doPid(" | ||
| + | dischOutput = dischPidOutput | ||
| + | end | ||
| + | else | ||
| + | dischOutput = 100 | ||
| + | end | ||
| + | |||
| + | | ||
| + | local minOutput = 100 | ||
| + | local winning = 0 | ||
| + | if suctOutput < minOutput then | ||
| + | minOutput = suctOutput | ||
| + | winning = 1 | ||
| + | end | ||
| + | if dischOutput < minOutput then | ||
| + | minOutput = dischOutput | ||
| + | winning = 2 | ||
| + | end | ||
| + | |||
| + | if suctOutput == dischOutput then | ||
| + | winning = 0 | ||
| + | end | ||
| + | |||
| + | if winning == 0 then | ||
| + | set_gbl(" | ||
| + | set_gbl(" | ||
| + | end | ||
| + | |||
| + | if winning == 1 then | ||
| + | set_gbl(" | ||
| + | set_gbl(" | ||
| + | set_gbl(" | ||
| + | set_gbl(" | ||
| + | set_gbl(" | ||
| + | end | ||
| + | if winning == 2 then | ||
| + | set_gbl(" | ||
| + | set_gbl(" | ||
| + | set_gbl(" | ||
| + | set_gbl(" | ||
| + | set_gbl(" | ||
| + | end | ||
| + | |||
| + | local recycleMinOutput = minOutput | ||
| + | |||
| + | local manOutput = 0 | ||
| + | --******************************************************************** | ||
| + | local manMode = 0 | ||
| + | local manTerm = tonumber_def(get_gbl(" | ||
| + | local manChan = tonumber_def(get_gbl(" | ||
| + | if manTerm > 0 and manChan > 0 then | ||
| + | local manInput = get_channel_val(manTerm, | ||
| + | if manInput > 0.5 then | ||
| + | manMode = 0 | ||
| + | set_sVirt(" | ||
| + | else | ||
| + | manMode = 1 | ||
| + | set_sVirt(" | ||
| + | end | ||
| + | else | ||
| + | if get_sVirt(" | ||
| + | manMode = 0 | ||
| + | else | ||
| + | manMode = 1 | ||
| + | end | ||
| + | end | ||
| + | |||
| + | --if manMode == 1 and get_state() == 8 then | ||
| + | local manSpeed = get_sVirt(" | ||
| + | local idleSpeed = get_gbl(" | ||
| + | local lowSpeed = get_gbl(" | ||
| + | local highSpeed = get_gbl(" | ||
| + | local maxSpeed = get_gbl(" | ||
| + | local diff = highSpeed - lowSpeed | ||
| + | if diff < 0 then diff = 0 end | ||
| + | local maxDiff = maxSpeed - idleSpeed | ||
| + | if maxDiff < 0 then maxDiff = 0 end | ||
| + | |||
| + | if get_sVirt(" | ||
| + | local si = get_gbl(" | ||
| + | local sip = get_param(" | ||
| + | if sip ~= 0 then si = sip end | ||
| + | manSpeed = manSpeed + (si * get_sVirt(" | ||
| + | set_sVirt(" | ||
| + | end | ||
| + | |||
| + | if get_sVirt(" | ||
| + | set_sVirt(" | ||
| + | set_sVirt(" | ||
| + | end | ||
| + | |||
| + | if get_sVirt(" | ||
| + | set_sVirt(" | ||
| + | set_sVirt(" | ||
| + | end | ||
| + | |||
| + | if manMode == 1 then | ||
| + | local manSpeedTerm = tonumber_def(get_gbl(" | ||
| + | local manSpeedChan = tonumber_def(get_gbl(" | ||
| + | if manSpeedTerm > 0 and manSpeedChan > 0 then --*** USE SPEED POT TO SET SPEED | ||
| + | local speedInput = tonumber(get_channel_val(manSpeedTerm, | ||
| + | local speedPct = (speedInput / 5) * 100 | ||
| + | if speedPct > 100 then speedPct = 100 end | ||
| + | if speedPct < 0 then speedPct = 0 end | ||
| + | manOutput = speedPct | ||
| + | manSpeed = math.floor((speedPct / 100) * diff + lowSpeed + 0.5) | ||
| + | else -- Use ManualSpeed to set speed | ||
| + | manOutput = ((manSpeed - lowSpeed) / diff) * 100.0 | ||
| + | if manOutput < 0 then manOutput = 0 end | ||
| + | if manOutput > 100 then manOutput = 100 end | ||
| + | end | ||
| + | minOutput = manOutput | ||
| + | else | ||
| + | --speedTarget = | ||
| + | local stRpm = (speedTarget/ | ||
| + | if stRpm < lowSpeed then stRpm = lowSpeed end | ||
| + | if stRpm > highSpeed then stRpm = highSpeed end | ||
| + | manSpeed = math.floor(stRpm) | ||
| + | end | ||
| + | |||
| + | if manSpeed < lowSpeed then | ||
| + | manSpeed = lowSpeed | ||
| + | end | ||
| + | if manSpeed > highSpeed then | ||
| + | manSpeed = highSpeed | ||
| + | end | ||
| + | |||
| + | set_sVirt(" | ||
| + | |||
| + | |||
| + | |||
| + | --******************************************************************** | ||
| + | |||
| + | |||
| + | local output1 = 0 | ||
| + | local output2 = 0 | ||
| + | if spSuctType == " | ||
| + | output1 = map_range(outputLow, | ||
| + | set_sVirt(" | ||
| + | output2 = map_range(outputLow2, | ||
| + | set_sVirt(" | ||
| + | local hasRPM = idleSpeed > 0 and lowSpeed > 0 and highSpeed > 0 and maxSpeed > 0 | ||
| + | if outputTerm and outputChan then | ||
| + | if hasRPM then | ||
| + | local speedRpm = output1 / 100 * (highSpeed - lowSpeed) + lowSpeed | ||
| + | speedTarget = (speedRpm - idleSpeed) / (maxSpeed - idleSpeed) * 100 | ||
| + | else | ||
| + | speedTarget = output1 | ||
| + | end | ||
| + | end | ||
| + | if recycleTerm and recycleChan then | ||
| + | set_ao_val(recycleTerm, | ||
| + | end | ||
| + | |||
| + | if get_state() == 9 then | ||
| + | speedTarget = get_sGbl(" | ||
| + | if speedTarget > 0 then speedTarget = speedTarget - rampRate1 end | ||
| + | if speedTarget < 0 then speedTarget = 0 end | ||
| + | end | ||
| + | if get_state() < 8 then speedTarget = 0 end | ||
| + | set_sGbl(" | ||
| + | set_ao_val(outputTerm, | ||
| + | set_sVirt(" | ||
| + | |||
| + | if hasRPM then | ||
| + | local sRpm = (speedTarget/ | ||
| + | set_sVirt(" | ||
| + | end | ||
| + | |||
| + | |||
| + | |||
| + | else | ||
| + | |||
| + | -- Remember that minOutput is 0 - 100 pct of lowSpeed <-> highSpeed | ||
| + | -- We need to convert this to 0 - 100 pct of idleSpeed <-> maxSpeed | ||
| + | local suctPct = map_range(outputLow, | ||
| + | local speedRpm = suctPct / 100 * (highSpeed - lowSpeed) + lowSpeed | ||
| + | minOutput = (speedRpm - idleSpeed) / (maxSpeed - idleSpeed) * 100 | ||
| + | |||
| + | |||
| + | |||
| + | if minOutput <= speedTarget then | ||
| + | speedTarget = speedTarget - rampRate1 | ||
| + | if speedTarget < minOutput then speedTarget = minOutput end | ||
| + | else | ||
| + | speedTarget = speedTarget + rampRate1 | ||
| + | if speedTarget > minOutput then speedTarget = minOutput end | ||
| + | if speedTarget > maxLoad then speedTarget = maxLoad end | ||
| + | end | ||
| + | if speedTarget > maxLoad then speedTarget = maxLoad end | ||
| + | if speedTarget < minLoad then speedTarget = minLoad end | ||
| + | |||
| + | if recycleCtrl then | ||
| + | local recyclePct = map_range(outputLow2, | ||
| + | if recyclePct <= recycleTarget then | ||
| + | recycleTarget = recycleTarget - rampRate2 | ||
| + | if recycleTarget < recyclePct then recycleTarget = recyclePct end | ||
| + | else | ||
| + | recycleTarget = recycleTarget + rampRate2 | ||
| + | if recycleTarget > recyclePct then recycleTarget = recyclePct end | ||
| + | end | ||
| + | if recycleTarget > maxRecycle then recycleTarget = maxRecycle end | ||
| + | if recycleTarget < minRecycle then recycleTarget = minRecycle end | ||
| + | local recycleOutput = recycleTarget | ||
| + | if get_state() < 8 then | ||
| + | recycleTarget = 0 | ||
| + | end | ||
| + | if recycleRevAct == 1 then | ||
| + | recycleOutput = 100 - recycleOutput | ||
| + | end | ||
| + | set_ao_val(recycleTerm, | ||
| + | set_sGbl(" | ||
| + | set_sVirt(" | ||
| + | end | ||
| + | |||
| + | if get_state() == 9 then | ||
| + | speedTarget = get_sGbl(" | ||
| + | if speedTarget > 0 then speedTarget = speedTarget - rampRate1 end | ||
| + | if speedTarget < 0 then speedTarget = 0 end | ||
| + | end | ||
| + | if get_state() < 8 then speedTarget = 0 end | ||
| + | set_sGbl(" | ||
| + | set_ao_val(outputTerm, | ||
| + | set_sVirt(" | ||
| + | local sRpm = (speedTarget/ | ||
| + | set_sVirt(" | ||
| + | |||
| + | |||
| + | end | ||
| + | |||
| + | </ | ||