Pi 2, 1wire direkt am GPIO4

Hallo,

bin seit einigen Tagen am überlegen, einen PI2 mit IPS als Heizungsregler zu versuchen.
Da soll die komplette Kesselsteuerung mit Kesselwasser, Mischer und Speicher übernehmen.
Erster Versuch, Temperaturen zu erfassen direkt per GPIO4 am PI aus Symcon.


<?
		$ds_id[1] = "10-000801717bee";
		$ds_id[2] = "10-00080282e6eb";
		$ds_id[3] = "10-00080282eb9c";
		$ds_id[4] = "28-000001326a54";
		$ds_id[5] = "28-000005110ea4";
		$ds_id[6] = "28-000005944153";
// Test
		$temp = exec('cat /sys/bus/w1/devices/'.$ds_id[1].'/w1_slave |grep t=');
		$temp = explode('t=',$temp);
		$temp = $temp[1] / 1000;
		$temp = round($temp,2);

//		echo $temp . " C";

 if($_IPS['SENDER'] == "Execute")                // nur wenn bei "Ausführen"
 {
	  $vid = CreateVariableByName($_IPS['SELF'], "Running", 0);
	  $eid = CreateEventIDByName($_IPS['SELF'], "StartStop", 0);
	  IPS_SetEventActive($eid, true);
	  IPS_SetEventTrigger($eid, 0, $vid);
	  IPS_SetEventScript($eid, $_IPS['SELF']);
 }

 if($_IPS['SENDER'] == "Variable")
 {
  if($_IPS['VALUE'])
  {
   IPS_SetScriptTimer($_IPS['SELF'], 15);         // 15-Sekunden-Takt
  } else {
   IPS_SetScriptTimer($_IPS['SELF'], 0);
  }
 }

 if($_IPS['SENDER'] == "TimerEvent")             //
 {
	for ($i = 1; ; $i++) {
	   if ($i > 5) {
	        break;
	   }
		$temp = exec('cat /sys/bus/w1/devices/'.$ds_id[$i].'/w1_slave |grep t=');
		$temp = explode('t=',$temp);
		$temp = $temp[1] / 1000;
		$temp = round($temp,2);
  	   $id = CreateVariableByName($_IPS['SELF'], $ds_id[$i], 2);
	   SetValue($id, $temp);
	}
 }

function CreateVariableByName($id, $name, $type)
{
   $vid = @IPS_GetVariableIDByName($name, $id);
   if($vid===false) {
      $vid = IPS_CreateVariable($type);
      IPS_SetParent($vid, $id);
      IPS_SetName($vid, $name);
   }
   return $vid;
}

function CreateEventIDByName($id, $name, $type)
{
   $eid = @IPS_GetEventIDByName($name, $id);
   if($eid===false) {
      $eid = IPS_CreateEvent($type);
      IPS_SetParent($eid, $id);
      IPS_SetName($eid, $name);
   }
   return $eid;
}
?>

Jetzt muss ich mir mal über die Regler Gedanken machen, wie ich so etwas in PHP lösen könnte.
Falls einer Tipp’s hat, her damit.
Im Moment fehlt mir leider Zeit, und ich komme fast nur noch am WE etwas weiter.

ps :
config.txt in /boot:

dtoverlay=w1-gpio,gpiopin=4,pullup=on

Mit einer Kesselregelung wird es schwer. Du bräuchtest dann ein Event das zyklisch ein PHP Skript triggert um die Kesseltemperatur abzufragen und die Lastanforderung an den Brenner macht. Außerdem kannst du mit PHP keinen PI/PID-Regler bauen, da PHP keine Werte (Kp, Tn) zwischen speichern kann. Wirst mit PHP nicht hinbekommen. Am besten du holst die ne günstige Wago SPS mit paar I/O´s. Diese dann per Modbus TCP anbinden :wink:

Gruß
Martin

…warum sollte das ein Problem darstellen?:confused:

Alles was Du beschrieben hast ist mit IPS möglich.

