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?
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
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
jalousiesteuerung müssen wir leider auf die 1.6 verschieben, dann aber definitiv mit sonnenstandsabhängigkeit usw.
Hallo Hugo,
was macht die Jalousiensteuerung? Hast du schon eine Beschreibung der Funktionen ?
danke :-)
Klaus
nein wir sind erzeit an vielen kleinen detail wie siemens kompatibilität usw. die jalosiesteuerung wird wohl anfang april kommen
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
ja das heizen kühlen über die jalosie macht wirklich sinn
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
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?
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 ...
... interessant !!
Kannst Du noch die Definiotion von "IfTime" nachliefern.
Danke
Klaus
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