IMSE MxM28 (WMPro)

Detaljer

Typ
Drivrutin
Upplaggd av
Daniel Carlson, Abelko Innovation
Version
5
Uppdaterad
2016-11-02
Skapad
2015-12-08
Kategori
IO enheter, Modbus
Visningar
2857

Beskrivning

Typdefinition för Abelkos expansionsmodul MxM28 som ingår IMSE-familjen. Detta skript används då modulen kopplas som en modbus-enhet till en WMPro.
Modulen har 8 universalingångar, 8 digitala ingångar, 6 analoga utgångar och 6 digitala reläutgångar.

Bruksanvisning

Detta skript är anpassat till WMPro och saknar därför en del funktionalitet jämfört med det skript som är skrivet för UltraBase30. Saknade funktioner är t.ex. nollställning av räknaringångar, val av fast resistansområde, mm.

Skriptet är uppdelat i fyra separata enheter (p.g.a. begränsningar av antalet publika variabler och parametrar i en WMPro):
ExM28_DI_DO (TYEPID 21471)
- Styr digitala utgångar
- Läser digitala ingångar
- Val av omslagsspänning för digitala ingångar
- Kommunikationstimeout för när en utgång skall nollställas vid kommunikationsbortfall
- Status för manuellstyrning av digitala utgångar

ExM28_Freq_Count (TYPEID 21472)
- Frekvensingng för en digital ingång
- Räknare på digitala ingångar
- Val av vilken flank räknarna skall slå om på (atigande, fallande eller båda)

ExM28_AO (TYPEID 21473)
- Styr analoga utgångar
- Status för manuellstyrning
(- Använd ExM28_DI_DO för att ställa kommunikationstimeout)

ExM28_UI (TYPEID 21470)
- Läser universalingångar
- Status på universalingångar
- Val av typ. Resistans, spänning, ström, DI, eller givare enligt följande lista:
0 Resistans (Råvärde)
1 Spänning
2 Ström
3 DI (Sluts mot jord för aktiv signal)
4 Pt100 (EN 60751 / IEC 751) α 0.003850 -50 till 850 ˚C
5 Pt100 α 0.003750 -50 till 850 ˚C
6 Pt100 α 0.003920 -50 till 850 ˚C
7 Pt1000 (EN 60751 / IEC 751) α 0.003850 -50 till 850 ˚C
8 Pt1000 α 0.003750 -50 till 850 ˚C
9 Pt1000 α 0.003920 -50 till 850 ˚C
10 Ni1000 (DIN 43760) -50 till 160 ˚C
11 Ni1000LG -50 till 120 ˚C
12 L&S QAC31/32 (670.89 Ω vid -35 ˚C) -50 till 50 ˚C
13 NTC575 (Siemens / QAC31/32) (672.1 Ω vid -35 ˚C) -35 till 35 ˚C
14 FWT1G -35 till 130 ˚C
15 FO-T35 -35 till 35 ˚C
16 TAC EGU -50 till 125 ˚C
17 Satchwell DOT,DWT,DWS -50 till 150 ˚C
18 Satchwell DW1202 / DW1204 0 till 150 ˚C
19 Satchwell DO2202 -40 till 40 ˚C
20 IVT -40 till 90 ˚C
21 NIBE -40 till 50 ˚C
22 Vissman KTY 10/7 (Siemens) -40 till 113 ˚C
23 RST Instruments 2252(25) -40 till 40 ˚C

Juridisk information

Alla skript tillhandahålls i befintligt skick och all användning sker på eget ansvar. Felaktig använding kan leda till skadad eller förstörd utrustning.

Skript kod

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Device definition for IMSE ExM28
%
% Settings module:
%       Parity: None
%       Baud:   38400
%       Mode:   RTU
%       
% Factory default 
%       Address: 1

