Jalousiesteuerung

Begonnen von hugo, 18. Februar 2007, 18:19:48

Vorheriges Thema - Nächstes Thema

0 Mitglieder und 4 Gäste betrachten dieses Thema.

hugo

neues Moful Jalousiesteuerung soll kommen:

- Sonnenstandsgeführte Jalousiesteuerung (Sonnenstand wird berechnet)
- Interface für single und double Taster
- Nachtmodus / Tagmodus
- interface für Lichtsensor (Jalousie kann hochfahren wenn Himmel vollständig bewölkt und Beleuchtung gespart werden kann)

weitere Wünsche?

klaus313

vielleicht:

- Sicherheitsposition anfahren (und dort bleiben) -> fürs Fensterputzen :-)) und Windsensor
- Beschattungsposition (mit Lamellenverstellung) - siehe Beckhoff lib
- Berechnen und ausgeben der aktellen Position
- Anfahren einer bestimmten Position
- SelbstKalibrieren

gruß
Klaus

hugo

danke klaus,

es wird 2 analoge eingänge / ausgänge geben, die analogen eingänge dienen dazu aus szenen bausteinen stellungsinformationen zu erhalten, bzw die stellung die manuell angefahren wurde auszulesen.
wert 1 gibt die höhe der jalouse an, z.b. 50% geschlossen.
wert 2 gibt die stellung der lamellen an z.b. 100% geneigt.
die lamellenstellung hat weitere optionen
- option a sonnenstandsführung (die stellung der lamelle hängt vom sonnenstand ab
- option b automatisches öffnen der lamellen wenn der himmel vollständig bewölkt ist um beleuchtung zu sparen.
windsensor ja wird berücksichtigt auch für putzen, ist ein separater eingang der durch einen puls die jalousie 100% öffnet
ein 2ter eingang zu wird durch einen puls 100% geschlossen, z.b. nachtbeschattung um heizkosten zu sparen.
selbstkalibrierung ja.
eine totzeit zwischen umschaltung ab / auf ist einstellbar

hugo

jalousiesteuerung müssen wir leider auf die 1.6 verschieben, dann aber definitiv mit sonnenstandsabhängigkeit usw.

klaus313

Hallo Hugo,

was macht die Jalousiensteuerung? Hast du schon eine Beschreibung der Funktionen ?

danke :-)

Klaus

hugo

nein wir sind erzeit an vielen kleinen detail wie siemens kompatibilität usw. die jalosiesteuerung wird wohl anfang april kommen

swmggs

Hallo Hugo,

bin jetzt mal an der Kühlung meiner Hütte dran ( mit der Funktion Heizen ist im Moment ja Gottseidank mal Ruhe) und bastle so mit vorhandenen Jalousiensteueungen rum (wie weit ist den eigentlich deiner ? ::) ::) ::)), aber da ich ja auch mit der Heizung rummache meinst Du nicht das bei einer Jalousiensteuerung ein sagen wir mal Heizen/Kühlen Eingang Sinn machen würde den im Sommer will ich Kühlen, Jalousie zu und im Winter dürfte die Sonne ruhig reinschauen und mir meinen Bauch wärmen und meinen Vitamin D Mangel wäre dann nicht so gross  ;D

mfg swmggs

hugo

ja das heizen kühlen über die jalosie macht wirklich sinn

ChristophB

Ich hätte noch einen Wunsch. Einen Eingang für einen Öffnungsmelder. Der Rolladen darf dann nicht runterfahren bzw. sollte dann stoppen. Und einen Eingang für Feueralarm wäre nicht schlecht. Wenn wir schon dabei sind: Ich möchte die Automatik (Rolladen auf,zu zum Sonnenschutz und in der Nacht) ein und ausschalten können. Per Visualisierung und per Tastendruck Auf/Ab gleichzeitg.

Christoph

hugo

