﻿%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Device definition for IMSE MxDI12
%
% Settings module:
%       Parity: None
%       Baud:   38400
%       Mode:   RTU
%       
% Factory default 
%       Address: 1
% 
% Author: Daniel Carlson, ABELKO AB Luleå
%
% History:  2016-09-23 Initial version (Converted to WMPro)
%           2016-10-25 Tested and minor corrections
%
DEVICETYPE MxDI12_DI NAMED "MxDI12_DI" TYPEID 21475 IS  
  PARAMETER
    % Address of this unit
    Addr: "Address";
       
    % Trip voltage
    DI_TripVoltage: "DI Trip voltage";
      
  PUBLIC
    % Digital input
    DI1:  "DI1";
    DI2:  "DI2";
    DI3:  "DI3";
    DI4:  "DI4";
    DI5:  "DI5";
    DI6:  "DI6";
    DI7:  "DI7";
    DI8:  "DI8";
    DI9:  "DI9";
    DI10: "DI10";
    DI11: "DI11";
    DI12: "DI12";
    
    % Short circuit
    DI_ShortCirc: "DI Short Circuit";
    
  PRIVATE
    Tmp;
    
  BAUDRATE 38400;
  CHECKSUM MODBUS SWAPPED;
  
  %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  % Telegrams used for settting values in the unit
  TELEGRAM SetDISettings NAMED "SetDISettings" IS
    QUESTION
      DATA[0] := BYTE(Addr);     % Modbus unit address
      DATA[1] := BYTE(6);        % Modbus command "16" write multiple registers
      DATA[2] := RWORD(86);      % Start register
      DATA[4] <- RWORD(DATA := DI_TripVoltage;);
      
    ANSWER SIZE 8
      DATA[0] = BYTE(Addr);
      DATA[1] = BYTE(6);
      DATA[2] = BYTE(0);
      DATA[3] = BYTE(86);
  
    TIMEOUT 300
  END;
  
  %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  % Telegrams used for getting values from the unit
  
  TELEGRAM GetDIStatus NAMED "GetDIStatus" IS
    QUESTION
      DATA[0]  := BYTE(Addr);    % Modbus unit address
      DATA[1]  := BYTE(3);       % Modbus command "03h" read multiple registers
      DATA[2]  := RWORD(73);     % Start register
      DATA[4]  := RWORD(1);      % Number of registers to read
            
    ANSWER SIZE 7
      DATA[0]  =  BYTE(Addr);    % Modbus unit address
      DATA[1]  =  BYTE(3);       % Modbus command "03h" read multiple registers
      DATA[2]  =  BYTE(2);       % Number of bytes of data
      DATA[3]  -> RWORD(DI_ShortCirc := DATA;); 
          
    TIMEOUT 300
  END;
  
  TELEGRAM GetDI1_12 NAMED "DI1-12" IS
    QUESTION
      DATA[0]  := BYTE(Addr);    % Modbus unit address
      DATA[1]  := BYTE(3);       % Modbus command "03h" read multiple registers
      DATA[2]  := RWORD(1);      % Start register
      DATA[4]  := RWORD(12);     % Number of registers to read
            
    ANSWER SIZE 29
      DATA[0]  =  BYTE(Addr);    % Modbus unit address
      DATA[1]  =  BYTE(3);       % Modbus command "03h" read multiple registers
      DATA[2]  =  BYTE(24);      % Number of bytes of data, two for each DI
      DATA[3]  -> RWORD(DI1 := DATA;); 
      DATA[5]  -> RWORD(DI2 := DATA;); 
      DATA[7]  -> RWORD(DI3 := DATA;);
      DATA[9]  -> RWORD(DI4 := DATA;);
      DATA[11] -> RWORD(DI5 := DATA;);
      DATA[13] -> RWORD(DI6 := DATA;);
      DATA[15] -> RWORD(DI7 := DATA;);
      DATA[17] -> RWORD(DI8 := DATA;);
      DATA[19] -> RWORD(DI9 := DATA;);
      DATA[21] -> RWORD(DI10 := DATA;);
      DATA[23] -> RWORD(DI11 := DATA;);
      DATA[25] -> RWORD(DI12 := DATA;);
      
    TIMEOUT 300
  END;
END;