% Author: Daniel Carlson, ABELKO AB Luleå
%
% History:  2014-03-28 Initial version
%           2015-11-26 Converted to fit WMPro
%           2016-03-23 RWORD not allowed as comparison in answers
%           2016-04-08 Group script for UI added
%
DEVICETYPE ExM28_DI_DO NAMED "ExM28_DI_DO" TYPEID 21471 IS  
  PARAMETER
    % Address of this unit
    Addr: "Address";
    
    % Communication timeout
    ComTimeout: "ComTimeout";
       
    % Trip voltage
    DI_TripVoltage: "DI Trip voltage";
    
    % Digital output
    DO1: "DO1";      
    DO2: "DO2";      
    DO3: "DO3";      
    DO4: "DO4";      
    DO5: "DO5";      
    DO6: "DO6";
      
  PUBLIC
    % Digital input
    DI1  :"DI1";      
    DI2  :"DI2";      
    DI3  :"DI3";      
    DI4  :"DI4";      
    DI5  :"DI5";      
    DI6  :"DI6";      
    DI7  :"DI7";      
    DI8  :"DI8";
    
    % Short circuit
    DI_ShortCirc: "DI Short Circuit";
    
    % DO Override
    DO1_Overridden : "DO1 Man. overr.";      
    DO2_Overridden : "DO2 Man. overr.";      
    DO3_Overridden : "DO3 Man. overr.";      
    DO4_Overridden : "DO4 Man. overr.";   
    DO5_Overridden : "DO5 Man. overr.";      
    DO6_Overridden : "DO6 Man. overr.";    
    
  PRIVATE
    Tmp;
    
  BAUDRATE 38400;
  CHECKSUM MODBUS SWAPPED;
  
  TELEGRAM SetComTimeout NAMED "SetCommunicationTimeout" IS
    QUESTION
      DATA[0]  := BYTE(Addr);    % Modbus unit address
      DATA[1]  := BYTE(6);       % Modbus command "6" write single register
      DATA[2]  := RWORD(101);    % Start register
      DATA[4]  <- RWORD(DATA := ComTimeout;); 
      
    ANSWER SIZE 8
      DATA[0] = BYTE(Addr);
      DATA[1] = BYTE(6);
      DATA[2] = BYTE(0);
      DATA[3] = BYTE(101);
  
    TIMEOUT 300
  END;
  
  TELEGRAM SetDO1_6 NAMED "SetDO1-6" IS
    QUESTION
      DATA[0]  := BYTE(Addr);    % Modbus unit address
      DATA[1]  := BYTE(16);      % Modbus command "16" write multiple registers
      DATA[2]  := RWORD(102);    % Start register
      DATA[4]  := RWORD(6);      % Number of registers to write
      DATA[6]  := BYTE(12);      % Numer of bytes of data, two for each DO
      DATA[7]  <- RWORD(DATA := DO1;);
      DATA[9]  <- RWORD(DATA := DO2;);
      DATA[11] <- RWORD(DATA := DO3;);
      DATA[13] <- RWORD(DATA := DO4;);
      DATA[15] <- RWORD(DATA := DO5;);
      DATA[17] <- RWORD(DATA := DO6;);
      
    ANSWER SIZE 8
      DATA[0] = BYTE(Addr);
      DATA[1] = BYTE(16);
      DATA[2] = BYTE(0);
      DATA[3] = BYTE(102);
      DATA[4] = BYTE(0);
      DATA[5] = BYTE(6);

    TIMEOUT 300
  END;
  
  %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  % 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(100);     % 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(100);
  
    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(49);     % 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);      % Numer of bytes of data
      DATA[3]  -> RWORD(DI_ShortCirc := DATA;); 
          
    TIMEOUT 300
  END;
  
  TELEGRAM GetDI1_8 NAMED "DI1-8" 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(8);      % Number of registers to read
            
    ANSWER SIZE 21
      DATA[0]  =  BYTE(Addr);    % Modbus unit address
      DATA[1]  =  BYTE(3);       % Modbus command "03h" read multiple registers
      DATA[2]  =  BYTE(16);      % Numer 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;);
      
    TIMEOUT 300
  END;
      
  TELEGRAM GetDOManualOverrideStatus NAMED "DOManualOverrideStatus" IS
    QUESTION
      DATA[0]  := BYTE(Addr);    % Modbus unit address
      DATA[1]  := BYTE(3);       % Modbus command "03h" read multiple registers
      DATA[2]  := RWORD(50);     % Start register
      DATA[4]  := RWORD(6);      % Number of registers to read
            
    ANSWER SIZE 17
      DATA[0]  =   BYTE(Addr);    % Modbus unit address
      DATA[1]  =   BYTE(3);       % Modbus command "03h" read multiple registers
      DATA[2]  =   BYTE(12);      % Numer of bytes of data
      DATA[3]  ->  RWORD(DO1_Overridden := DATA;);
      DATA[5]  ->  RWORD(DO2_Overridden := DATA;);
      DATA[7]  ->  RWORD(DO3_Overridden := DATA;);
      DATA[9]  ->  RWORD(DO4_Overridden := DATA;);
      DATA[11] ->  RWORD(DO5_Overridden := DATA;);
      DATA[13] ->  RWORD(DO6_Overridden := DATA;);
      
    TIMEOUT 300
  END;  