ein wesentliches problem stellt die kalibrierung dar.
die position nund der winkel wird dadurch erreicht as auf die position runtergefahren wird und dann solange zurück bis der winkel steht.
die jalousie hat aber keinerlei endschalter denkbar wäre ein stromsensor, ist aber normalerweise nicht verfügbar.
hat jemand ideen wie die kalibrierung stattfinden soll? vor allem eine selbstkalibrierung.
speziell beim einstellen des winkel kann man ja auch keinen stromsensor benutzen weil die jalousie einfach nach dem winkelstellen hoch oder runterfährt.
wie unterschiedlich verhalten sich eigentlich jalousien. verhalten über die zeit, temperatur windgeschwindigkeit usw...
hat hier jemand weitere daten?

bitte gebt mir eure ideen?

SHendrik

Hallo.

Habe nun schon mehrere Monate an meiner Rollladensteuerung gespielt und programmiert.

Anbei mein FB als Info ...

in dieser Struktur speichere ich für jeden Rollladen die letzten Bewegungen mit Position und Zeit, je Wochentag + Betriebsstunden

TYPE tRolloConf:
  STRUCT
    iDemandTime:ARRAY[1..MAXROLLSP,1..MAX_DAY] OF TOD;
    iDemandPos:ARRAY[1..MAXROLLSP,1..MAX_DAY] OF INT;
    iDemandIndex:INT:=1;
    iBetrStunden:TIME;
    END_STRUCT
END_TYPE

über diese Struktur erhält man den Namen,Position und kann Automatikbefehle über Sollposition und bChangePosition schicken ..
der if_time Block, dient der Anwesenheitssimulation, die dann die gespeicherten Sollposition aus der oberen Struktur wieder anfährt ...

TYPE tRollo:
   STRUCT
      sName:STRING[20];
      iPosition:INT;
      PositionTime: TIME:= t#0s;
      SollPosition:INT;
      bChangePosition:BOOL;
      if_Time:ARRAY[1..MAXROLLSP] OF IfTime;
   END_STRUCT
END_TYPE

nun der FB ...

FUNCTION_BLOCK Rolladensteuerung
VAR_INPUT
    Taster_Roll_Hoch:BOOL;
    Taster_Roll_Runter:BOOL;
    Gruppe_Roll_Hoch:BOOL;
    Gruppe_Roll_Runter:BOOL;
    Beschattung:BOOL;
    Beschattung_Pos:INT;
    MaxTime: TIME;
   iRoll:INT;
    bExtern:BOOL;
END_VAR
VAR_OUTPUT
    Ausgang_Roll_Hoch:BOOL;
   Ausgang_Roll_Runter:BOOL;
   Position: INT:=0;
END_VAR
VAR

   Eingang_Roll_Hoch :BOOL;
   Eingang_Roll_Runter:BOOL;
   edge_hoch : BOOL;
   edge_runter : BOOL;
   edge_Taster_hoch : BOOL;
   edge_Taster_runter : BOOL;
   t_neu: TIME;
   t_last: TIME;
   t_taster_hoch_alt: TIME;
   t_taster_runter_alt: TIME;
   t_last_time_hoch: TIME;
   t_last_time_runter: TIME;
   t_alt: TIME;
   t_delta: TIME;
   postmp: DINT;
   up_time:IfTime;
   down_time:IfTime;
   bSwitchUpTime: BOOL;
   bSwitchDownTime: BOOL;

   ExternAktiv: BOOL;
   stmp: STRING;
   Index: INT;
   bHandbedienung: BOOL;
   day: INT;
   bCal: BOOL;
END_VAR

(*aktuelle Zeit holen*)
t_neu := TIME();

(*Löschen der Speicherdaten*)
IF ClearRollData=1 THEN
   Config.Rollos[iRoll].iBetrStunden:=T#0s;
   Config.Rollos[iRoll].iDemandIndex:=1;
   FOR day:=1 TO MAX_DAY DO
      FOR Index:=1 TO MAXROLLSP DO
         Config.Rollos[iRoll].iDemandTime[Index,day]:=TOD#00:00:00;
         Config.Rollos[iRoll].iDemandPos[Index,day]:=0;
      END_FOR
   END_FOR
