IpcDiagnostics_2

Dieses Beispiel ähnelt stark dem Beispiel IpcDiagnostics und unterscheidet sich lediglich durch eine andere Variante der Implementierung sowie dem optionalen Schreiben eines Parameters.

Der Aufbau des Programms ist so gestaltet, dass das Programm leicht für den Zugriff auf andere Parameter der IPC-Diagnose angepasst werden kann.

Enumerationsdefinition

{attribute 'qualified_only'}
TYPE E_State :
(
    Init,
    Idle,
    ReadOnce_CpuUsage,
    ReadOnce_CpuTemperature,
    ReadOnce_SrnMainboard,
    ReadOnce_SrnIPC,
    Write_DHCP,
    Write_IPAddr,
    ReadPeriodically,
    Error
);
END_TYPE

Variablendeklaration

PROGRAM MAIN
VAR
    bStart                 : BOOL := TRUE;           // flag to trigger (re)start of statemachine
    bSkipSettingIPAddr     : BOOL := TRUE;           // for safety reasons - set FALSE if you want to set the IP address
    eState                 : E_State := E_State.Init;
    
    bError                 : BOOL;                   // error flag (indicator: error occured)
    hrErrorCode            : HRESULT;                // last error code
    hrGetValue             : HRESULT;
    
    nCpuUsage              : UINT;                   // CPU usage [%]
    nCpuTemperature        : INT;                    // CPU temerature [°C]
    sSerialNumberMainboard : STRING;                 // serial number of mainboard
    sSerialNumberIPC       : STRING;                 // serial number of IPC
    nNicModuleIdx          : USINT := 1;             // select which NIC adapter should be adapted with a new IP address
    bDHCP                  : BOOL := FALSE;
    sIPAddr                : T_IPv4Addr := '174.18.3.154'; // the new ip address 
    aFanSpeed              : ARRAY[1..2] OF UINT;    // speed of fans - should be read periodically
    
    fbDiagRegister         : FB_IPCDiag_Register := (sNetId:=cNetId);
    fbDiagRead             : FB_IPCDiag_ReadParameter := (sNetId:=cNetId);
    fbDiagReadPeriodic     : FB_IPCDiag_ReadParameterPeriodic := (tPeriod:= T#10S, sNetId:=cNetId);
    fbDiagWrite            : FB_IPCDiag_WriteParameter := (sNetId:=cNetId);
END_VAR
VAR CONSTANT
    cNetId : T_AmsNetID := ''; // local
END_VAR

Initialisierung

E_State.Init:
    IF NOT fbDiagRegister.bBusy THEN
        fbDiagRegister(bExecute:=TRUE);
    ELSE
        fbDiagRegister(bExecute:=FALSE, bError=>bError, hrErrorCode=>hrErrorCode);
    END_IF
    IF NOT fbDiagRegister.bBusy THEN
        IF fbDiagRegister.bError THEN
            eState := E_State.Error;
        ELSE
            eState := E_State.Idle;
        END_IF
    END_IF

Einfache Abfrage eines Parameters (hier am Beispiel der CPU-Temperatur)

E_State.ReadOnce_CpuTemperature:
    IF NOT fbDiagRead.bBusy THEN
        fbDiagRead(bExecute:= TRUE, eParameterKey:=E_IPCDiag_ParameterKey.CPU_Temp, fbRegister:=fbDiagRegister);    
    ELSE
        fbDiagRead(bExecute:= FALSE, fbRegister:=fbDiagRegister, bError=>bError, hrErrorCode=>hrErrorCode);
    END_IF
    IF NOT fbDiagRead.bBusy THEN
        IF fbDiagRead.bError THEN
            eState := E_State.Error;
        ELSE // get value
            hrGetValue := fbDiagRead.GetParameter(pBuffer:=ADR(nCpuTemperature), nBufferSize:=SIZEOF(nCpuTemperature));    
            IF FAILED(hrGetValue) THEN
                eState := E_State.Error;
            ELSE
                eState := E_State.ReadOnce_SrnMainboard;
            END_IF
        END_IF
    END_IF        

Schreiben eines Parameters (hier am Beispiel der IP-Adresse)

E_State.Write_IPAddr:
    IF NOT fbDiagWrite.bBusy THEN
        fbDiagWrite(bExecute:= TRUE, 
                    eParameterKey:=E_IPCDiag_ParameterKey.NIC_IPv4Address,
                    pBuffer:=ADR(sIPAddr),
                    nBufferSize:=INT_TO_UDINT(LEN(sIPAddr)+1),
                    nModuleIdx:=nNicModuleIdx,
                    fbRegister:=fbDiagRegister );    
    ELSE
        fbDiagWrite(bExecute:= FALSE, fbRegister:=fbDiagRegister, bError=>bError, hrErrorCode=>hrErrorCode);
    END_IF
    IF NOT fbDiagWrite.bBusy THEN
        IF fbDiagWrite.bError THEN
            eState := E_State.Error;
        ELSE
            eState := E_State.ReadPeriodically;
        END_IF
    END_IF

Periodische Abfrage eines Parameters (hier am Beispiel der Lüfterdrehzahl)

E_State.ReadPeriodically:
    fbDiagReadPeriodic(bEnable:=TRUE, eParameterKey:=E_IPCDiag_ParameterKey.Fan_Speed, fbRegister:=fbDiagRegister,
                       bError=>bError, hrErrorCode=>hrErrorCode);
    IF fbDiagReadPeriodic.bValid THEN
        fbDiagReadPeriodic.GetParameter(pBuffer:=ADR(aFanSpeed), nBufferSize:=SIZEOF(aFanSpeed) );    
    END_IF
    IF fbDiagReadPeriodic.bError THEN
        eState := E_State.Error;
    END_IF