END;

DEVICETYPE ExM28_Freq_Count NAMED "ExM28_Freq_Count" TYPEID 21472 IS  
  PARAMETER
    % Address of this unit
    Addr: "Address";
    
    % Flank Settings
    DI1_FlankSettings: "DI1 Pulse edge";      
    DI2_FlankSettings: "DI2 Pulse edge";      
    DI3_FlankSettings: "DI3 Pulse edge";      
    DI4_FlankSettings: "DI4 Pulse edge";    
    DI5_FlankSettings: "DI5 Pulse edge";      
    DI6_FlankSettings: "DI6 Pulse edge";      
    DI7_FlankSettings: "DI7 Pulse edge";      
    DI8_FlankSettings: "DI8 Pulse edge";
          
  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";
      
    % 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";
        
  PRIVATE
    Tmp;
    
  BAUDRATE 38400;
  CHECKSUM MODBUS SWAPPED;
  
  %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  % Telegrams used for settting values in the unit
  
  TELEGRAM SetFlankSettings NAMED "SetFlankSettings" IS
    QUESTION
      DATA[0]  := BYTE(Addr);    % Modbus unit address
      DATA[1]  := BYTE(16);      % Modbus command "16" write multiple registers
      DATA[2]  := RWORD(92);     % Start register
      DATA[4]  := RWORD(8);      % Number of registers to write
      DATA[6]  := BYTE(16);      % Numer of bytes of data, two for each register
      DATA[7]  <- RWORD(DATA := DI1_FlankSettings * 4;);
      DATA[9]  <- RWORD(DATA := DI2_FlankSettings * 4;);
      DATA[11] <- RWORD(DATA := DI3_FlankSettings * 4;);
      DATA[13] <- RWORD(DATA := DI4_FlankSettings * 4;);
      DATA[15] <- RWORD(DATA := DI5_FlankSettings * 4;);
      DATA[17] <- RWORD(DATA := DI6_FlankSettings * 4;);
      DATA[19] <- RWORD(DATA := DI7_FlankSettings * 4;);
      DATA[21] <- RWORD(DATA := DI8_FlankSettings * 4;);
      
    ANSWER SIZE 8
      DATA[0] = BYTE(Addr);
      DATA[1] = BYTE(16);
      DATA[2] = BYTE(0);
      DATA[3] = BYTE(92);
      DATA[4] = BYTE(0);
      DATA[5] = BYTE(8);
  
    TIMEOUT 300
  END;
  
  %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  % Telegrams used for getting values from the unit

  TELEGRAM GetDI1_8Freq_Cnt NAMED "DI1-8Freq_Cnt" IS
    QUESTION
      DATA[0]  := BYTE(Addr);    % Modbus unit address
      DATA[1]  := BYTE(3);       % Modbus command "03h" read multiple registers
      DATA[2]  := RWORD(9);      % Start register
      DATA[4]  := RWORD(32);     % Number of registers to read
            
    ANSWER SIZE 69
      DATA[0]   =  BYTE(Addr);    % Modbus unit address
      DATA[1]   =  BYTE(3);       % Modbus command "03h" read multiple registers
      DATA[2]   =  BYTE(64);      % Numer 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(DI1_Counter := DATA + Tmp*65536;);
      DATA[39]  ->  RWORD(Tmp         := DATA;);
      DATA[41]  ->  RWORD(DI2_Counter := DATA + Tmp*65536;);
      DATA[43]  ->  RWORD(Tmp         := DATA;);
      DATA[45]  ->  RWORD(DI3_Counter := DATA + Tmp*65536;);
      DATA[47]  ->  RWORD(Tmp         := DATA;);
      DATA[49]  ->  RWORD(DI4_Counter := DATA + Tmp*65536;);
      DATA[51]  ->  RWORD(Tmp         := DATA;);
      DATA[53]  ->  RWORD(DI5_Counter := DATA + Tmp*65536;);
      DATA[55]  ->  RWORD(Tmp         := DATA;);
      DATA[57]  ->  RWORD(DI6_Counter := DATA + Tmp*65536;);
      DATA[59]  ->  RWORD(Tmp         := DATA;);
      DATA[61]  ->  RWORD(DI7_Counter := DATA + Tmp*65536;);
      DATA[63]  ->  RWORD(Tmp         := DATA;);
      DATA[65]  ->  RWORD(DI8_Counter := DATA + Tmp*65536;);
            
    TIMEOUT 300
  END;