END_IF

(*Verknüpfung des Einzel- u. Gruppeneingangs*)
Eingang_Roll_Hoch:=Taster_Roll_Hoch OR Gruppe_Roll_Hoch;
Eingang_Roll_Runter:=Taster_Roll_Runter OR Gruppe_Roll_Runter;

(*Eingangsabfrage Hoch*)
IF Eingang_Roll_Hoch AND NOT edge_taster_hoch THEN
   (*wenn gedrückt*)
   (*Automatik abbrechen*)
   ExternAktiv:=FALSE;
   edge_taster_hoch := TRUE;
   (*Zeit merken*)
   t_taster_hoch_alt:=t_neu;
ELSIF NOT Eingang_Roll_Hoch AND edge_taster_hoch THEN
   (*wenn losgelassen*)
   edge_taster_hoch := FALSE;
END_IF

(*Eingang Hoch wurde betätigt*)
IF edge_taster_hoch THEN
   (*Abfrage der Tastzeit*)
   IF t_neu-t_taster_hoch_alt>Config.Rollos_TastZeitKurz THEN
      (*Lange Tastzeit -> Automatik / Zeit merken*)
      (*Handbedienungsflag setzen -> keine Fenstertürkontaktprüfung*)
      bHandbedienung:=TRUE;
      Rollos[iRoll].bChangePosition:=TRUE;
      Rollos[iRoll].SollPosition:=0;
   END_IF
END_IF

(*Eingangsabfrage Runter*)
IF Eingang_Roll_Runter AND NOT edge_taster_runter THEN
   (*wenn gedrückt*)
   (*Automatik abbrechen*)
   ExternAktiv:=FALSE;
   edge_taster_runter := TRUE;
   t_taster_runter_alt:=t_neu;
ELSIF NOT Eingang_Roll_Runter AND edge_taster_runter THEN
   (*wenn losgelassen*)
   edge_taster_runter := FALSE;
END_IF

(*Eingang Runter wurde betätigt*)
IF edge_taster_runter THEN
   IF t_neu-t_taster_runter_alt>Config.Rollos_TastZeitKurz THEN
      (*Lange Tastzeit -> Automatik / Zeit merken*)
      bHandbedienung:=TRUE;
      Rollos[iRoll].bChangePosition:=TRUE;
      Rollos[iRoll].SollPosition:=100;
   END_IF
END_IF

(*Simulation*)
IF bSimulation=1 THEN
   FOR Index:=1 TO MAXROLLSP DO
      Rollos[iRoll].if_Time[Index](ActTime:=Times.dActualTime_TOD, SwitchTime:=Config.Rollos[iRoll].iDemandTime[Index,Times.weekday], bSwitchTime=>bSwitchUpTime);
      IF bSwitchUpTime=1 AND bSimulation THEN
         Rollos[iRoll].bChangePosition:=TRUE;
         Rollos[iRoll].SollPosition:=Config.Rollos[iRoll].iDemandPos[Index,Times.weekday];
         bHandbedienung:=TRUE;
      END_IF
   END_FOR
END_IF

(*Ausgang Hoch setzen*)
IF Eingang_Roll_Hoch=1 THEN
   Ausgang_Roll_Hoch:=TRUE;
   Ausgang_Roll_Runter:=FALSE;
(*Ausgang Runter setzen*)
ELSIF Eingang_Roll_Runter=1 THEN
   Ausgang_Roll_Hoch:=FALSE;
   Ausgang_Roll_Runter:=TRUE;
ELSE
   (*Ausgänge löschen*)
   Ausgang_Roll_Hoch:=FALSE;
   Ausgang_Roll_Runter:=FALSE;
END_IF