DEVICETYPE MxDI12_Frequency NAMED "MxDI12_Freq" TYPEID 21476 IS  
  PARAMETER
    % Address of this unit
    Addr: "Address";
          
  PUBLIC
    % Frequency
    DI1_Freq:  "DI1 Frequency";
    DI2_Freq:  "DI2 Frequency";
    DI3_Freq:  "DI3 Frequency";
    DI4_Freq:  "DI4 Frequency";
    DI5_Freq:  "DI5 Frequency";
    DI6_Freq:  "DI6 Frequency";
    DI7_Freq:  "DI7 Frequency";
    DI8_Freq:  "DI8 Frequency";
    DI9_Freq:  "DI9 Frequency";
    DI10_Freq: "DI10 Frequency";
    DI11_Freq: "DI11 Frequency";
    DI12_Freq: "DI12 Frequency";
        
  PRIVATE
    Tmp;
    
  BAUDRATE 38400;
  CHECKSUM MODBUS SWAPPED;
  
  %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  % Telegrams used for getting values from the unit

  TELEGRAM GetDI1_12Frequency NAMED "DI1-12_Freq" IS
    QUESTION
      DATA[0]  := BYTE(Addr);    % Modbus unit address
      DATA[1]  := BYTE(3);       % Modbus command "03h" read multiple registers
      DATA[2]  := RWORD(13);     % Start register
      DATA[4]  := RWORD(24);     % Number of registers to read
            
    ANSWER SIZE 53
      DATA[0]   =  BYTE(Addr);    % Modbus unit address
      DATA[1]   =  BYTE(3);       % Modbus command "03h" read multiple registers
      DATA[2]   =  BYTE(48);      % Number of bytes of data, two for each DI
      DATA[3]   ->  RWORD(Tmp       :=  DATA;);
      DATA[5]   ->  RWORD(DI1_Freq  := (DATA + Tmp*65536) / 1000;);
      DATA[7]   ->  RWORD(Tmp       :=  DATA;);
      DATA[9]   ->  RWORD(DI2_Freq  := (DATA + Tmp*65536) / 1000;);
      DATA[11]  ->  RWORD(Tmp       :=  DATA;);
      DATA[13]  ->  RWORD(DI3_Freq  := (DATA + Tmp*65536) / 1000;);
      DATA[15]  ->  RWORD(Tmp       :=  DATA;);
      DATA[17]  ->  RWORD(DI4_Freq  := (DATA + Tmp*65536) / 1000;);
      DATA[19]  ->  RWORD(Tmp       :=  DATA;);
      DATA[21]  ->  RWORD(DI5_Freq  := (DATA + Tmp*65536) / 1000;);
      DATA[23]  ->  RWORD(Tmp       :=  DATA;);
      DATA[25]  ->  RWORD(DI6_Freq  := (DATA + Tmp*65536) / 1000;);
      DATA[27]  ->  RWORD(Tmp       :=  DATA;);
      DATA[29]  ->  RWORD(DI7_Freq  := (DATA + Tmp*65536) / 1000;);
      DATA[31]  ->  RWORD(Tmp       :=  DATA;);
      DATA[33]  ->  RWORD(DI8_Freq  := (DATA + Tmp*65536) / 1000;);
      DATA[35]  ->  RWORD(Tmp       :=  DATA;);
      DATA[37]  ->  RWORD(DI9_Freq  := (DATA + Tmp*65536) / 1000;);
      DATA[39]  ->  RWORD(Tmp       :=  DATA;);
      DATA[41]  ->  RWORD(DI10_Freq := (DATA + Tmp*65536) / 1000;);
      DATA[43]  ->  RWORD(Tmp       :=  DATA;);
      DATA[45]  ->  RWORD(DI11_Freq := (DATA + Tmp*65536) / 1000;);
      DATA[47]  ->  RWORD(Tmp       :=  DATA;);
      DATA[49]  ->  RWORD(DI12_Freq := (DATA + Tmp*65536) / 1000;);
                  
    TIMEOUT 300
  END;
END;