END;

DEVICETYPE ExM28_AO NAMED "ExM28_AO" TYPEID 21473 IS  
  PARAMETER
    % Address of this unit
    Addr: "Address";
    
    % Communication timeout
    % ComTimeout: "ComTimeout"; Note! Use DI_DO-script to set this parameter

    % Analog output
    AO1: "AO1";      
    AO2: "AO2";      
    AO3: "AO3";      
    AO4: "AO4";      
    AO5: "AO5";      
    AO6: "AO6";
      
  PUBLIC
    % AO Override
    AO1_Overridden : "AO1 Man. overr.";      
    AO2_Overridden : "AO2 Man. overr.";      
    AO3_Overridden : "AO3 Man. overr.";      
    AO4_Overridden : "AO4 Man. overr.";      
    AO5_Overridden : "AO5 Man. overr.";      
    AO6_Overridden : "AO6 Man. overr.";      
    
  PRIVATE
    Tmp;
    Tmp2;
    
  BAUDRATE 38400;
  CHECKSUM MODBUS SWAPPED;
      
  TELEGRAM SetAO1_6 NAMED "SetAO1-6" IS
    QUESTION
      DATA[0]  := BYTE(Addr);    % Modbus unit address
      DATA[1]  := BYTE(16);      % Modbus command "16" write multiple registers
      DATA[2]  := RWORD(116);    % Start register
      DATA[4]  := RWORD(12);     % Number of registers to write
      DATA[6]  := BYTE(24);      % Numer of bytes of data, two for each AO
      DATA[7]  := RWORD(0);
      DATA[9]  <- RWORD(DATA :=  AO1 * 1000;);
      DATA[11] := RWORD(0);
      DATA[13] <- RWORD(DATA :=  AO2 * 1000;);
      DATA[15] := RWORD(0);
      DATA[17] <- RWORD(DATA :=  AO3 * 1000;);
      DATA[19] := RWORD(0);
      DATA[21] <- RWORD(DATA :=  AO4 * 1000;);
      DATA[23] := RWORD(0);
      DATA[25] <- RWORD(DATA :=  AO5 * 1000;);
      DATA[27] := RWORD(0);
      DATA[29] <- RWORD(DATA :=  AO6 * 1000;);
      
    ANSWER SIZE 8
      DATA[0] = BYTE(Addr);
      DATA[1] = BYTE(16);
      DATA[2] = BYTE(0);
      DATA[3] = BYTE(116);
      DATA[4] = BYTE(0);
      DATA[5] = BYTE(12);

    TIMEOUT 300
  END;
  
  %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  % Telegrams used for getting values from the unit
  
  TELEGRAM GetAO1_6Status NAMED "GetAO1-6Status" IS
    QUESTION
      DATA[0]  := BYTE(Addr);    % Modbus unit address
      DATA[1]  := BYTE(3);       % Modbus command "03h" read multiple registers
      DATA[2]  := RWORD(80);     % 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);      % Numer of bytes of data
      DATA[3]  -> RWORD(Tmp :=  DATA;);
      DATA[5]  -> RWORD(IF DATA < 32768 THEN AO1_Overridden := (DATA + Tmp*65536) / 1000; ELSE AO1_Overridden := -1; ENDIF;);
      DATA[7]  -> RWORD(Tmp :=  DATA;);
      DATA[9]  -> RWORD(IF DATA < 32768 THEN AO2_Overridden := (DATA + Tmp*65536) / 1000; ELSE AO2_Overridden := -1; ENDIF;);
      DATA[11] -> RWORD(Tmp :=  DATA;);
      DATA[13] -> RWORD(IF DATA < 32768 THEN AO3_Overridden := (DATA + Tmp*65536) / 1000; ELSE AO3_Overridden := -1; ENDIF;);
      DATA[15] -> RWORD(Tmp :=  DATA;);
      DATA[17] -> RWORD(IF DATA < 32768 THEN AO4_Overridden := (DATA + Tmp*65536) / 1000; ELSE AO4_Overridden := -1; ENDIF;);
      DATA[19] -> RWORD(Tmp :=  DATA;);
      DATA[21] -> RWORD(IF DATA < 32768 THEN AO5_Overridden := (DATA + Tmp*65536) / 1000; ELSE AO5_Overridden := -1; ENDIF;);
      DATA[23] -> RWORD(Tmp :=  DATA;);
      DATA[25] -> RWORD(IF DATA < 32768 THEN AO6_Overridden := (DATA + Tmp*65536) / 1000; ELSE AO6_Overridden := -1; ENDIF;);
      
    TIMEOUT 300
  END;
