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 [2021/12/23 12:24] admin |
documents:de4000:de4000script [2022/01/25 16:22] (current) twebster |
||
---|---|---|---|
Line 1: | Line 1: | ||
- | <html> | + | =====DE-4000 SCRIPTING REFERENCE MANUAL===== |
- | <body> | + | |
- | This is html | + | 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, |
- | </body> | + | |
- | </html> | + | Lua is often referred to as a scripting language. Scripting languages differ from compiled languages as they eliminate extra step of compiling the written program into machine code. |
+ | |||
+ | Lua comes with a background of being robust, fast, and geared towards embedded | ||
+ | applications, | ||
+ | system it is small and fits in the memory we have available, holds a lot of power, and | ||
+ | keeps it simple for writing in the language. | ||
+ | All information regarding the Lua scripting language is located at https:// | ||
+ | Using the Lua engine as an embedded tool allows for taking advantage of a full | ||
+ | architecture and standard at your fingertips. Within the language there are all of | ||
+ | the normal attributes to programming such as functions, variables, statements, | ||
+ | expressions etc. All of this reference material can be found at https:// | ||
+ | manual/ | ||
+ | For getting started and using a guided reference, there are several editions of | ||
+ | “Programming in Lua” available. Most recent editions are a paid for product that | ||
+ | come in paper back or ebook form. While testing out Lua and becoming familiar, a | ||
+ | free first edition is available and covers a lot of learning needs to get comfortable with | ||
+ | the language. It can be located at https:// | ||
+ | A major advantage to using Lua is its inherent ability to allow custom functions. While | ||
+ | all normal functions and calls are published, there is the ability to add new functions | ||
+ | in the DE-4000 firmware. Once new functions are defined and have calls to their | ||
+ | internal properties, they then can be published for the user. This includes functions | ||
+ | such as our flexible Modbus table and talking with various terminal boards linked in | ||
+ | the system. Below is the start to the list of Altronic based functions. As functionality | ||
+ | and features come to life through new ideas, this document will continually get | ||
+ | updated with the latest scripts that we make available. | ||
+ | |||
+ | |||
+ | GETTING STARTED WITH DE-4000 SCRIPTS | ||
+ | Basic Scripting on DE-4000 | ||
+ | |||
+ | ===== - Begin on Dashboard on DE-4000 system environment ===== | ||
+ | {{: | ||
+ | |||
+ | |||
+ | ===== - Choose “Global” from menu on left side of screen ===== | ||
+ | {{: | ||
+ | |||
+ | |||
+ | ===== - In the Sub-Menu on the Left side select “Scripts” ===== | ||
+ | {{: | ||
+ | |||
+ | |||
+ | ===== - Select one of the page icons under one of the 4 script options to open editor ===== | ||
+ | {{: | ||
+ | |||
+ | ===== - Scripting can be entered into the editor ===== | ||
+ | {{: | ||
+ | |||
+ | |||
+ | **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”, | ||
+ | </code> | ||
+ | |||
+ | 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. | ||
+ | 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, | ||
+ | </code> | ||
+ | |||
+ | 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 | ||
+ | |||
+ | ==== - DE4000 Lua Script API ==== | ||
+ | <markdown> | ||
+ | **CUSTOM FUNCTIONS FOR SCRIPTING** | ||
+ | |||
+ | --- | ||
+ | ##### create_param(" | ||
+ | * creates a user configurable parameter | ||
+ | * parameter is stored as `index`, | ||
+ | * default value(If not changed by user) is `default` | ||
+ | * parameters will be grouped on the Global/Params page by `category` | ||
+ | * `description` is text to describe the parameter to the user | ||
+ | |||
+ | **Example: | ||
+ | ```lua | ||
+ | create_param(" | ||
+ | ``` | ||
+ | --- | ||
+ | ##### get_channel_val(terminal, | ||
+ | * returns current value of analog input `channel` on terminal module `terminal` | ||
+ | * return value type is numeric | ||
+ | |||
+ | **Example: | ||
+ | ```lua | ||
+ | local sp = get_channel_val(1, | ||
+ | ``` | ||
+ | |||
+ | > reads value of Suction Pressure | ||
+ | |||
+ | --- | ||
+ | |||
+ | ##### get_gbl(" | ||
+ | * returns global config setting stored under `index` or returns `default` if not defined | ||
+ | > **note:** get_gbl is used to retrieve global CONFIGURATION settings that are typically set when the system is configured and do not change as the system is running. | ||
+ | > If you want to set and retrieve global STATUS variables use the get_sGbl() and set_sGbl() functions | ||
+ | >If you want to create and read virtual channels use the set_sVirt() and get_sVirt() functions. | ||
+ | |||
+ | **Example: | ||
+ | ```lua | ||
+ | local nt = get_gbl(" | ||
+ | ``` | ||
+ | |||
+ | > gets the number of terminal boards installed in the system | ||
+ | |||
+ | --- | ||
+ | |||
+ | ##### get_param(" | ||
+ | * return either the default value or the user configured value of the parameter `index` | ||
+ | |||
+ | **Example: | ||
+ | |||
+ | ```lua | ||
+ | get_param(" | ||
+ | ``` | ||
+ | |||
+ | >gets the configured parameter for number of engine cylinders | ||
+ | |||
+ | --- | ||
+ | |||
+ | ##### get_rpm(channel) | ||
+ | * reads the RPM input `channel` in units of revolutions per minute | ||
+ | |||
+ | > **note:** valid channel numbers are 1 - 10(2 channels per board, up to 5 terminal boards) | ||
+ | |||
+ | Each Terminal Module has 2 RPM inputs (RPM1 and RPM2) | ||
+ | * Terminal Module **#1** RPM channels are **1,2** | ||
+ | * Terminal Module **#2** RPM channels are **3,4** | ||
+ | * Terminal Module **#3** RPM channels are **5,6** | ||
+ | * Terminal Module **#4** RPM channels are **7,8** | ||
+ | * Terminal Module **#5** RPM channels are **9,10** | ||
+ | |||
+ | **Example: | ||
+ | |||
+ | ```lua | ||
+ | local engineRPM = get_rpm(1) | ||
+ | local turboRPM = get_rpm(6) | ||
+ | ``` | ||
+ | |||
+ | > Read RPM1 channel from terminal module #1 and read RPM2 channel from Terminal module #3 | ||
+ | |||
+ | --- | ||
+ | |||
+ | |||
+ | ##### get_sGbl(" | ||
+ | |||
+ | * If `index` is defined in the global status table then it returns the value associated with `index` | ||
+ | * If `index` is not defined and optional `default` is provided then returns `default` | ||
+ | |||
+ | > | ||
+ | |||
+ | **Example: | ||
+ | ```lua | ||
+ | local cp = get_sGbl(" | ||
+ | ``` | ||
+ | |||
+ | > get the previously stored value " | ||
+ | |||
+ | --- | ||
+ | |||
+ | ##### get_state() | ||
+ | |||
+ | * returns the current engine state(possible values currently 0 - 10) | ||
+ | |||
+ | **Example: | ||
+ | ```lua | ||
+ | local engineState = get_state() | ||
+ | if engineState > 7 then | ||
+ | set_timer(" | ||
+ | end | ||
+ | ``` | ||
+ | |||
+ | --- | ||
+ | |||
+ | ##### get_sVirt(" | ||
+ | |||
+ | * returns the value of virtual channel `index` or returns `default` if the virtual channel does not exist. | ||
+ | |||
+ | **Example: | ||
+ | |||
+ | ```lua | ||
+ | local tl = get_sGbl(" | ||
+ | local et = get_sVirt(" | ||
+ | if et > tl then | ||
+ | set_sGbl(" | ||
+ | else | ||
+ | set_sGbl(" | ||
+ | end | ||
+ | ``` | ||
+ | |||
+ | >Gets the value of virtual channel ElapsedTime and set value of status global " | ||
+ | |||
+ | --- | ||
+ | |||
+ | ##### get_time() | ||
+ | |||
+ | * returns the UNIX " | ||
+ | |||
+ | **Example: | ||
+ | |||
+ | ```lua | ||
+ | local startTime = get_sGbl(" | ||
+ | if startTime == 0 then | ||
+ | local currentTime = get_time() | ||
+ | startTime = currentTime | ||
+ | set_sGbl(" | ||
+ | end | ||
+ | local et = get_time() - startTime | ||
+ | set_sVirt(" | ||
+ | ``` | ||
+ | |||
+ | >Stores current time if first time through, otherwise calculate elapsed time | ||
+ | |||
+ | --- | ||
+ | |||
+ | ##### get_timer(" | ||
+ | |||
+ | * returns 1 or 2 values | ||
+ | * First return value(Boolean) is **true** if timer is active(counting down) or **false** if timer is expired or has not been set yet | ||
+ | * Second return value is the number of seconds remaining or **-1** if timer is not active or has not been set yet | ||
+ | |||
+ | **Example: | ||
+ | |||
+ | ```lua | ||
+ | if not get_timer(" | ||
+ | set_sGbl(" | ||
+ | else | ||
+ | set_sGbl(" | ||
+ | end | ||
+ | ``` | ||
+ | |||
+ | > if timer is expired, then set global status " | ||
+ | |||
+ | ```lue | ||
+ | local active, | ||
+ | if not active then | ||
+ | set_sVirt(" | ||
+ | else | ||
+ | set_sVirt(" | ||
+ | end | ||
+ | ``` | ||
+ | |||
+ | --- | ||
+ | |||
+ | ##### getStateLabel(state) | ||
+ | |||
+ | * return the label for the engine state corresponding to the parameter `state` | ||
+ | |||
+ | **Example: | ||
+ | |||
+ | ```lua | ||
+ | local stateLabel = getStateLabel(get_state()) | ||
+ | local active, remaining = get_timer(" | ||
+ | if remaining > 0 then | ||
+ | stateLabel == StateLabel.." | ||
+ | end | ||
+ | set_sVirt(" | ||
+ | ``` | ||
+ | |||
+ | --- | ||
+ | ##### set_sGbl(" | ||
+ | |||
+ | * store `value` in the global status table under `index` | ||
+ | * value can be a number or string but if storing a boolean use the **tostring()** function | ||
+ | |||
+ | **Example: | ||
+ | |||
+ | ```lua | ||
+ | local mpe = false | ||
+ | local sp = get_channel_val(1, | ||
+ | if sp > 15 then | ||
+ | mpe = true | ||
+ | end | ||
+ | set_sGbl(" | ||
+ | ``` | ||
+ | |||
+ | > store boolean value **minPressureExceeded** | ||
+ | |||
+ | --- | ||
+ | |||
+ | ##### set_sVirt(" | ||
+ | |||
+ | * sets a virtual status channel with channel name `index` | ||
+ | > **Note:** Once you create a virtual channel, you can add that channel to the dashboard using the channel name `index` | ||
+ | |||
+ | **Example: | ||
+ | |||
+ | ```lua | ||
+ | local sp = get_channel_val(1, | ||
+ | local dp = get_channel_val(1, | ||
+ | local diffPress = dp - sp | ||
+ | set_sVirt(" | ||
+ | ``` | ||
+ | |||
+ | > calculate the differential between suction and discharge pressure and assign to virtual channel | ||
+ | |||
+ | --- | ||
+ | |||
+ | ##### set_timer(" | ||
+ | |||
+ | * activate timer `index` and set countdown time to `secs` | ||
+ | |||
+ | **Example: | ||
+ | |||
+ | ```lua | ||
+ | set_timer(" | ||
+ | ``` | ||
+ | |||
+ | > create timer `myTimer` and start countdown time to 300 seconds | ||
+ | |||
+ | --- | ||
+ | |||
+ | |||
+ | </ | ||
+ | ==== - 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 | ||
+ | |||
+ | </file> |