Vaillant Therme analog steuern

Wer über eine Vaillant-Therme verfügt, die kein eBus kann, oder aber sonstige Probleme bei der Ansteuerung per eBus macht, den dürfte das hier interessieren:

Ich benutze diese Schaltung hier in Verbindung mit einem PWM-fähigen Ausgangspin eines Arduino Uno. Die Schaltung habe ich im Microcontroller-Forum in einem Thread zur analogen 7-8-9-Schnittstelle gefunden und nachgebaut. Sie sorgt für die Pegelwandlung und galvanische Trennung zwischen dem PWM-Ausgangspin (0…5V) des Arduino und der Heizungstherme.

Arduino-seitig ist die Ansteuerung ein Einzeiler; man setzt eben per analogOut den Duty-Cycle des Pins auf einen sinnvollen Sollwert (siehe Tabelle).

Damit funktioniert bei mir die Ansteuerung nun endlich zuverlässig. Ich habe folgenden Zusammenhang zwischen Steuerspannung und Vorlauftemperatur gefunden:


DutyCyc	VHeiz	Effekt/VlfTPeak
0		14.8		Heizt, 65°C 
1		14.0		Heizt, 59°C
2		13.4		Heizt, 54°C
3		12.9		Heizt, 50°C
4		12.4		Heizt, 45°C
5		11.9		Heizt, 40°C
6		11.5		Kein Wbdf

Daran, dass nur die sehr niedrigen Duty-Cycle-Werte (der Bereich geht von 0…255, was 0…5V entspricht) überhaupt zu sinnvollen Spannugnspegeln führen, kann man erkennen dass die verwendete Schaltung durchaus noch optimierbar wäre für eine noch feinere Ansteuerung der Heizung. Es ist auch unbedingt anzuraten, die Spannungswerte beim Nachbau zu überprüfen, ob sie eventuell anders sind als bei mir. Es wurde je in dem Thread davon ausgegangen, dass die Therme Spannungspegel von 0…15 V interpretiert, tatsächlich ist aber alles ab 11.5 V für sie „kein Wärmebedarf“, ab einer weiteren Unterschreitung kommt dazu eine Statusmeldung „Sollwert am Regler < 20°C“. Mir langt es aber so wie es ist, ich kann damit leben, die Vorlauftemperatur nur im ungefähren 5°-Raster zu setzen, zumal man die Maximaltemperatur noch zusätzlich per Handrad an der Therme begrenzen kann.

Der Originalregler von Vaillant hat übrigens keineswegs so eine feinfühlige Regelung gemacht. Der hat nur jeweils zwischen „aus“ und „Maximalwert vom Handrad“ hin und her geschaltet. :eek:

Danke für die Details, ich fange dann mal an das nachzubauen

Wer sowieso ein Pokey56E-Modul hat, kann auch die PWM-Funktion mit der hohen Auflösung zur analogen Spannungserzeugung nutzen.

Gruß Helmut

Cool - aber ich würde lieber das eBus-Problem gelöst sehen. Obwohl es gar nicht so schlimm ist und bei mir nur noch 2 mal im Monat auftaucht. Am Ende wärmt es „nur“ mein Speicher auf - also nicht das Ende der Welt. Dafür bekommt man unglaublich viel mehr Möglichkeiten…

Ich lese die Therme auch immer noch per eBus aus und habe durchaus einen „Umschalter“ im Konfigurationsbereich des Webfront, um wieder zur eBus-Regelung zurückzukehren.

Aber das tolle an dieser Lösung ist, dass sie jetzt erstmal funktioniert.

Können wir hier bitte bei der analogen Steuerung bleiben und Ebus wo anders besprechen?
Zur Therme: Das Problem ist wohl auch, dass die Anlage die Spannungsdifferenz auswertet und nicht die Spannung an sich. Insbesondere bei Anlagen aus dem letzten Jahrtausend (wie meine).

Ich bin auch auf der Suche nach einer Schaltung mit der ich relativ einfach die Spannungsdifferenz anpassen kann.
Die Anlage liefert an einem PIN 10-20V (nicht stabilisiert) und an einem weiteren PIN muss man dann z.B. 75% der gerade existierenden Spannung zurückgeben.