(*Beschattungsabfrage*)
IF Beschattung THEN
   IF ABS(Beschattung_Pos-Position)>1 THEN
      Rollos[iRoll].bChangePosition:=TRUE;
      Rollos[iRoll].SollPosition:=Beschattung_Pos;
      bHandbedienung:=TRUE;
   END_IF
END_IF

(*Externe Sollwertvorgabe*)
IF Rollos[iRoll].bChangePosition THEN
   Rollos[iRoll].bChangePosition:=FALSE;
   IF ABS(Rollos[iRoll].SollPosition-Position)>1 THEN
      (*Automatikbetriebsarten löschen*)
      (*Externaktiv Flag setzen*)
      ExternAktiv:=TRUE;
      IF Rollos[iRoll].SollPosition<Rollos[iRoll].iPosition THEN
         bHandbedienung:=TRUE;
      END_IF
      IF Rollos[iRoll].SollPosition=0 THEN
         bCal:=1;
      ELSE
         bCal:=0;
      END_IF
   END_IF
END_IF

(*Abfrage Externaktiv*)
IF ExternAktiv THEN
   IF bExtern=TRUE OR bHandbedienung=TRUE THEN
      (*Vergleich Soll-/Ist-Position*)
      IF ABS(Rollos[iRoll].SollPosition-Position)>=1 OR bCal THEN
         IF ABS(Rollos[iRoll].SollPosition-Position)<1 THEN
            IF t_neu-t_last>t#5s THEN
               bCal:=FALSE;
            END_IF
         ELSE
            t_last:=t_neu;
         END_IF
         (*Ausgang Runter setzen*)
         IF Rollos[iRoll].SollPosition>Position THEN
            Ausgang_Roll_Runter:=TRUE;
            Ausgang_Roll_Hoch:=FALSE;
                ELSE
            (*Ausgang Hoch setzen*)
            Ausgang_Roll_Hoch:=TRUE;
            Ausgang_Roll_Runter:=FALSE;
         END_IF;
      ELSE
         stmp:=CONCAT('->',INT_TO_STRING(Rollos[iRoll].SollPosition));
         stmp := CONCAT (Rollos[iRoll].sName,stmp);
         stmp := CONCAT ('Rolladen ',stmp);
         BDEMeldung(MeldungIn:=stmp);

         IF bSimulation=0 THEN
            Config.Rollos[iRoll].iDemandTime[Config.Rollos[iRoll].iDemandIndex,Times.weekday]:=Times.dActualTime_TOD;
            Config.Rollos[iRoll].iDemandPos[Config.Rollos[iRoll].iDemandIndex,Times.weekday]:=Rollos[iRoll].SollPosition;
            IF Config.Rollos[iRoll].iDemandIndex<MAXROLLSP THEN
               Config.Rollos[iRoll].iDemandIndex:=Config.Rollos[iRoll].iDemandIndex+1;
            ELSE
               Config.Rollos[iRoll].iDemandIndex:=1;
            END_IF
         END_IF
         (*wenn Position erreicht -> Beschattungaktiv auf 0*)
         bHandbedienung:=FALSE;
         ExternAktiv:=FALSE;
      END_IF
   ELSE
      ExternAktiv:=FALSE;
   END_IF
END_IF

(*Abfrage, wann letzter Runter Vorgang*)
IF Ausgang_Roll_Hoch THEN
   (*Ausgang Hoch für Zeit sperren*)
   IF t_neu-t_last_time_Runter<Config.Rollos_PauseAufAb THEN
      Ausgang_Roll_Hoch:=FALSE;
   END_IF
   t_last_time_Hoch:=t_neu;
END_IF

(*Abfrage, wann letzter Hoch Vorgang*)
IF Ausgang_Roll_Runter THEN
   (*Ausgang Runter für Zeit sperren*)
   IF t_neu-t_last_time_Hoch<Config.Rollos_PauseAufAb THEN
      Ausgang_Roll_Runter:=FALSE;
   END_IF
   t_last_time_Runter:=t_neu;
END_IF