END;

DEVICETYPE ExM28_UI NAMED "ExM28_UI" TYPEID 21470 IS  
  PARAMETER
    % Address of this unit
    Addr: "Address";
    
    % Universal input type
    UI1_Type: "UI1 Type";      
    UI2_Type: "UI2 Type";      
    UI3_Type: "UI3 Type";      
    UI4_Type: "UI4 Type";      
    UI5_Type: "UI5 Type";      
    UI6_Type: "UI6 Type";      
    UI7_Type: "UI7 Type";      
    UI8_Type: "UI8 Type";
    
    % Resistor Range
    %UI1_Range: "UI1_Range ";
    %UI2_Range: "UI2_Range ";
    %UI3_Range: "UI3_Range ";
    %UI4_Range: "UI4_Range ";
    %UI5_Range: "UI5_Range ";
    %UI6_Range: "UI6_Range ";
    %UI7_Range: "UI7_Range ";
    %UI8_Range: "UI8_Range ";
      
  PUBLIC
    % Universal input value
    UI1 : "UI1";      
    UI2 : "UI2";      
    UI3 : "UI3";      
    UI4 : "UI4";      
    UI5 : "UI5";      
    UI6 : "UI6";      
    UI7 : "UI7";      
    UI8 : "UI8";
   
    % Universal input status
    UI1_Status : "UI1 Status";      
    UI2_Status : "UI2 Status";      
    UI3_Status : "UI3 Status";      
    UI4_Status : "UI4 Status";      
    UI5_Status : "UI5 Status";      
    UI6_Status : "UI6 Status";      
    UI7_Status : "UI7 Status";      
    UI8_Status : "UI8 Status";
          
  PRIVATE
    Tmp;
    UI1_Raw;
    UI2_Raw;
    UI3_Raw;
    UI4_Raw;
    UI5_Raw;
    UI6_Raw;
    UI7_Raw;
    UI8_Raw;
    
    % Used by group script
    Input;
    Raw;
    Type;
    Value;
    R2;
    R3;
    R5;
    R7;
    LNR;
    
  BAUDRATE 38400;
  CHECKSUM MODBUS SWAPPED;
    
  TELEGRAM SetUISettings NAMED "SetUISettings" IS
    QUESTION
      DATA[0]  := BYTE(Addr);    % Modbus unit address
      DATA[1]  := BYTE(16);      % Modbus command "16" write multiple registers
      DATA[2]  := RWORD(108);    % Start register
      DATA[4]  := RWORD(8);      % Number of registers to write
      DATA[6]  := BYTE(16);      % Numer of bytes of data, two for each DO
      DATA[7]  <- RWORD(IF UI1_Type > 3 THEN DATA := 0; ELSE DATA := UI1_Type * 64; ENDIF;);
      DATA[9]  <- RWORD(IF UI1_Type > 3 THEN DATA := 0; ELSE DATA := UI2_Type * 64; ENDIF;);
      DATA[11] <- RWORD(IF UI1_Type > 3 THEN DATA := 0; ELSE DATA := UI3_Type * 64; ENDIF;);
      DATA[13] <- RWORD(IF UI1_Type > 3 THEN DATA := 0; ELSE DATA := UI4_Type * 64; ENDIF;);
      DATA[15] <- RWORD(IF UI1_Type > 3 THEN DATA := 0; ELSE DATA := UI5_Type * 64; ENDIF;);
      DATA[17] <- RWORD(IF UI1_Type > 3 THEN DATA := 0; ELSE DATA := UI6_Type * 64; ENDIF;);
      DATA[19] <- RWORD(IF UI1_Type > 3 THEN DATA := 0; ELSE DATA := UI7_Type * 64; ENDIF;);
      DATA[21] <- RWORD(IF UI1_Type > 3 THEN DATA := 0; ELSE DATA := UI8_Type * 64; ENDIF;);
          
    ANSWER SIZE 8
      DATA[0] = BYTE(Addr);
      DATA[1] = BYTE(16);
      DATA[2] = BYTE(0);
      DATA[3] = BYTE(108);
      DATA[4] = BYTE(0);
      DATA[5] = BYTE(8);

    TIMEOUT 300
  END;
      
  %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  % Telegrams used for getting values from the unit
    
  TELEGRAM GetUI1_8 NAMED "GetUI1-8" IS
    QUESTION
      DATA[0]  := BYTE(Addr);    % Modbus unit address
      DATA[1]  := BYTE(3);       % Modbus command "03h" read multiple registers
      DATA[2]  := RWORD(56);     % Start register
      DATA[4]  := RWORD(16);     % Number of registers to read
            
    ANSWER SIZE 37
      DATA[0]  =  BYTE(Addr);    % Modbus unit address
      DATA[1]  =  BYTE(3);       % Modbus command "03h" read multiple registers
      DATA[2]  =  BYTE(32);      % Numer of bytes of data
      
      DATA[3]  -> RWORD(Tmp     :=  DATA;);
      DATA[5]  -> RWORD(UI1_Raw := (DATA + Tmp*65536) / 1000;);
      DATA[7]  -> RWORD(Tmp     :=  DATA;);
      DATA[9]  -> RWORD(UI2_Raw := (DATA + Tmp*65536) / 1000;);
      DATA[11] -> RWORD(Tmp     :=  DATA;);
      DATA[13] -> RWORD(UI3_Raw := (DATA + Tmp*65536) / 1000;);
      DATA[15] -> RWORD(Tmp     :=  DATA;);
      DATA[17] -> RWORD(UI4_Raw := (DATA + Tmp*65536) / 1000;);
      DATA[19] -> RWORD(Tmp     :=  DATA;);
      DATA[21] -> RWORD(UI5_Raw := (DATA + Tmp*65536) / 1000;);
      DATA[23] -> RWORD(Tmp     :=  DATA;);
      DATA[25] -> RWORD(UI6_Raw := (DATA + Tmp*65536) / 1000;);
      DATA[27] -> RWORD(Tmp     :=  DATA;);
      DATA[29] -> RWORD(UI7_Raw := (DATA + Tmp*65536) / 1000;);
      DATA[31] -> RWORD(Tmp     :=  DATA;);
      DATA[33] -> RWORD(UI8_Raw := (DATA + Tmp*65536) / 1000;);
      
    TIMEOUT 300
  END;
  
  TELEGRAM GetUI1_8Status NAMED "GetUI1-8Status" IS
    QUESTION
      DATA[0]  := BYTE(Addr);    % Modbus unit address
      DATA[1]  := BYTE(3);       % Modbus command "03h" read multiple registers
      DATA[2]  := RWORD(72);     % Start register
      DATA[4]  := RWORD(8);      % Number of registers to read
            
    ANSWER SIZE 21
      DATA[0]  =  BYTE(Addr);    % Modbus unit address
      DATA[1]  =  BYTE(3);       % Modbus command "03h" read multiple registers
      DATA[2]  =  BYTE(16);      % Numer of bytes of data
      DATA[3]  -> RWORD(UI1_Status := DATA;);
      DATA[5]  -> RWORD(UI2_Status := DATA;);
      DATA[7]  -> RWORD(UI3_Status := DATA;);
      DATA[9]  -> RWORD(UI4_Status := DATA;);
      DATA[11] -> RWORD(UI5_Status := DATA;);
      DATA[13] -> RWORD(UI6_Status := DATA;);
      DATA[15] -> RWORD(UI7_Status := DATA;);
      DATA[17] -> RWORD(UI8_Status := DATA;);
      
    TIMEOUT 300
  END;
