www.brix.de - Hauptseite » Elektrotechnik » Heimautomation » SX_Mofloko|
Stand: 2025-01-10
|
|
In Industrieanwendungen besteht die Sensorik meist aus Näherungsschalter, Lichtschranken und Reed-Kontakten. Was davon ist für Hausautomatisierung mit einer SPS sinnvoll zu verwenden? Und gibt es günstige Bewegungsmelder für 24 V? - Im Folgenden sollen diese Fragen, aber grundsätzliche Überlegungen bei der Heimautomation erörtert werden.
(*****************************************************************************************
** **
** Copyright (C) 2021 Stefan Brix **
** All Rights Reserved Lohenstrasse 2 **
** 38300 Wolfenbuettel **
** sx@brix.de **
** **
******************************************************************************************
** **
** Aenderungsjournal **
**--------------------------------------------------------------------------------------**
** Datum Version Autor Beschreibung **
**--------------------------------------------------------------------------------------**
** 2022-03-14 1.0 Brix erste Version **
** 2023-04-09 1.1 Brix Cfg ergaenzt, **
** Kommentare ueberarbeitet, **
** Zeit fuer Sensorbetaetigung ergaenzt **
** 2023-12-12 1.2 Brix Visuwerte und Sammelstatus ergaenzt, **
** Variablennamen ueberarbeitet **
*****************************************************************************************)
FUNCTION_BLOCK FB_Mofloko_20 // FB 103 - muss in der Symboltabelle deklariert sein!
TITLE = 'Version 1.2.0' // --> Kommentarspalte
VERSION : '1.2' // x.y mit x und y in [0..15] of INT (fuehrende 0 werden ignoriert)
AUTHOR : BRIX_S // max. 8 Zeichen, A-Z, a-z, 0-9, _
NAME : Moflo_20 // max. 8 Zeichen, A-Z, a-z, 0-9, _
FAMILY : Mofloko // max. 8 Zeichen, A-Z, a-z, 0-9, _
VAR_INPUT // "IN" - Input --> Instanz-DB
IN_xTaster : BOOL ; // menschlich betaetigter Taster
IN_xSensor : BOOL ; // Sensor, z.B. Bewegungsmelder
IN_xSensor_aktiv : BOOL ; // Sensoreingang aktiv schalten
IN_xSet : BOOL ; // Ausgang EINschalten
IN_xReset : BOOL ; // Ausgang AUSschalten
Cfg : WORD; // Konfigurationswort
_Cfg AT Cfg : STRUCT
X8 : BOOL;
X9 : BOOL;
X10 : BOOL;
X11 : BOOL;
X12 : BOOL;
X13 : BOOL;
X14 : BOOL;
X15 : BOOL;
X0 : BOOL;
X1 : BOOL;
X2 : BOOL;
X3 : BOOL;
X4 : BOOL;
X5 : BOOL;
X6 : BOOL;
X7 : BOOL;
END_STRUCT;
IN_tKurz : TIME ; // kurze Einschaltdauer bei kurzer Tasterbetaetigung
IN_tLang : TIME ; // lange Einschaltdauer bei langer Tasterbetaetigung
IN_tSensor : TIME ; // Einschaltdauer bei Sensorausloesung
IN_tUmLang : TIME ; // Betaetigungszeit fuer Umschalten auf lange Einschaltdauer
IN_xReset_Count : BOOL ; // Schaltspielzaehler ruecksetzen
END_VAR // "IN" - Input
VAR_OUTPUT // "OUT" - Output --> Instanz-DB
OUT_xLicht_1 : BOOL ; // der eigentliche Ausgang
OUT_xLicht_2 : BOOL ; // der eigentliche Ausgang
OUT_xLicht_3 : BOOL ; // der eigentliche Ausgang
OUT_xLang : BOOL ; // Lange Zeit aktiv
OUT_tLicht : TIME ; // Einschaltdauer, gesamt (seit Initialisierung des Instanz-DB)
OUT_diLicht AT
OUT_tLicht : DINT ; // Einschaltdauer, gesamt (seit Initialisierung des Instanz-DB)
OUT_diLicht_h : DINT ; // Einschaltdauer, gesamt, Stunden
OUT_diLicht_min : DINT ; // Einschaltdauer, gesamt, Minuten
OUT_iLicht : INT ; // Anzahl Schaltspiele Lichtausgang
OUT_iSensor : INT ; // Anzahl Schaltspiele Sensoreingang
OUT_tRestzeit : TIME ; // Restzeit bis Licht aus
OUT_bVisuwerte : BYTE ; // Visuwerte
END_VAR // "OUT" - Output
VAR_IN_OUT // "IN_OUT" - Input/Output
IN_OUT_bSStatus : BYTE ; // Sammelstatus: Aktiv/Stoerung
END_VAR // "OUT" - Output
VAR // "STAT" - Statische Daten --> Instanz-DB
xTaster_flp : BOOL ; // positive Signalflanke
xTaster_fln : BOOL ; // negative Signalflanke
xTaster_alt : BOOL ; // Signalzustand aus vorherigem Zyklus
xSensor_flp : BOOL ; // positive Signalflanke
xSensor_fln : BOOL ; // negative Signalflanke
xSensor_alt : BOOL ; // Signalzustand aus vorherigem Zyklus
xSensor_flp_akt : BOOL ; // aktiv UND positive Signalflanke
xSensor_fln_akt : BOOL ; // aktiv UND negative Signalflanke
xUmLang : BOOL ; // Umschaltsignal fuer lange Zeit
xUmLang_flp : BOOL ; // positive Signalflanke
xUmLang_alt : BOOL ; // Signalzustand aus vorherigem Zyklus
xAus_vormerken : BOOL ; // ???
xAus : BOOL ; // ???
xLicht_vormerken : BOOL ; // ???
xLeuchtzeit_ein : BOOL ; // ???
xLicht_flp : BOOL ; // positive Signalflanke des eigentliche Ausgang
xLicht_alt : BOOL ; // Signalzustand aus vorherigem Zyklus
xStoe : BOOL ; // Sammelstoerung
tLeuchtzeit : TIME ; // die tatsaechlich gewaehlte Leuchtdauer
tAbgel_Zeit : TIME ; // bereits abgelaufene Zeit des Timers
TOF_Leuchtzeit : TOF ;
TON_UmLang : TON ;
bSammelStatus : BYTE; // Statusbyte Sammelstatus Visu
xSammelStatus
AT bSammelStatus : ARRAY[0..7] OF BOOL ;
bVisuwerte : BYTE ; // Visuwerte
xVisuwerte
AT bVisuwerte : ARRAY[0..7] OF BOOL ;
END_VAR // "STAT" - Statische Daten
VAR_TEMP // "TEMP" - Temporaere Daten --> Stack (Speicherbereich im RAM der SPS)
xCfg_0 : BOOL; // Reserve
xCfg_1 : BOOL; // Reserve
xCfg_2 : BOOL; // Reserve
xCfg_3 : BOOL; // Reserve
xCfg_4 : BOOL; // Reserve
xCfg_5 : BOOL; // Reserve
xCfg_6 : BOOL; // Reserve
xCfg_7 : BOOL; // Reserve
xCfg_8 : BOOL; // Reserve
END_VAR // "TEMP" - Temporaere Daten
(********************************* Programmbeginn ***************************************)
(*Konfigurationsbits auswerten*)
xCfg_0 := _Cfg.X0; // Reserve
xCfg_1 := _Cfg.X1; // Auch dann Ausschalten, wenn Sensor noch aktiv, Sensor schaltet erst mit naechster Flanke wieder ein
xCfg_2 := _Cfg.X2; // Reserve
xCfg_3 := _Cfg.X3; // Reserve
xCfg_4 := _Cfg.X4; // Reserve
xCfg_5 := _Cfg.X5; // Reserve
xCfg_6 := _Cfg.X6; // Reserve
xCfg_7 := _Cfg.X7; // Reserve
xCfg_8 := _Cfg.X8; // Reserve
// Signalflanken bilden
xTaster_flp := NOT xTaster_alt AND IN_xTaster ;
xTaster_fln := xTaster_alt AND NOT IN_xTaster ;
xTaster_alt := IN_xTaster ;
xSensor_flp := NOT xSensor_alt AND IN_xSensor ;
xSensor_fln := xSensor_alt AND NOT IN_xSensor ;
xSensor_alt := IN_xSensor ;
xSensor_flp_akt := xSensor_flp AND IN_xSensor_aktiv ;
xSensor_fln_akt := xSensor_fln AND IN_xSensor_aktiv ;
xUmLang_flp := NOT xUmLang_alt AND xUmLang ;
xUmLang_alt := xUmLang ;
(* Das Laden der Zeiten fuer die Ausschaltverzoegerung hat seinen Grund vor allem
im nicht vorhandenen Reset-Eingang des TOF-IEC-Timers! - Eine Zeit "0" am PT
loescht die Ausschaltverzoegerung sofort und ist die einzige Moeglichkeit diese
abzubrechen. *)
(* kurze Zeit waehlen *)
IF xTaster_flp THEN
tLeuchtzeit := IN_tKurz ;
OUT_xLang := FALSE ;
END_IF;
(* lange Zeit waehlen
entsprechend vorherigem NW, aber fuer die lange Zeit, getriggert vom Signal aus
der Einschaltverzoegerung fuer die Umschaltzeit. *)
IF xUmLang_flp THEN
tLeuchtzeit := IN_tLang ;
OUT_xLang := TRUE ;
END_IF;
(* Zeit fuer Sensorbetaetigung waehlen
entsprechend vorherigem NW, aber fuer die lange Zeit, getriggert vom Sensor-Signal. *)
IF xSensor_flp_akt AND NOT OUT_xLicht_1 THEN
tLeuchtzeit := IN_tSensor ;
END_IF;
// TOF fuer vorher gewaehlte Leuchtzeit (DIE Ausschaltverzoegerung)
TOF_Leuchtzeit (IN := xTaster_flp OR (IN_xSensor AND IN_xSensor_aktiv),
PT := tLeuchtzeit) ;
xLeuchtzeit_ein := TOF_Leuchtzeit.Q ;
tAbgel_Zeit := TOF_Leuchtzeit.ET ;
(* Ausschalten oder retriggern, um die lange Zeit einzuschalten?
"aus"-Merker wird gesetzt, wenn eine positive Flanke am Taster erscheint und
das Licht bereits an ist.
Warum?
Wird der Taster betaetigt, wenn das Licht aus ist, so wird eingeschaltet (also
nicht "aus").
Wird der Taster betaetigt, wenn das Licht ein ist, so wird ausgeschaltet,
solange
der Taster losgelassen wird, waehrend die Umschaltzeit nicht erreicht wird
(naechstes Netzwerk). Ansonsten wird (ohne Auszuschalten) in die lange Zeit
gewechselt.
ACHTUNG!
Die Bildung von "um" erfolgt mit Status des Tasters, muss also NACH diesem
Netzwerk erfolgen, sonst fallen die negative Flanke des Tasters und NICHT-"um"
immer in einen Zyklus! *)
IF xTaster_flp AND OUT_xLicht_1 AND NOT (IN_xSensor AND IN_xSensor_aktiv AND NOT xCfg_1) THEN
xAus_vormerken := TRUE ;
ELSIF xTaster_flp AND NOT OUT_xLicht_1 THEN
xAus_vormerken := FALSE ;
END_IF;
xAus := xAus_vormerken AND NOT xUmLang AND xTaster_fln ;
(* Die Zuweisung fuer den einzigen, entscheidenden Ausgang:
Das Licht wird durch das Druecken des Tasters eingeschaltet.
Ausgeschaltet wird es durch die abgelaufene Leuchtzeit oder das vorher
generierte "aus"-Signal oder durch "Reset". *)
IF (xTaster_flp OR xSensor_flp_akt OR IN_xSet) AND NOT IN_xReset THEN
xLicht_vormerken := TRUE ;
ELSIF ((xAus OR NOT xLeuchtzeit_ein) AND NOT IN_xSet) OR IN_xReset THEN
xLicht_vormerken := FALSE ;
END_IF;
OUT_xLicht_1 := xLicht_vormerken ;
OUT_xLicht_2 := xLicht_vormerken ;
OUT_xLicht_3 := xLicht_vormerken ;
xLicht_flp := NOT xLicht_alt AND OUT_xLicht_1 ;
xLicht_alt := OUT_xLicht_1 ;
(* Wird das Licht ausgeschaltet, wae;hrend die Leuchtzeit noch nicht abgelaufen ist
(durch das mit "aus" erzeugte Signal), wuerde der Timer intern weiterlaufen,
weil TOF keinen Reset kennt. Daher loescht ein NICHT-leuchtendes Licht den Timer
durch Vorwahl der Laufzeit "0". *)
IF NOT OUT_xLicht_1 THEN
tLeuchtzeit := T#0MS ;
END_IF;
(* Der Taster muss laenger als die Umschaltzeit gedrueckt sein, damit die lange Zeit
aktiviert wird. *)
TON_UmLang (IN := IN_xTaster,
PT := IN_tUmLang) ;
xUmLang := TON_UmLang.Q ;
IF OUT_xLicht_1 AND M_Takt_01_000_Hz_Fl_pos THEN
OUT_tLicht := OUT_tLicht + T#1s ;
END_IF;
OUT_diLicht_h := OUT_diLicht DIV DINT#3600000 ;
OUT_diLicht_min := OUT_diLicht MOD DINT#3600000 ;
OUT_diLicht_min := OUT_diLicht DIV DINT#60000 ;
IF xLicht_flp THEN
OUT_iLicht := OUT_iLicht + 1 ;
END_IF;
IF xSensor_flp THEN
OUT_iSensor := OUT_iSensor + 1 ;
END_IF;
IF IN_xReset_Count THEN
OUT_iLicht := 0 ;
OUT_iSensor := 0 ;
END_IF;
OUT_tRestzeit := tLeuchtzeit - tAbgel_Zeit ;
// Visu-Signale zuweisen
bSammelStatus := IN_OUT_bSStatus ;
IF OUT_xLicht_1 THEN
xSammelStatus[0] := TRUE ;
END_IF ;
xSammelStatus[7] := xSammelStatus[7] OR xStoe ;
IN_OUT_bSStatus := bSammelStatus ;
xVisuwerte[1] := OUT_xLicht_1 ;
xVisuwerte[2] := OUT_xLicht_1 AND OUT_xLang ;
xVisuwerte[7] := IN_xTaster ;
OUT_bVisuwerte := bVisuwerte;
(*--------------------------------------------------------------------------------------*)
(********************************** Programmende ****************************************)
END_FUNCTION_BLOCK
PIR-Bwegungsmelder sind nicht besonders genau in der Erfassung und daher schwierig einzustellen. Radarsensoren sind wesentlich besser, auch Lichtschranken tun gute Dienste. Da experimentiere ich noch. Türen werden mit Näherungsschalter als offen oder geschlossen erkannt. Für die Vorratskammer tut es genau so eine Türauslösung und das Ganze fühlt sich wie ein Kühlschranklicht an.
|
Was macht |