Als x Minuten ein Skript antriggern, durch eine PID-Formel jagen und einen neuen Zielwert festlegen. Die letzte Temperaturdifferenz und die Summe der Temperaturdifferenzen wird dabei im IPS in einen Variablen gespeichert.

Ich habe hier so etwas zur Raumtemparatur-Reglung auch laufen - funktioniert besser als gedacht…

Joachim

Ah, okay, cool.

Stimmt, an das Speichern in einer Variable habe ich vergessen.
Dein Skript würde mich mal interessieren. Könntest es mal posten? Vielleicht auch für tomgr interessant!?

Gruß
Martin

…ist in Gänze etwas komplexer, ich versuche es mal darzustellen.

Dieses ist die Kernformel:

	//e = aktuelle Reglerabweichung -> Soll-Ist
	//ealt = vorherige Reglerabweichung
	//esum = die Summe aller bisherigen Abweichungen e
	//y = Antwort -> muss im Bereich zwischen 0-100 sein
	//esum = esum + e
	//y = Kp * e + Ki * Ta * esum + Kd * (e – ealt)/Ta
	//ealt = e
	//Kp = Verstärkungsfaktor Proportionalregler
	//Ki = Verstärkungsfaktor Integralregler
	//Kd = Verstärkungsfaktor Differenzialregler
	
	// Die Berechnung des neuen Regelwertes
	$y = ($Kp * $e + $Ki * $Ta * $esum + $Kd * ($e - $ealt) / $Ta);

Hier mal die angepasste Version für diese FHT80 Stellmotoren:

// Daten die vorgegeben werden müssen
$Kp=5; //Kp = Verstärkungsfaktor Proportionalregler
$Ki=2.5; //Ki = Verstärkungsfaktor Integralregler
$Kd=0; //Kd = Verstärkungsfaktor Differenzialregler
$StellmotorAdresseDaten = "T123401";
$reg = 39231 /*[CUNO\CUNO]*/   ;

// Ab hier nichts mehr ändern **************************************************************

//Ta = Rechenschrittweite (Abtastzeit)
$Ta = Round((time() - IPS_GetScript($IPS_SELF)['LastExecute'])/60,0);
//Schutzmechanismus falls Skript innerhalb einer Minute zweimal ausgeführt wird
$Ta = Max($Ta, 1);

//VariablenID des dazugehörigen Objektbaums ermitteln
$ppID = IPS_GetParent(IPS_GetParent(IPS_GetScript($IPS_SELF)['ScriptID']));
$SollTemperaturID = IPS_GetVariableIDByName("Soll Temperatur", $ppID);
$IstTemperaturID = IPS_GetVariableIDByName("Temperatur", $ppID);
$HeizungsStellelementID = IPS_GetVariableIDByName("Heizungs-Stellelement", $ppID);
$HilfsvariablenID = IPS_GetCategoryIDByName ("Hilfsvariablen", $ppID);
$SummeRegelabweichungenID = IPS_GetVariableIDByName("Summe Regelabweichungen", $HilfsvariablenID);
$VorherigeRegelabweichungID = IPS_GetVariableIDByName("Vorherige Regelabweichung", $HilfsvariablenID);;

// Sonstige benötigte Variablen
$TagDesMonats = 10856 /*[Sonstige Daten\Variablen\Sonstige Variablen\Tag des Monats]*/;
$AktuelleUhrzeit = 37001 /*[Sonstige Daten\Variablen\Sonstige Variablen\Aktuelle Uhrzeit]*/;

//aktuelle Regelabweichung bestimmen
$e = GetValueFloat($SollTemperaturID)- GetValueFloat($IstTemperaturID);

// Die Summe aller vorherigen Regelabweichungen bestimmen
//Echo GetValueInteger($HeizungsStellelementID)." - ".$e;
If (((GetValueInteger($HeizungsStellelementID) == 0) and ($e < 0)) OR ((GetValueInteger($HeizungsStellelementID) == 100) and ($e > 0)))
	// Die Negativ-Werte sollen nicht weiter aufsummiert werden, wenn der Stellmotor schon auf 0 ist bzw. Die Positiv-Werte sollen nicht weiter aufsummiert werden, wenn der Stellmotor schon auf 100 ist
	{
	$esum = GetValueFloat($SummeRegelabweichungenID);
   }