Ich besitze übrigens ein Vorlauf und Außentemperatur geregelte Steuerung von Vaillant, welche an dieser 3-Draht Schnittstelle der Heizung irgendwelche Vorlaufwerte angibt. Mehr weiß ich auch noch nicht.

Da ich aber ab heute die Temperaturdaten des Vorlaufs/Rücklaufs/Warmwasserspeicher und der Außentemperatur logge, werde ich die Temperaturverläufe mal übereinandere legen um hier Abhängigkeiten herauszufinden.

Ich würde die 10-20Volt messen und dann per Script berechnen wieviel 75% oder 60% davon sind und dann, nach meinen Wünschen, die %-Werte wieder als Spannung ausgeben.

Meinst Du sowas als Aufgabe?

Gruß Helmut

Teste bitte mal jemand, ob diese Behauptung mit der Spannungsdifferenz so stimmt. Ich habe das auch im Microcontroller-Forum gelesen, aufgrund meiner eigenen Messungen aber den Eindruck, dass es sich da um ein Gerücht handelt.

Update: Also ich kann das mit der Differenz nicht bestätigen, bei mir sende ich wie gesagt fixe Spannungen mit der genannten Schaltung und die Therme regelt dementsprechend korrekt.

Ist zwar alt, aber ich brauche was für meine Tochter im Haus.
Also mal nen Pi mit pwm Pin genommen, und mal schnell was auf Lochraster gestrickt, aber etwas anders (6N137 genommen).
Testskript in IPS mit den Daten die ich am Ausgang der Schaltung messe. Das ganze nur am 24V Netzteil ohne Therme…
Mal sehen, was geht…

<?
$test = 10000;
exec ('echo '."$test".' > /sys/class/pwm/pwmchip0/pwm0/period');
$test = 200;
exec ('echo '."$test".' > /sys/class/pwm/pwmchip0/pwm0/duty_cycle');
var_dump (exec ( 'cat /sys/class/pwm/pwmchip0/pwm0/duty_cycle'));
var_dump (exec ( 'cat /sys/class/pwm/pwmchip0/pwm0/period'));

/*
260 = 11,9V
0 = 15V
50 = 14,5V
100 = 13,8V
150 = 13,1V
200 = 12,5V

*/ 
?>

Mit nem Multimeter geht das einwandfrei. Pi per confic.txt und init.d Skript aud den Hardware GPIO eingerichtet.

So,
einen kleinen Schritt weiter.
Schaltung etwas verändert, den R3 (1k) gegen 100k getauscht.
Der Optokoppler(Pin2) wird direkt vom GPIO-PVM Pin vom Pi3 mit einem 330R (war R1 4k7) angesteuert, T1 und R2 sind raus.

Skript für den Pi nur um Spannungswerte zu ermitteln ! :


<?
var_dump (exec ( 'cat /sys/class/pwm/pwmchip0/pwm0/period'));
exec ('echo normal > /sys/class/pwm/pwmchip0/pwm0/polarity');
$period = 1000000;
exec ('echo '."$period".' > /sys/class/pwm/pwmchip0/pwm0/period');

$duty_cycle = 38000; // 15,0
$duty_cycle = 43500; // 14,9
$duty_cycle = 49800; // 14,8
$duty_cycle = 55800; // 14,7
$duty_cycle = 61800; // 14,6
$duty_cycle = 67800; // 14,5
$duty_cycle = 73800; // 14,4
$duty_cycle = 79800; // 14,3
$duty_cycle = 85800; // 14,2
$duty_cycle = 91800; // 14,1
$duty_cycle = 97800; // 14,0
$duty_cycle = 103800; // 13,9
$duty_cycle = 109800; // 13,8
$duty_cycle = 115800; // 13,7
$duty_cycle = 121800; // 13,6
$duty_cycle = 127800; // 13,4
$duty_cycle = 139800; // 13,3
$duty_cycle = 145800; // 13,2
$duty_cycle = 151800; // 13,1
$duty_cycle = 158000; // 13,0
$duty_cycle = 164000; // 12,9
$duty_cycle = 170000; // 12,8
$duty_cycle = 176500; // 12,7
$duty_cycle = 182500; // 12,6
$duty_cycle = 188500; // 12,5
$duty_cycle = 194500; // 12,4
$duty_cycle = 201000; // 12,3
$duty_cycle = 207000; // 12,2
$duty_cycle = 213000; // 12,1
$duty_cycle = 219000; // 12,0
$duty_cycle = 225000; // 11.9
$duty_cycle = 232000; // 11.8
$duty_cycle = 238000; // 11.7
$duty_cycle = 244000; // 11.6
$duty_cycle = 250000; // 11.5
$duty_cycle = 256500; // 11.4

