IMSE MxA12 (WMPro)

Detaljer

Typ
Drivrutin
Upplaggd av
Daniel Carlson, Abelko Innovation
Version
3
Uppdaterad
2018-05-21
Skapad
2016-11-02
Kategori
IO enheter, Modbus
Visningar
2722

Beskrivning

Typdefinition för Abelkos expansionsmodul MxA12 som ingår IMSE-familjen. Detta skript används då modulen kopplas som en modbus-enhet till en WMPro.
Modulen har 8 universalingångar och 4 analoga 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. val av fast resistansområde.

Skriptet är uppdelat i två separata enheter (p.g.a. begränsningar av antalet publika variabler och parametrar i en WMPro):

MxA12_AO (TYPEID 21480)
- Styr analoga utgångar
- Status för manuellstyrning
- Ställ kommunikationstimeout

ExM28_UI (TYPEID 21481)
- 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 MxA12
%
% 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)
%

DEVICETYPE MxA12_AO NAMED "MxA12_AO" TYPEID 21480 IS  
  PARAMETER
    % Address of this unit
    Addr: "Address";
    
    % Communication timeout
    ComTimeout: "ComTimeout"; 

    % Analog output
    AO1: "AO1";
    AO2: "AO2";
    AO3: "AO3";
    AO4: "AO4";
      
  PUBLIC
    % AO Override
    AO1_Overridden : "AO1 Man. overr.";      
    AO2_Overridden : "AO2 Man. overr.";      
    AO3_Overridden : "AO3 Man. overr.";      
    AO4_Overridden : "AO4 Man. overr.";      
    
  PRIVATE
    Tmp;
    Tmp2;
    
  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(33);     % 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(33);
  
    TIMEOUT 300
  END;

  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(42);     % Start register
      DATA[4]  := RWORD(8);      % Number of registers to write
      DATA[6]  := BYTE(16);      % 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;);

    ANSWER SIZE 8
      DATA[0] = BYTE(Addr);
      DATA[1] = BYTE(16);
      DATA[2] = BYTE(0);
      DATA[3] = BYTE(42);
      DATA[4] = BYTE(0);
      DATA[5] = BYTE(8);

    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(25);     % 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(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;);

    TIMEOUT 300
  END;
END;

DEVICETYPE MxA12_UI NAMED "MxA12_UI" TYPEID 21481 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(34);    % 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 UI2_Type > 3 THEN DATA := 0; ELSE DATA := UI2_Type * 64; ENDIF;);
      DATA[11] <- RWORD(IF UI3_Type > 3 THEN DATA := 0; ELSE DATA := UI3_Type * 64; ENDIF;);
      DATA[13] <- RWORD(IF UI4_Type > 3 THEN DATA := 0; ELSE DATA := UI4_Type * 64; ENDIF;);
      DATA[15] <- RWORD(IF UI5_Type > 3 THEN DATA := 0; ELSE DATA := UI5_Type * 64; ENDIF;);
      DATA[17] <- RWORD(IF UI6_Type > 3 THEN DATA := 0; ELSE DATA := UI6_Type * 64; ENDIF;);
      DATA[19] <- RWORD(IF UI7_Type > 3 THEN DATA := 0; ELSE DATA := UI7_Type * 64; ENDIF;);
      DATA[21] <- RWORD(IF UI8_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(34);
      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(1);      % 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(17);     % 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 21481 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.