# KNX FbDPT in einem Funktionsblock implementieren



## Player-Ben (31 Januar 2021)

Liebe SPS-Gemeinde,

ich versuche seit ein paar Stunden mir einen Funktionsblock zu basteln, welcher mit einem Taster (angeschlossen an die SPS), einem KNX-Taster und der Gira X1 Visu funktioniert. Grundsätzlich ist das Problem, dass die Visu den Zustand des Lichts nur bei der Funktion „Umschalten“ anzeigt und dieses über die SPS realisiert werden musste. Das klappt soweit auch alles ganz gut. Nun zu meinem Hindernis:

Der Funktionsblock enthält aktuell den benötigten KNX-Datenpunkt als Globale Variable, dieses würde ich gerne umgehen.

Gibt es die Möglichkeit den Datenpunkt dem Funktionsblock zu übergeben (Innerhalb des Programms) oder wäre die Sache mit dem DPT-Baustein-Array die schickere Lösung. Letzteres habe ich schon versucht, leider ohne Erfolg.

Freue mich auf ein paar Ideen.
Viele Grüße
Ben

```
FUNCTION_BLOCK FBLatchedRelayKNX
VAR_INPUT
    xButton                :BOOL;        (*Button for switching        || Tastsignal *)                    (*PAR_OP*)
    xCentralOn            :BOOL;        (*central on                || Zentral EIN *)                (*PAR_OP*)
    xCentralOff            :BOOL;        (*central off                || Zentral AUS *)                (*PAR_OP*)
    KNX                    :BOOL;        (*Schaltsignal von der Gruppenadresse*)
    bKNX_Master            :BYTE:=1;
    dwIndex_DPT            :DWORD;
    iActuator                :BOOL;

END_VAR
VAR_INPUT CONSTANT
    T_on_max                :TIME := T#0s; (*Wird nach der Zeit automatisch abgeschaltet*)
END_VAR
VAR_OUTPUT
    oActuator                :BOOL;         (*Digital signal for relay    || Ausgangsschaltsignal *)    (*physical output L*)
END_VAR
VAR
    status:                                BOOL:=FALSE;
    FBTOF:                            TOF;
    FTrigButton                        :F_TRIGER;
    RTrigButton                        :R_TRIGER;
    FTrigExtern                        :F_TRIGER;
    RTrigExtern                        :R_TRIGER;
    T_on                                :TIME;
    tx                                    :TIME;
    (*DPT_Switch01                    :FbDPT_Switch;*)
    typDPT                                : typDPT;
    init                                    :BOOL:=TRUE;

END_VAR
----------------------------------------------------------------------------
(*IF init THEN
    init:=FALSE;
    DPT01( xSwitch_IN:=oActuator , dwIndex_DPT:=dwIndex_DPT , bKNX_Master:=bKNX_Master , typDPT:=typDPT );
    IF dwIndex_DPT>0 THEN
        dwIndex_DPT:=dwIndex_DPT*1000+0;
    END_IF
ELSE
    DPT_Switch01( dwIndex_DPT:=dwIndex_DPT , bKNX_Master:=bKNX_Master , typDPT:=typDPT );
END_IF
*)
X1_seg_01_01( bKNX_Master:=bKNX_Master );
tx := DT_TO_TIME(SysRtcGetTime(TRUE)); (* systemzeit zum Startpunkt setzten für auto abschaltung*)

RTrigButton();
RTrigExtern();
FTrigExtern();

RTrigButton.CLK:=xButton;

IF X1_seg_01_01.xUpdate_PLC  THEN
    oActuator:=X1_seg_01_01.xSwitch_OUT;
ELSIF RTrigButton.Q THEN
    IF NOT iActuator THEN
        oActuator:=TRUE;
    ELSIF iActuator THEN
        oActuator:=FALSE;
    END_IF;
ELSE
    X1_seg_01_01.xSwitch_IN:=iActuator;
END_IF
```

*Aufruf im Programm:*


```
Programm KNX
VAR
X1_test                                    :FBLatchedRelayKNX;
END_VAR
----------------------------------------------------------------------------
X1_test(xButton:=seg01_1 OR test_Guest ,iActuator:=deg01,dwIndex_DPT:=3,oActuator=>deg01);
```

*Deklaration der Globalen Variablen:
*

```
X1_seg_01_01                            :FbDPT_Switch;(*Virtueller Schalter Gästezimmer*)
```


----------



## .:WAGO::011726:. (4 Februar 2021)

Hallo Player-Ben,

Um sich eigene Funktionsbausteine zu schreiben die auch KNX Datenpunkte (und somit die FbDPT_xxx Bausteine) enthalten gibt es eine Möglichkeit. Diese ist auch in dem Anwendungshinweis zur KNX_02-Bibliothek beschrieben: https://www.wago.com/de/d/3102

Der Trick ist, dass der dwIndex über ein Faktor und ein Offset in dein Baustein Inneres geholt wird (dwIndex_intern = dwIndex_außen*1000000+1000). Benötigts du mehrere KNX-Bausteine intern so wird die dwIndex_intern Variabel einfach für jeden weiteren Baustein um 1000 erhöht. Anbei die Bilder aus dem Anwendungshinweis. 









Damit solltest du dein Fb erstellen können.


----------



## Player-Ben (5 Februar 2021)

Danke für die Info:
Mein Baustein sieht folgendermaßen aus:

*Funktionsbaustein*:

```
FUNCTION_BLOCK  KNXDPT

VAR_INPUT
    xSwitch_IN                : BOOL;
    dwIndex_DPT                : DWORD;
    bKNX_Master                : BYTE;
END_VAR

VAR_OUTPUT
    xSwitch_0_OUT            : BOOL;
END_VAR

VAR
    _02_ArraySwitchOUT        : FbDPT_Switch;


END_VAR
---------------------------------------------------------------------------------------
_02_ArraySwitchOUT( dwIndex_DPT:= dwIndex_DPT*1000000+1000, bKNX_Master:= bKNX_Master );

xSwitch_0_OUT:=_02_ArraySwitchOUT.xSwitch_OUT;;
```
Aufruf im Hauptprogramm:

```
M1_002_TestDPT                                :KNXDPT;

----------------------------------------------------------------------------------------------
M1_002_TestDPT(bKNX_Master:=1,dwIndex_DPT:=2,xSwitch_0_OUT=>Test_DPT);
```


Leider empfängt der Baustein keine Telegramme aus dem Bus, die Variabel Test_DPT wird nicht gesetzt.

*EDIT*:
_02_ArraySwitchOUT        : FbDPT_Switch; Hier muss mit 1 begonnen werden...-->_01_ArraySwitchOUT


----------



## Methi (5 Februar 2021)

Hast du in deinem Programm auch einen FB FbKNX_Master und rufst du diesen mit den richtigen Parametern zu Beginn auf?
In deinem ersten Post ist dies nicht zu erkennen.


----------



## Player-Ben (5 Februar 2021)

genau im Hauptprogramm muss immer einemal der Master aufgerufen werden, damit das Programm weiß. dass es die KNX-Klemme gibt.
ungefähr so:

```
KNX_Master(bKNX_Master:= 1, eStatusKNX=> Status, xProg_Mode=> , dwCRC=> );(*Aufruf Masterklemme*)
```

Und dann kommt in das selbe Programm der Aufruf der Funktionsblöcke von oben.


----------



## Methi (5 Februar 2021)

Was hat der KNX Master denn als Status, wenn das Programm läuft (nachdem senden eines KNX Telegrams, also bspw. Nach Tastendruck)


----------



## .:WAGO::011726:. (5 Februar 2021)

Hallo Player-Ben,

is zwar eigentlich schon Feierabend, aber deine Frage hat mich noch beschäftigt .  Und damit du am WE tätig werden kannst, hab ich dein Programm mal ausprobiert.

Der Fehler steckt in dem inneren Bausteinnamen. Laut Kapitel 8.1.4 des AH müssen die inneren Bausteine zweistellig durchnummeriert werden. Dabei muss mit der _01_ angefangen werden. Du hast dein Baustein aber "_02_ArraySwitchOUT" genannt. Also entweder in "_01_ArraySwitchOUT" umbenennen oder noch ein Baustein davor setzen.


----------



## Player-Ben (5 Februar 2021)

.:WAGO::011726:. schrieb:


> Hallo Player-Ben,
> .... Du hast dein Baustein aber "_02_ArraySwitchOUT" genannt. Also entweder in "_01_ArraySwitchOUT" umbenennen oder noch ein Baustein davor setzen.


Besten Dank, genau das war das Problem und vielen Dank für den guten Support hier im Forum.



Methi schrieb:


> Was hat der KNX Master denn als Status, wenn das  Programm läuft (nachdem senden eines KNX Telegrams, also bspw. Nach  Tastendruck)



Der Status ist eine Variabel vom Typ: :eStatusKNX; In diese schreibt der Funktionsblock der Masterklemme seinen Status, ob auf der Seite des KNX-Bus alles funktioniert. Wenn KNX_OK im Status steht, dann ist alles in Ordnung und die Kommunikation zwischen Bus und Wago funktioniert. 
Der Status verändert sich nicht beim Senden und Empfangen von Telegrammen. 

Falls du ein konkretesProblem hast, es es vielleicht hilfreicher wenn Du es direkt beschreibst.

Auszug aus der KNX_02_de.pdf
Die Ausgangsvariable „eStatusKNX“ gibt Statusinformationen bezüglich der Klemmenkommunikation aus.
Mögliche Zustände:
KNX_NOT_INIT
KNX_OK
KNX_TX_CHECKSUM
KNX_NO_DEVICE_MODUS
KNX_TimeOutSend
KNX_TimeOutReceive
KNX_TimeOutSYNC
KNX_COM_ERROR
KNX_POWER_FAILURE
KNX_ERROR_MODULE
KNX_SYNC
KNX_CONFIG_FAILURE


----------



## Methi (6 Februar 2021)

Ich hab kein Problem, ich wollte dir helfen, den Fehler zu finden. Und in deinem Code konnte ich keinen finden (den Fehler _01_ statt _02_ hattest du oben im Edit ja schon lange als "korrigiert" angegeben, da bin ich davon ausgegangen, dass du dies auch getestet hast und dein Problem weiterhin besteht.)

Aber wenn es jetzt bei dir läuft, umso besser - ich habe damals auch lange mit verschachteltsten KNX-FB gekämpft.


----------



## Player-Ben (6 Februar 2021)

Dann war es wohl ein klassischer Fall, von Missverständnis.
Ich dachte du wolltest meinen Code nachbauen und hattest den Fehler mit dem Masterbaustein.
Dann danke für deine Hilfe.


----------