DEVICETYPE MxDI12_Counter NAMED "MxDI12_Counter" TYPEID 21477 IS  
  PARAMETER
    % Address of this unit
    Addr: "Address";
    
    % Flank Settings
    DI1_4_FlankSettings:   "DI1-4 Flank";
    DI5_8_FlankSettings:   "DI5-8 Flank";
    DI9_12_FlankSettings:  "DI9-12 Flank";
          
  PUBLIC
    % Counter
    DI1_Counter:  "DI1 Counter";
    DI2_Counter:  "DI2 Counter";
    DI3_Counter:  "DI3 Counter";
    DI4_Counter:  "DI4 Counter";
    DI5_Counter:  "DI5 Counter";
    DI6_Counter:  "DI6 Counter";
    DI7_Counter:  "DI7 Counter";
    DI8_Counter:  "DI8 Counter";
    DI9_Counter:  "DI9 Counter";
    DI10_Counter: "DI10 Counter";
    DI11_Counter: "DI11 Counter";
    DI12_Counter: "DI12 Counter";
        
  PRIVATE
    Tmp;
    
  BAUDRATE 38400;
  CHECKSUM MODBUS SWAPPED;
  
  %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  % Telegrams used for settting values in the unit
  
  TELEGRAM SetFlankSettings NAMED "DI1-12_SetFlankSettings" IS
    QUESTION
      DATA[0]  := BYTE(Addr);    % Modbus unit address
      DATA[1]  := BYTE(16);      % Modbus command "16" write multiple registers
      DATA[2]  := RWORD(74);     % Start register
      DATA[4]  := RWORD(12);     % Number of registers to write
      DATA[6]  := BYTE(24);      % Numer of bytes of data, two for each register
      DATA[7]  <- RWORD(DATA := DI1_4_FlankSettings  * 4;);
      DATA[9]  <- RWORD(DATA := DI1_4_FlankSettings  * 4;);
      DATA[11] <- RWORD(DATA := DI1_4_FlankSettings  * 4;);
      DATA[13] <- RWORD(DATA := DI1_4_FlankSettings  * 4;);
      DATA[15] <- RWORD(DATA := DI5_8_FlankSettings  * 4;);
      DATA[17] <- RWORD(DATA := DI5_8_FlankSettings  * 4;);
      DATA[19] <- RWORD(DATA := DI5_8_FlankSettings  * 4;);
      DATA[21] <- RWORD(DATA := DI5_8_FlankSettings  * 4;);
      DATA[23] <- RWORD(DATA := DI9_12_FlankSettings * 4;);
      DATA[25] <- RWORD(DATA := DI9_12_FlankSettings * 4;);
      DATA[27] <- RWORD(DATA := DI9_12_FlankSettings * 4;);
      DATA[29] <- RWORD(DATA := DI9_12_FlankSettings * 4;);
      
    ANSWER SIZE 8
      DATA[0] = BYTE(Addr);
      DATA[1] = BYTE(16);
      DATA[2] = BYTE(0);
      DATA[3] = BYTE(74);
      DATA[4] = BYTE(0);
      DATA[5] = BYTE(12);
  
    TIMEOUT 300
  END;
  
  %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  % Telegrams used for getting values from the unit

  TELEGRAM GetDI1_12Counter NAMED "DI1-12_Counter" IS
    QUESTION
      DATA[0]  := BYTE(Addr);    % Modbus unit address
      DATA[1]  := BYTE(3);       % Modbus command "03h" read multiple registers
      DATA[2]  := RWORD(37);     % Start register
      DATA[4]  := RWORD(24);     % Number of registers to read
            
    ANSWER SIZE 53
      DATA[0]   =  BYTE(Addr);    % Modbus unit address
      DATA[1]   =  BYTE(3);       % Modbus command "03h" read multiple registers
      DATA[2]   =  BYTE(48);      % Number of bytes of data, two for each DI
     
      DATA[3]  ->  RWORD(Tmp          := DATA;);
      DATA[5]  ->  RWORD(DI1_Counter  := DATA + Tmp*65536;);
      DATA[7]  ->  RWORD(Tmp          := DATA;);
      DATA[9]  ->  RWORD(DI2_Counter  := DATA + Tmp*65536;);
      DATA[11]  ->  RWORD(Tmp          := DATA;);
      DATA[13]  ->  RWORD(DI3_Counter  := DATA + Tmp*65536;);
      DATA[15]  ->  RWORD(Tmp          := DATA;);
      DATA[17]  ->  RWORD(DI4_Counter  := DATA + Tmp*65536;);
      DATA[19]  ->  RWORD(Tmp          := DATA;);
      DATA[21]  ->  RWORD(DI5_Counter  := DATA + Tmp*65536;);
      DATA[23]  ->  RWORD(Tmp          := DATA;);
      DATA[25]  ->  RWORD(DI6_Counter  := DATA + Tmp*65536;);
      DATA[27]  ->  RWORD(Tmp          := DATA;);
      DATA[29]  ->  RWORD(DI7_Counter  := DATA + Tmp*65536;);
      DATA[31]  ->  RWORD(Tmp          := DATA;);
      DATA[33]  ->  RWORD(DI8_Counter  := DATA + Tmp*65536;);
      DATA[35]  ->  RWORD(Tmp          := DATA;);
      DATA[37]  ->  RWORD(DI9_Counter  := DATA + Tmp*65536;);
      DATA[39]  ->  RWORD(Tmp          := DATA;);
      DATA[41]  ->  RWORD(DI10_Counter := DATA + Tmp*65536;);
      DATA[43]  ->  RWORD(Tmp          := DATA;);
      DATA[45]  ->  RWORD(DI11_Counter := DATA + Tmp*65536;);
      DATA[47]  ->  RWORD(Tmp          := DATA;);
      DATA[49]  ->  RWORD(DI12_Counter := DATA + Tmp*65536;);

    TIMEOUT 300
  END;
END;