$duty_cycle = 44000; //testwert
exec ('echo '."$duty_cycle".' > /sys/class/pwm/pwmchip0/pwm0/duty_cycle');
var_dump (exec ( 'cat /sys/class/pwm/pwmchip0/pwm0/duty_cycle'));
var_dump (exec ( 'cat /sys/class/pwm/pwmchip0/pwm0/polarity'));




/*

DutyCyc	VHeiz	Effekt/VlfTPeak
0		14.8		Heizt, 65°C 
1		14.0		Heizt, 59°C
2		13.4		Heizt, 54°C
3		12.9		Heizt, 50°C
4		12.4		Heizt, 45°C
5		11.9		Heizt, 40°C
6		11.5		Kein Wbdf
*/ 
?>

Meine Datei, /opt/gpio/gpio_init.sh, die vom Pi beim starten aufgerufen wird :


#!/bin/sh
# Input-Ports (Taster)
for Port in  20 21
  do
  echo "$Port" > /sys/class/gpio/export
  echo "in" >/sys/class/gpio/gpio${Port}/direction
  chmod 660 /sys/class/gpio/gpio${Port}/direction
  chmod 660 /sys/class/gpio/gpio${Port}/value
done

# Output-Ports (Relais)
for Port in 17 27 22 23 24
  do
  echo "$Port" > /sys/class/gpio/export
  echo "out" >/sys/class/gpio/gpio${Port}/direction
  echo "1" >/sys/class/gpio/gpio${Port}/value
  chmod 660 /sys/class/gpio/gpio${Port}/direction
  chmod 660 /sys/class/gpio/gpio${Port}/value
done


#PWM für Spannungssteuerung Therme
echo "0" > /sys/class/pwm/pwmchip0/export
echo "1000000" > /sys/class/pwm/pwmchip0/pwm0/period
echo "43500" > /sys/class/pwm/pwmchip0/pwm0/duty_cycle
echo "1" > /sys/class/pwm/pwmchip0/pwm0/enable


Eintrag in der /boot/conig.txt


#1-wire Bus für DS18x20
dtoverlay=w1-gpio 
# PWM 
dtoverlay=pwm,pin=18,func=2 

und
etc/rc.local


#!/bin/sh -e
#
# rc.local
#
# This script is executed at the end of each multiuser runlevel.
# Make sure that the script will "exit 0" on success or any other
# value on error.
#
# In order to enable or disable this script just change the execution
# bits.
#
# By default this script does nothing.
/opt/gpio/gpio_init.sh
#/opt/gpio/gpio_in.py &
exit 0


Jetzt muss ich am WE den Nachbau mal an die Therme hängen, und sehen was die anzeigt.
Von der Auflösung sollte dann etwas mehr gehen,

Hallo Thomas,

hatte mich damit auch mal beschäftigt - bisher aber noch nichts umgesetzt.
Hier aber noch mal zwei Links, die in diesem Zusammenhang interessant sein könnten:
Heizungsschnittstelle 7-8-9 - Mikrocontroller.net (hier besonders der von Autor: minti (Gast) Datum: 23.10.2009 15:09)
2-Punkt-Heizungsregelung über die analoge 7-8-9-Schnittstelle (Vaillant VCW 204) | DL1MK

Joachim

P.S.: Freue mich auf Deine Lösung!:smiley:

Hallo Joachim,
danke für den Tipp, aber die Seiten sind schon im Blick.
Danach ist ja schon was im Testlauf, noch ohne Therme, da ich die nicht direkt im Zugriff habe.
.
sokkederheld :

Update: Also ich kann das mit der Differenz nicht bestätigen, bei mir sende ich wie gesagt fixe Spannungen mit der genannten Schaltung und die Therme regelt dementsprechend korrekt.