(*Sicherheitsabfrage, damit nicht beide Ausgänge geschaltet*)
IF Ausgang_Roll_Hoch=1 THEN
   IF  Ausgang_Roll_Runter=1 THEN
      Ausgang_Roll_Hoch:=FALSE;
      Ausgang_Roll_Runter:=FALSE;
   END_IF;
END_IF;

(*Betriebsstunden hochzählen*)
IF Ausgang_Roll_Runter OR Ausgang_Roll_Hoch THEN
      Config.Rollos[iRoll].iBetrStunden:=Config.Rollos[iRoll].iBetrStunden+t_neu-t_alt;
END_IF

(*Abfrage ob Ausgang zugeschaltet*)
IF Ausgang_Roll_Hoch AND NOT edge_hoch THEN
   edge_hoch := TRUE;
ELSIF NOT Ausgang_Roll_Hoch AND edge_hoch THEN
   edge_hoch := FALSE;
END_IF

(*Abfrage ob Ausgang zugeschaltet*)
IF edge_hoch THEN
   t_delta:=t_neu-t_alt;
   (*Berechnung neuer Bestrommungszeit*)
   Rollos[iRoll].PositionTime:=Rollos[iRoll].PositionTime-REAL_TO_TIME(TIME_TO_REAL(t_delta)*(1/Config.Rollos_RollUpFaktor));
   IF Rollos[iRoll].PositionTime>MaxTime THEN
      Rollos[iRoll].PositionTime:=t#0s;
   END_IF
END_IF

(*Abfrage ob Ausgang zugeschaltet*)
IF Ausgang_Roll_Runter AND NOT edge_runter THEN
   edge_runter := TRUE;
ELSIF NOT Ausgang_Roll_Runter AND edge_runter THEN
   edge_runter := FALSE;
END_IF

(*Abfrage ob Ausgang zugeschaltet*)
IF edge_runter THEN
   t_delta:=t_neu-t_alt;
   (*Berechnung neuer Bestrommungszeit*)
   Rollos[iRoll].PositionTime:=Rollos[iRoll].PositionTime+t_delta;
   IF Rollos[iRoll].PositionTime>MaxTime THEN
      Rollos[iRoll].PositionTime:=MaxTime;
   END_IF
END_IF

(*Berechnung Position aus Bestromungszeit*)
postmp:=TIME_TO_DINT(Rollos[iRoll].PositionTime)*100;
Position:=DINT_TO_INT(postmp/TIME_TO_DINT(MaxTime));
Rollos[iRoll].iPosition:=Position;
t_alt:=t_neu;

was an der ganzen Sache interessant ist,

- er speichert alle Position die angefahren wurden
- wenn das Simulation's Bit gesetzt ist, fährt er seine Sollwerte aus dem Speicher
- der FB berechnet sich aus der bisherigen Bestromungszeit die aktuelle Position..
- er fährt nur auf die Sollposition geregelt ..
- eingebauter Faktor für Mehrzeit beim Hochfahren ...
- Selbstkalibrierung beim Hochfahren auf 0 -> längere Bestromung als nötig ...

klaus313

... interessant !!

Kannst Du noch die Definiotion von "IfTime" nachliefern.

Danke
Klaus

SHendrik

Hallo.

IfTime:

FUNCTION_BLOCK IfTime
VAR_INPUT
   ActTime:TOD;
   SwitchTime:TOD;
END_VAR
VAR_OUTPUT
   bSwitchTime:BOOL;
END_VAR
VAR
   bEdge:BOOL;
END_VAR

(*Switch Standard auf False*)
bSwitchTime:=FALSE;
(*wenn Zeit kleiner ... *)
IF ActTime<SwitchTime THEN
   bEdge:=TRUE;
END_IF

(*wenn Zeit größer und vorher kleiner*)
IF ActTime>=SwitchTime THEN
   IF bEdge=TRUE THEN
      bSwitchTime:=TRUE;
   END_IF
   bEdge:=FALSE;
END_IF

Viele Grüße

Hendrik