ezeio2:scriptref:start

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revision Previous revision
Next revision
Previous revision
ezeio2:scriptref:start [2019-09-02 20:49] andrehezeio2:scriptref:start [2024-03-01 17:24] (current) andreh
Line 1: Line 1:
 ===== Script reference ===== ===== Script reference =====
-{{indexmenu_n>710}}+{{indexmenu_n>1000}}
  
 === ezeio script programming - the PAWN language === === ezeio script programming - the PAWN language ===
Line 12: Line 12:
 We strongly recommend reading the following documents to get introduced to the PAWN language: We strongly recommend reading the following documents to get introduced to the PAWN language:
  
-[[https://github.com/compuphase/pawn/raw/master/doc/Pawn_Getting_Started.pdf|Introduction to PAWN]]+[[https://doc.eze.io/_media/ezeio2/pawn_getting_started.pdf|Introduction to PAWN]]
  
-[[https://github.com/compuphase/pawn/raw/master/doc/Pawn_Language_Guide.pdf|PAWN language guide]]+[[https://doc.eze.io/_media/ezeio2/pawn_language_guide.pdf|PAWN language guide]]
  
  
Line 31: Line 31:
 The estimated requirements for a script is displayed when compiling. The estimated requirements for a script is displayed when compiling.
  
-=== Programming style ===+=== Programming pattern ===
  
-Although the user script runs in a sandboxed runtime engine, the recommended programming pattern is similar to cooperative multitasking. +Although the user script runs in a sandboxed runtime engine, the recommended programming pattern is similar to [[https://en.wikipedia.org/wiki/Cooperative_multitasking|cooperative multitasking]].
- +
-This means that you should avoid long-running loops, and instead make use of blocking calls or system callbacks provided in the function library. +
- +
-The following calls are blocking: +
- +
-| ''ModbusRead()'' | Read a register block from a Modbus RTU device | +
-| ''RS485WriteRead()'' | Write & Read to the Modbus port in 'raw' mode (not Modbus protocol) | +
-| ''ModbusWriteRead()'' | Write and read Modbus commands on the RTU port | +
-| ''SDICmd()'' | Send a SDI12 command and receive the response | +
-| ''ModbusTCP()'' | Send & Receive Modbus commands on the Ethernet port | +
-| ''sleep()'' | Suspend the script for a short time (process events immediately) | +
-| ''msSleep()'' | Suspend the script for a short time (not processing events - DEPRECIATED) | +
-| ''MBRTU_Read()'' | Read a register from a Modbus RTU device | +
-| ''MBRTU_Write()'' | Write to a register on a Modbus RTU device | +
-| ''MBTCP_Read()'' | Read a register from a Modbus TCP device | +
-| ''MBTCP_Write()'' | Write to a register on a ModbusTCP device | +
-| ''SunSpecIP_Base()'' | Find the base address for a SunSpec/TCP device | +
-| ''SunSpecIP_Ofs()'' | Find the offset for a SunSpec/TCP device |+
  
 +This means that you should avoid long-running loops, and instead make use of system callbacks provided in the function library.
  
 The following system callback functions are defined: The following system callback functions are defined:
  
 | ''@Tick'' | Called at a regular interval, set by SetTickInterval() | | ''@Tick'' | Called at a regular interval, set by SetTickInterval() |
-| ''@Timer'' | Called when one of the four millisecond timers expire, see SetTimer() |+| ''@Timer'' | Called when one of the millisecond timers expire, see SetTimer() |
 | ''@Action'' | Called when an action is triggered due to an alarm event | | ''@Action'' | Called when an action is triggered due to an alarm event |
 | ''@Key'' | Called when a button is pressed on a connected terminal device | | ''@Key'' | Called when a button is pressed on a connected terminal device |
 | ''@Scan'' | Called when a code is received from a scanner device | | ''@Scan'' | Called when a code is received from a scanner device |
-| ''@J1939'' | Called when a J1939 packet is received | 
  
 +=== Some examples ===
 +
 +The program below will print out "Hello" on the debug console.
 +
 +<code javascript>
 +main()
 +{
 +    PDebug("Hello");
 +}
 +</code>
 +
 +The following example adds the values of field 1 and field 2 together, and writes the result to field 3.
 +
 +<code javascript>
 +// This example adds the value of field 1 and 2 and writes the sum to field 3
 +// The value of field 3 is updated every 500ms (twice per second)
 +
 +main()
 +{
 +    SetTickInterval(500);       // Make sure the @Tick function is called twice per second
 +}
 +
 +@Tick(uptime)
 +{
 +    new f1, f2;             // declare local variables
 +    
 +    f1 = GetField(1);       // set f1 to the value of field 1
 +    f2 = GetField(2);       // set f2 to the value of field 2
 +    
 +    SetField(3, f1+f2);     // set the value of field 3 with the sum of f1 and f2
 +}
 +</code>
 +
 +The example below illustrates the use of a global variable, the use of the main() function to initialize the values, and the @Tick(uptime) call. The program will use field number 1, and count from 100 down to 50, and then starting over.
 +
 +<code javascript>
 +// A simple demo program, counting down from 100 to 50, and then starts over
 +
 +new myCounter;                  // Declare a 'global' variable
 +
 +main()                          // The main() function will run on startup, once
 +{
 +    SetTickInterval(1000);      // Make sure the @Tick function is called once every 1000ms (1s)
 +    myCounter = 100;            // Initialize the counter with value 100
 +}
 +
 +@Tick(uptime)                   // The @Tick function will be called once per second
 +{
 +    myCounter = myCounter - 1;  // Count down the counter with 1
 +    
 +    if(myCounter <= 50) {       // If we reached 50 (or lower)
 +        myCounter = 100         // ..then set it back to 100
 +    }
 +        
 +    SetField(1, myCounter);     // Update field 1 with the counter value
 +}
 +</code>
 +
 +The example below will run a 3-speed fan based on the input from a temperature sensor on field 1.
 +Output 1 is used for low speed, output 2 is medium speed, and output 3 is high speed.
 +The speed is selected based on how much the temperature exceeds a given setpoint (here set to 20.5 degrees C)
 +
 +<code javascript>
 +main()
 +{
 +    SetTickInterval(5000);  // Update every 5s (5000ms)
 +}
 +
 +@Tick(uptime)
 +{
 +    new Float:temp, Float:diff; // Declare "float" variables to handle fractions
 +    
 +    temp = GetFieldFloat(1);    // Fetch the current temperature from Field 1
 +    diff = temp - 20.5;         // 20.5 is our setpoint. diff is the differece
 +    
 +    if(diff > 0.0)              // Over setpoint?
 +        SetOutput(1, 100);      // ..yes, so enable low speed
 +    else
 +        SetOutput(1, 0);        // ..no, so shut off
 +        
 +    if(diff > 2.0)              // 2 degrees or more over setpoint?
 +        SetOutput(2, 100);      //..yes, so enable mid-speed
 +    else
 +        SetOutput(2, 0);
 +
 +    if(diff > 6.0)              // 6 degrees or more over setpoint?
 +        SetOutput(3, 100);      //..yes, so run full speed
 +    else
 +        SetOutput(3, 0);
 +}
 +</code>
 +
 +=== State machines ===
 +
 +A common programming pattern in control applications is to use state machines. PAWN and the ezeio implements strong support for state machines. The following is a typical pattern showing the startup sequence of an engine. Note that there are three @Tick handlers; one for each state. Also note the "entry" and "exit" functions. For more detail, refer to the PAWN language guide.
 +
 +<code javascript>
 +
 +  new count = 0;
 +
 +  main()
 +  {
 +    SetTickInterval(100);   // set tick interval to 100ms (0.1s)
 +    state WAITING;          // start in the waiting mode
 +  }
 +  
 +  @Tick(uptime) <WAITING>
 +  {
 +     if( GetField(1) < 100 )  // condition to start up the process
 +        state IGNITION;
 +  }
 +  
 +// ***** the IGNITION state
 +
 +  entry() <IGNITION>
 +  {
 +     SetOutput(1, 100);       // Turn on the ignition switch
 +     count = 0;
 +  }
 +  
 +  @Tick(uptime) <IGNITION>
 +  {
 +     if( GetField(2) > 100 )  // Did the engine start?
 +        state RUNNING;        // yes - we're running
 +
 +     if(count++ > 50)
 +        state WAITING;        // didn't start in 5s? Give up and go back to waiting.
 +  }
 +  
 +  exit() <IGNITION>
 +  {
 +     SetOutput(1, 0);         // Turn the ignition switch off
 +  }
 +  
 +// ***** the RUNNING state
 +
 +  @Tick(uptime) <RUNNING>
 +  {
 +     if( GetField(2) < 100 )  // Check if the engine stopped
 +        state WAITING;        // ..go back to waiting
 +  }
 +  
 +</code>
  
  • ezeio2/scriptref/start.1567457375.txt.gz
  • Last modified: 2019-09-02 20:49
  • by andreh