Daher werde ich die Werte mal so an die Therme senden, und sehen was da passiert.
Es scheinen ja doch verschiedene Dinge zu gehen.
Ich halte Euch auf dem laufenden.
ps die Messungen der Temperaturen erfolgt auch über den PI am GPIO, aber mit Pullup von2k7 an 3.3V, und V+ vom DS18x20 hängt an 5V, damit bekomme ich über 30mtr ISTY 2x2x0.6 für 2 Sensoren stabile Werte, mit 3.3V und der Leitungslänge ging es nicht.

Keine Ahnung, ob sich meine Vorgehensweise auf Eurer Thema übertragen lässt. Ich steuere meine Vaillant-Therme (VC146, Vorlauf und Speichertemperatur) über eine Widerstandskaskade bzw einen Widerstand. Das funktioniert sehr zuverlässig, da der Außentemperatur- und der Speichertemperatur-Fühler nichts anderes als ein temperaturabhängiger Widerstand sind.
Mit 4 Schaltern lassen sich dann 16 Außentemperaturen simulieren. Ich habe mich allerdings für 8 Temperaturen und eine „Aus“-Temperatur (30•C) entschieden, um einen deutlichen Abstand zwischen „An“ und „Aus“ zu haben.
Viele Grüße
Jürgen

Hallo Jürgen,
dass könnte schon gehen, aber ich möchte erst mal den Weg von sokkederheld versuchen, und die Vorlauftemperaturen per PWM setzen (kommt ja vom IPS Pi schon raus…)
Also habe ich eine Hardware (Pi3) die IPS und Heizung steuert. Im Moment läuft das ach schon Life, aber mit Relais an Klemme „230V Raumthermostat“, Messung der Raumtemperatur auch am PI3 über DS18s20.
Ich selbst habe nen 50Kw „Öl-Brüller“ im Haus, der komplett von IPS seit 2 Jahren gesteuert wird, mit Brauchwasser, Mischer Heizungsvorlauf und Brenner. Das läuft besser als die alte orginal Steuerung (die mittlerweile ganz den Geist aufgegeben hat.)
Mit den Thermen habe ich noch keine Erfahrung, daher erst mal der Versuch, die Daten vor Ort zu ermitteln. Einen Eingriff in die Sicherheitskette mache ich nicht ! Es geht nur um den Regler an der Schnittstelle.

Mist ist, mir fehlt einfach Zeit, geht immer nur am WE da was zu machen, nebenbei muss der Umbau noch neu verkabelt werden.(Da würden dann später auch mal „Bus“ gehen, lege genug rein…)

Hallo,
PWM-Steuerung läuft seit heute Mittag an der Therme.
Sieht so aus ;

…magst Du bitte noch mal Deine Schaltung mit den Anpassungen im Ganzen posten?

Joachim

Und die Skript aus Therme,
Regler:


<?
$id = IPS_GetParent($_IPS['SELF']);
$id2= IPS_GetParent($id);
$id3= IPS_GetObjectIDByName("Regler Aussentemperatur", $id2);
$id4= IPS_GetObjectIDByName("Regler Raum1", $id2);
//$IstTemperaturAussenID = IPS_GetObjectIDByName("Temperatur_Aussen", $id3);
$IstTemperaturAussenID = IPS_GetObjectIDByName("Temperatur_Regler", $id3);
$SommerID = IPS_GetObjectIDByName("Sommerumschaltung", $id3);
$statusID = IPS_GetObjectIDByName("Status", $id3);

$Aussentemp=GetValueFloat($IstTemperaturAussenID);
var_dump($Aussentemp);
$Sommertemp=GetValue($SommerID);

//Sommer, Kesselsollwert
   if ($Aussentemp < $Sommertemp ) { 
   		SetValueBoolean($statusID,false);
		
		$Raumsollwert = GetValue(IPS_GetObjectIDByName("Solltemperatur Raum", $id4));
		$Steilheit=GetValue(IPS_GetObjectIDByName("Steilheit", $id));
		$min=GetValue(IPS_GetObjectIDByName("Min. Temperatur", $id));
		$max=GetValue(IPS_GetObjectIDByName("Max. Temperatur", $id));
		$Korrektur_Kessel=GetValue(IPS_GetObjectIDByName("Parallelverschiebung", $id));

		$Vorlauftemperatur_Kessel=min(max(round((0.55*$Steilheit*(pow($Raumsollwert,($Aussentemp/(320-$Aussentemp*4))))*((-$Aussentemp+20)*2)+$Raumsollwert+$Korrektur_Kessel)*1)/1,$min),$max);
		SetValue( (IPS_GetObjectIDByName("Solltemperatur", $id)), $Vorlauftemperatur_Kessel);
var_dump($Vorlauftemperatur_Kessel);
		$spannung=((($Vorlauftemperatur_Kessel-40)/10)+11.9);
		
		// var_dump($spannung);
		$spannung_id=IPS_GetObjectIDByName("Spannung", $id);
		SetValue($spannung_id, $spannung);

   }
   if ($Aussentemp > $Sommertemp ) { 
   		SetValueBoolean($statusID,true);
		$spannung_id=IPS_GetObjectIDByName("Spannung", $id);
		SetValue($spannung_id, 11.4);


   }