END; 


% Group script used to calulate vaues for universal inputs
GROUP All_UI OF MAX 4 DEVICE TYPEID 21470 SELECT ALL
  ITERATOR CalcValue
  ALIAS
  BEGIN
    IF Input = 1 THEN
      Type  := UI2_Type;
      Raw   := UI2_Raw;
    ELSIF Input = 2 THEN
      Type  := UI3_Type;
      Raw   := UI3_Raw;
    ELSIF Input = 3 THEN
      Type  := UI4_Type;
      Raw   := UI4_Raw;
    ELSIF Input = 4 THEN
      Type  := UI5_Type;
      Raw   := UI5_Raw;
    ELSIF Input = 5 THEN
      Type  := UI6_Type;
      Raw   := UI6_Raw;
    ELSIF Input = 6 THEN
      Type  := UI7_Type;
      Raw   := UI7_Raw;
    ELSIF Input = 7 THEN
      Type  := UI8_Type;
      Raw   := UI8_Raw;
    ELSE
      Type  := UI1_Type;
      Raw   := UI1_Raw;
      Input := 0;
    ENDIF;
    
    IF Type <= 3 THEN % Raw resistance, Voltage, Current or DI
      Value := Raw;
    
    ELSIF Type = 4 THEN %Pt100 EN 50 751 alpha 0.00385
      Value := 3383.809524 - 0.08658008660 * (1758480889 - 2310000 * Raw)^0.5;
    ELSIF Type = 5 THEN %Pt100 alpha 0.00375
      Value := 3164.451827 - 8305.647840 * (0.169241 - 0.000240800 * Raw)^0.5;
    ELSIF Type = 6 THEN %Pt100 alpha 0.00392
      Value := 3392.940594 - 8527.911855 * (0.1817473668 - 0.00023452400 * Raw)^0.5;
    ELSIF Type = 7 THEN %Pt1000 EN 50 751 alpha 0.00385
      Value := 3383.809524 - 865.8008660 * (17.58480889 - 0.00231 * Raw)^0.5;
    ELSIF Type = 8 THEN %Pt1000 alpha 0.00375
      Value := 3164.451827 - 830.5647840 * (16.9241 - 0.002408 * Raw)^0.5;
    ELSIF Type = 9 THEN %Pt1000 alpha 0.00392
      Value := 3392.940594 - 852.7911855 * (18.17473668 - 0.00234524 * Raw)^0.5;
    ELSIF Type = 10 THEN %Ni1000 DIN
      R5:= Raw*Raw*Raw*Raw*Raw;
      R7:= R5*Raw*Raw;
      Value := (-412.6) + (140.41 * (1 + (0.00764 * Raw))^0.5) - (0.0000000000000000625 * R5) - (0.00000000000000000000000125 * R7);
    ELSIF Type = 11 THEN %Ni1000 LG
      R2:= Raw*Raw;
      R3:= R2*Raw;
      Value := (-300.0187) + (Raw * 0.3888) - (R2 * 0.00010355) + (R3 * 0.000000014749);
    ELSIF Type = 12 THEN %QAC31/32 old
      R2:= Raw*Raw;
      R3:= R2*Raw;
      IF Raw <= 622.27 THEN
        Value :=  1840.822526461981 - (8.81283638032425 * Raw) + (0.01481833026842 * R2) - (0.000008693645718129028 * R3);
      ELSIF Raw <= 655.74 THEN
        Value :=  18284.57180623524 - (87.53497076730491 * Raw) + (0.14047361791540 * R2) - (0.00007556728104760220 * R3);
      ELSE
        Value :=  447598.5593294129 - (2034.707401563966 * Raw) + (3.08435262703205 * R2) - (0.00155918519608 * R3);      
      ENDIF;  
    ELSIF Type = 13 THEN %NTC575 (QAC3132)
      R2:= Raw*Raw;
      R3:= R2*Raw;
      IF Raw <= 616.7 THEN
        Value :=  1984.368236149433 - (9.45847603610924 * Raw) + (0.01577267911992 * R2) - (0.000009153756833227248 * R3);
      ELSIF Raw <= 675.5 THEN
        Value :=  13500.31890121417 - (64.89024643188350 * Raw) + (0.10472492893027 * R2) - (0.00005674169841769381 * R3);
      ELSE
        Value :=  -8135.044676629710 + (25.40018648262130 * Raw) - (0.01986043031034 * R2);      
      ENDIF;  
    ELSIF Type = 14 THEN %FWT1G
      Value := (-264.6311531847244) + (Raw * 0.13733939226662) - (Raw * Raw * 0.000008300189626466234);
    ELSIF Type = 15 THEN %FOT35
      LNR:= LN(Raw);
      Value := 245.7686957352614 - (Raw * 0.0002180214076186565) + (Raw * Raw * 0.000000001160703041443256) + (0.07334532481221 * LNR * LNR * LNR) - (34.06632737942485 * LNR);
    ELSIF Type = 16 THEN %TAC ECU
      LNR:= LN(Raw);
      Value := (-273.15) + (1 / (0.00114944558407 + (0.0002941176088004037 * LNR) - (0.0000000000002525998855897292 * LNR* LNR* LNR)));

    ELSIF Type = 17 THEN %Satchwell DOT
      R2 := Raw*Raw;
      R3 := R2*Raw;
      IF Raw >= 7661 THEN
        Value :=  508885.1065949351 - (19.71706149035526 * Raw) + (0.001301247481832191 * R2) - (0.00000003594831664363352 * R3) - (3738912.809188366 / LN(Raw));
      ELSIF Raw >= 1193 THEN
        Value :=  (-128.4611061637296) - (0.007002012490937275 * Raw) + (0.0000006986512762901833 * R2) - (0.00000000006639391744752032 * R3) + (1529.490359465714 / LN(Raw));
      ELSE
        Value :=  (-339.6118638033802) + (0.09063945312481900 * Raw) - (0.00006415896542404209 * R2) + (0.00000001784096838726073 * R3) + (2639.015168861766 / LN(Raw));
      ENDIF;  
    ELSIF Type = 18 THEN %Satchwell DW1204 DWS1202
      R2 := Raw*Raw;
      R3 := R2*Raw;
      IF Raw >= 2236 THEN
        Value :=  39382.90132075548 - (6.021252248143583 * Raw) + (0.0013733544102798 * R2) - (0.0000001313622917888568 * R3) - (241223.6906016618 / LN(Raw));
      ELSIF Raw >= 974 THEN
        Value :=  (-888.2657030489725) + (0.1056691176426888 * Raw) - (0.00002987131417113171 * R2) + (0.000000002522599122874649 * R3) + (6271.371860366971 / LN(Raw));
      ELSE
        Value :=  (-9517.677682528738) + (4.164299211339042 * Raw) - (0.002604874308355931 * R2) + (0.0000006794599871065049 * R3) + (50956.91507092444 / LN(Raw));
      ENDIF;  
    ELSIF Type = 19 THEN %Satchwell DO2202
      R2 := Raw*Raw;
      R3 := R2*Raw;
      Value :=  (-1021.199118881201) + (0.04569968689660045 * Raw) + (0.00002069764420667956 * R2) - (0.00000000981645089002807 * R3) + (6869.504979681983 / LN(Raw));
    ELSIF Type = 20 THEN %IVT
      LNR:= LN(Raw);
      Value := (-273.15) + (1 / (0.001311184263438729 + (0.0002338997792885658 * LNR) + (0.0000001077046283506101 * LNR * LNR * LNR)));
    ELSIF Type = 21 THEN %NIBE
      LNR:= LN(Raw);
      Value := (-273.15) + (1 / (0.001387800349275742 + (0.0002400761437010071 * LNR) + (0.00000008613539226217632 * LNR * LNR * LNR)));
    ELSIF Type = 22 THEN %KTY 10/7
      R2 := Raw*Raw;
      R3 := R2*Raw;
      Value :=  311.5439406854249 + (0.04844211701143084 * Raw) - (0.000002908837846165819 * R2) + (0.0000000001362467604839759 * R3) - (2848.566087438425 / LN(Raw));
    ELSIF Type = 23 THEN %Bodendammen
      LNR:= LN(Raw);
      Value := (-273.15) + (1 / (0.001466426327478712 + (0.0002385193263772018 * LNR) + (0.0000001006014722395608 * LNR * LNR * LNR)));
    ELSIF Type = 24 THEN %T7043 Honywell
      LNR:= LN(Raw);
      Value := (-273.15) + (1 / (0.001705367599798446 + (0.0002527653342936799 * LNR) + (0.0000000005227580950721076 * LNR * LNR * LNR)));

    ELSE
      Value := Raw;
    ENDIF;  

    IF Input = 1 THEN
      UI2 := Value;
    ELSIF Input = 2 THEN
      UI3 := Value;
    ELSIF Input = 3 THEN
      UI4 := Value;
    ELSIF Input = 4 THEN
      UI5 := Value;
    ELSIF Input = 5 THEN
      UI6 := Value;
    ELSIF Input = 6 THEN
      UI7 := Value;
    ELSIF Input = 7 THEN
      UI8 := Value;
    ELSE
      UI1 := Value;
    ENDIF;
    Input := Input +1;
  END;
END;  


%Calls All_UI.CalcValue to calculate Universal input values
ROUTINE UpdateUI
BEGIN
  %One call for each input
  CALL All_UI.CalcValue;
  CALL All_UI.CalcValue;
  CALL All_UI.CalcValue;
  CALL All_UI.CalcValue;
  CALL All_UI.CalcValue;
  CALL All_UI.CalcValue;
  CALL All_UI.CalcValue;
  CALL All_UI.CalcValue;
END;

Användarnas noteringar

Du måste vara inloggad för att göra en notering. Bli medlem eller logga in. Vi använder en moderator som godkänner noteringarna innan de visas.