else
	{
	//Echo "Test";
	$esum = GetValueFloat($SummeRegelabweichungenID) + $e;
   SetValueFloat($SummeRegelabweichungenID, $esum);
	}

// Die vorherige Regelabweichung ermitteln
$ealt = GetValueFloat($VorherigeRegelabweichungID);

list($y, $Stellwert) = PID($Kp, $Ki, $Kd, $e, $esum, $ealt, $Ta);

// Vorherige Regelabweichung durch jetzige ersetzen
SetValueFloat($VorherigeRegelabweichungID, $e);

// Den berechneten Wert in einer Variablen sichern
SetValueInteger($HeizungsStellelementID, $Stellwert);

// Stellwert senden
//Puffer löschen
CUNO_Sendung($reg, $StellmotorAdresseDaten."FF00
");

// Für die monatliche Entkalkungsfahrt den Regelwert manipulieren
If ((GetValueInteger($TagDesMonats) == 1) and (GetValueString($AktuelleUhrzeit) == "08:00"))
{
	$y = "FF";
}

//Wert senden
CUNO_Sendung($reg, $StellmotorAdresseDaten."26".$y."
");
//Anzeigen, wie viele Sekunden bis zur nächsten Sendung vergehen
$result = CUNO_Sendung($reg, "T11
");
Echo "Nächste Datensendung: ".hexdec(substr($result, 0, 2))." sek";

Das Ganze habe ich auch für andere Stellglieder angepasst. Lediglich am Ende muss also der Code auf das angepasst werden, wie das Regelglied arbeitet (0-255, 0-100% usw.). Bei Ki, Kp und Kd muss ein wenig probiert werden. Hier im Forum gibt es irgendwo ein Skript, wie man diese Faktoren für jeden Tag neu und automatisch berechnen kann.

Bei einer aktuelleren Version ist dem Skript noch eine PWM-Stufe „nachgeschaltet“.

Das Skript wird alle zwei Minuten oder bei Änderung des Sollwertes getriggert.

Joachim

…ist in Gänze etwas komplexer, ich versuche es mal darzustellen.

Danke dir, werd mir das mal ansehen, und versuche fahren.
Wird aber etwas dauern:confused:

Zur Info,

dass ist der Verlauf der jetzigen Steuerung, die ich per PHP mal nachbilden möchete (mit mehr Optionen).
Hintergrund ist, die Steuerung hat (hatte) Fehler, ist aber eine längere Geschichte.

Ich möchte mich noch mal für Eure Ideen und Beispiele bedanken.
Habe das etwas anders gemacht, aber seit gestern (Heute) läuft ein IPS auf einen PI2, der nur die Heizung regelt, per 8fach Relaisblock und 1wire direkt an den GPIO’s.
Daten schiebe ich per json zwischen dem Haus Pi und dem Heizungs Pi noch hin und her, da ich mir die ganzen Temperaturen aus beiden Systemen hole und so besser Vergleichen kann.
Jetzt noch ein paar Kinderkrankheiten raus machen, dann baue ich da ein Modul von.
Gesteuert wird ein 50KW Ölkessel, mit Mischer (Heizungsvorlauf), Warmwasserspeicher, Brenner. Die alte Steuerung die mir Probleme macht, ist umsteckbar (zur Not).
Ich habe auf dem Pi mit IPS abder nichts anders am laufen, und will den auch so lassen. (Spiele einfach zu viel rum, wenn ich mal Zeit habe…)
Wenn die Dinge laufen und durchgetestet sind, werde ich das hier im Forum reinstellen. Da braucht es aber noch etwas Zeit, da alles in etwas Doku gefasst werden muss.

Man bin ich froh, dass das so gut geht, und ich mir ein paar Scheine sparen konnte,
#War aber nur möglich durch die lange Aufzeichnung der Heizungswerte (damals noch mit LinHk, seit 1,5 Jahren mit IPS),
Ich muss dazu sagen, es ich ein 4 Familien Haus ( BJ 1876) was ich habe, und kann leider nicht alles sehen, was in den Wohnungen passiert. Aber ich habe die alten Werte perfekt auf den PI-Symcon Regler übertragen können, jetzt sind Feinheiten angesagt.

Hallo,

habe heute den Heizungsregler soweit komplett fertig bekommen, dass steuert jetzt Life die Anlage.
Alle Temperaturen und Relais hangen direkt an den GPIO’s vom Raspberry2, Schaltkasten fehlt noch…:smiley:
Hoffe noch, die Zeit zu finden, da ein PHP Modul von zu machen,
Hier mal die Bilder.

Solche Projekte liebe ich. Super umgesetzt.

Nicht nur du.:smiley:
Ich teile es auch, wenn ich die Zeit finde, es "verteilbar " zu machen.
Wer es testen konn, oder möchte, ich kann eine „Sicherung“ von dem IPS per ZIP rausgeben, für ein PHP Modul reicht die Zeit noch nicht, kommt aber,
Ich bin jetzt ca 2 Wochen am testen, und habe nocht nicht alle Parameter perfekt, aber fast:D
OK, mein 50kW Kessel macht auch reichlich Last, und braucht noch etwas feintuning.:smiley:
Aber ich vermisse die orginal Viessmann Steuerung nicht mehr, da bin ich drüber weg.:cool:

Ich würde meine ja mal spaßeshalber umbauen aber das traue ich IPS nicht zu. Der beta gar nicht, obwohl die bei mir auf dem Raspi gut läuft und sonst nicht. Dann dreimal mehr einem meiner Pokeys.

Aber es reizt mich schon. [emoji41]

Schisshase:D
Ich habe ein 4 Fam Haus, und bin da schmerzfrei es auf dem Pi zu testen, da bis jetzt alles immer gut gelaufen ist.
Ich bin auf den Life Pi’s aber nicht immer „aktuell“, nur auf dem Test Pi, wenn der rennt, kommt das Update auf die „Life Systeme“.
Wenn ich nicht einen Fehler einbaue (Was ich gut kann:D), ist mir noch nicht das Life System noch nicht wirklich abgestürzt, die Testsysteme schon.
Da war der Fehler fast immer 50 cm vor dem Bildschirm:D, bis auf einige kleine Bug’s von IPS:cool:.
Ich habe da einen PI mit IPS nur für die Heizungsstuerung genommen, da läuft nichts anders drauf, ausser Austausch der Daten per json über tcp/ip zu anderen IPS Pi’s,
Ich nutze auf alle Pi’s „Minibian“, dafür ist der Anhang ausgelegt. (Achtung, nur die Heizungssteuerung, bitte nicht auf andere Life Systeme kopieren, sonst sind Eure IPS Daten WEG!!!)

Heizung.zip (1.33 MB)

:smiley:

Ich hätte sogar alles an Hardware da.
Meine Heizung ist sogar ohne Mischer und irgendwelchen komplizierten Dingen, hat aber ne moderne Steuerung (RC35 Buderus). Die kann ganz gut aber nicht perfekt.

Mhmmmm :rolleyes:

Ok Boui,
„moderne Steuerung“, dann lass es, oder mach es umsteckbar (so habe ich das am laufen, im Fehlerfall kann ich die alte Steuerung schnell wieder anstecken, unter dem Deckel der Heizung…)
Sitze aber immer noch an den Anpassungen der Parameter, um es noch besser auf Heizung an zu passen, aber das wird jeden Tag etwas besser.
Das nächste was ich machen muss, eine Sicherung auf SD-Karte da neben zu legen (Besser einen 2ten Pi mit SD), falls die mal ausfällt.
Dann noch Taster und Display an den Pi, um etwas vor der Heizung zu sehen, und auch eine Verstellung ohne Netzwerk machen zu können. Aber vorher muss noch ein Gehäuse her.:smiley:

Einige Baustellen habe ich noch, 1wire Skript ist noch doof (muss besser werden…), da von ein PHP Modul bauen, Soll Heizkurve als Graphen darstellen (noch keine Ahnung, wie ich das machen kann),
Raumtemperaturen von anderen Systemen (bei mir LCN und zwave) mit einbinden (geht per PCHK oder IP, da von dem Haus IPS), aber erst wenn alles fertig ist.
Weiterhin schwebt mir noch Wind und Aussenfeuchte vor, da ich einen Altbau habe, und da etwas mehr Vorlauftemp mit reinbringen könnte usw.
Ich würde mich aber freuen, wenn du es versuchen würdest, auch ohne Anbindung an die Heizung, und nur vergleichen würdest. Ich habe es zwar anders gemacht, Viessmann regeln lassen, und dieses im Pi nachgestellt, bei fast Gleichheit dann Umgesteckt.

Ich weiß schon, wie ich mit dem Thema umgehen muss. [emoji41]
Bei mir läuft gar nix ohne Rückfallstrategie. Die neue Steuerung hatte ich ja auch selbst in die Heizung gebaut.
Gehäuse drucke ich mittlerweile nach Belieben selbst.

Ich hab gerade noch ein Projekt laufen und wenn ich die Zeit finde, teste ich es mal.

Zumindest aufspielen und anschauen. Seit der IPS-OSX Pleite muss ich den WAF erst wieder aufbauen und Heizung ist da ganz kritisch.

Das würde ich auch gerne können.
Der Rest war schon klar. :smiley:

Ich bin jetzt fast auf dem Stand, dass optimum hier im Haus gefunden zu haben, wie ich es einstellen muss.
Aber es geht bestimmt noch etwas besser,

Dieser Fehler „1Wire 18B20 Refresh ausgefallen“, den Bernhard meldete, ist für ne Heizungssteuerung nicht beruhigend.

1Wire 18B20 Refresh ausgefallen

Ist hier kein Thema, 1wire kommt direkt von den GPIO 4 und liegt im Filesystem, am Pi brauche ich keine externen Geräte um mit 1wire zu sprechen. 4k7 Pullup von 3,3V an GPIO 4, Dallas + an +3,3V, GND an GND, fertig ist es.
Abholung mit :


$ds_id[1] = "10-000802293908";

$temp = exec('cat /sys/bus/w1/devices/'.$ds_id[$i].'/w1_slave |grep t=');
$crc = exec('cat /sys/bus/w1/devices/'.$ds_id[$i].'/w1_slave | grep crc | sed "s/^.*\(...\)$/\1/"');
if($crc =="YES" and $temp !== "-62" and $temp  !== "85000") {        //Fehler raus, "-62" , 85°C und CRC falsch
		$temp = $temp / 1000;
		$temp = round($temp,2);
	        SetValue(12345, $temp);
	   }

Wenn ich noch nen Levelshifter dranhänge, geht es auch mit 5V und der Bus kann länger werden. Mein 1wire Bus ist jetzt ca. 15 mtr lang an der Heizung und es geht mit 3,3V ohne Probleme.
Temperaturen im Takt von 5 -10Sekunden lesen, reicht.
Das rennt jetzt fast 2 Wochen, ohne Absturz, neuste Update ist auch drauf…

Ok,

:smiley:

Hatte ja fast übersehen, dass ich in meiner Heizung auch ne Handvoll der digitalen Zwerge zusätzlich eingebaut habe.
Die werden aktuell von einem Pokeys57E ausgelesen und IPS bereitgestellt.

Temperaturen im Takt von 5 -10Sekunden lesen, reicht.
Das rennt jetzt fast 2 Wochen, ohne Absturz, neuste Update ist auch drauf…

Stimmt. Das läuft hier seit jahren so problemlos, dass ich gar nicht mehr daran dachte.
Abgastemp messe ich auch noch mit einem anderen Sensor.

Aber aktuell alles nur zu Anzeigezwecken.