?>

Hier wird die Vorlauftemperatur berechnet und als Spannungswert in die VAR „Spannung“ geschrieben.

Spannung Vorlauf :

<?
$id = IPS_GetParent($_IPS[‚SELF‘]);
$id2= IPS_GetParent($id);
$id3= IPS_GetObjectIDByName(„Therme“, $id2);
$duty_cycle_id=IPS_GetObjectIDByName(„duty_cycle“, $id3);
$duty_cycle= (exec ( ‚cat /sys/class/pwm/pwmchip0/pwm0/duty_cycle‘));
SetValue($duty_cycle_id, $duty_cycle);

$spannung_id=IPS_GetObjectIDByName(„Spannung“, $id3);
$spannung=getvalue($spannung_id);

exec (‚echo inversed > /sys/class/pwm/pwmchip0/pwm0/polarity‘);
$period = 1000000;
exec (‚echo ‚."$period".‘ > /sys/class/pwm/pwmchip0/pwm0/period‘);

$stellwert=((($spannung-10)*61000)+657000); //657000 PWM = 10V, 61000 = +0,1V, Startwert ist 10V für die Berechnung
$duty_cycle = $stellwert;

exec (‚echo ‚."$duty_cycle".‘ > /sys/class/pwm/pwmchip0/pwm0/duty_cycle‘);

?>

Hier wird aus der berechneten Spannung die PCM erzeugt, die auf die Schaltung gehen und die Spannung (11,0 - 15V nutze ich dort im Moment) für die Vorlauftemperatur erzeugt.

Das klappt auf ±1K an der Therme, und läuft jetzt erst mal LIFE.

Die GPIO Ansteuerung mache ich über ein init Bash Skript bein Start des Pi’s, welches per rc.local aufgerufen wird :
gpio_init.sh

#!/bin/sh
# Input-Ports (Taster)
for Port in  20 21
  do
  echo "$Port" > /sys/class/gpio/export
  echo "in" >/sys/class/gpio/gpio${Port}/direction
  chmod 660 /sys/class/gpio/gpio${Port}/direction
  chmod 660 /sys/class/gpio/gpio${Port}/value
done

# Output-Ports (Relais)
for Port in 17 27 22 23 24
  do
  echo "$Port" > /sys/class/gpio/export
  echo "out" >/sys/class/gpio/gpio${Port}/direction
  echo "1" >/sys/class/gpio/gpio${Port}/value
  chmod 660 /sys/class/gpio/gpio${Port}/direction
  chmod 660 /sys/class/gpio/gpio${Port}/value
done


#PWM für Spannungssteuerung Therme
echo "0" > /sys/class/pwm/pwmchip0/export
echo "1000000" > /sys/class/pwm/pwmchip0/pwm0/period
echo "657000" > /sys/class/pwm/pwmchip0/pwm0/duty_cycle
echo "inversed" > /sys/class/pwm/pwmchip0/pwm0/polarity
echo "1" > /sys/class/pwm/pwmchip0/pwm0/enable


1wire für DS18x20 aktiviere ich per config.txt

Und die Schaltung :

Bei Bedarf, packe ich mal alles in eine ZIP, und stelle es zur Verfügung.
Besser wäre ein Modul, aber das dauert…
Ich möchte es jetzt erst mal ein paar Tage sehen, wie es so geht…

Dazu noch mal meinen Dank an paresy, der das mit ermöglicht hat, für die schnelle Lieferung einer Zusatzlizenz vor Geldeingang.:smiley: