Cooperating radiator monitoring 114
C.R.M. 114 Status: unstable | |
---|---|
Beschreibung | Steuerung und Überwachung von HR20 Thermostaten per 1-Wire |
Autor: | xoQUox |
Version | 1 |
PayPal |
Beschreibung
Idee
Um die Heizkosten im Backspace zu minimieren, möchten wir unsere Heizungen zentral über einen einfachen Bus steuern. Zusätzlich sollen über diesen Bus noch weitere Temperaturfühler und Erweiterungen ausgelesen und gesteuert werden können.
Planung
Für die Realisierung versuchen wir die Heizungsthermostate per 1-Wire Bus steuerbar zu machen. Zusätzlich sollen an diesen Bus auch DS18S20 Temperaturfühler angebracht werden. (vgl. DS1820TOUSB)
Die Daten soll von einem 1-Wire Master gesteuert werden, der auch die Regelung der Thermostate, die Raumtemperaturüberwachung und ein Webinterface bereit stellt.
Arbeitsverteilung
Die integration der Busfunktionalität auf Softwareebene übernimmt xoQUox. Für die Entwicklung der Bedienebene und Steuerung ist schinken verantwortlich, dies wird auf Basis eines Raspberry Pi realisiert.
Honeywell HR20
Hardware
Das Honeywell HR20 ist ein gängiges µC gesteuertes Heizungsthermostat. Seine große Verbreitung und die Tatsache das es bereits einige Projekte für alternative Betriebssoftware gibt, bietet die ideale Grundlage.
- 3 Tasten
- 1 Stellrad mit Drehgeber.
- LC-Display
- Stellmotor für Heizungsventil
- Prozessor: AVR ATmega169P
- 10 Zugängliche Pins: JTAG, RX(PE0)/TX(PE1), 1 GPIO (PE2), VCC, GND
Es gibt von diesem Thermostat auch eine ältere Version die mit einem NEC µC arbeitet. Wir beziehen uns jedoch nur auf die aktuelle Variante mit dem AVR.
Schaltplan
Bei dem aktuellen Schaltplan des HR20 waren alle Bauteile bis auf einen IC (IC 2) identifiziert. Nach einer Analyse von Lucky (lucky ät foxserver döt org) könnte es sich um einen Dual P-Channel 1.8V PowerTrence Specified MOSFET handeln. Genau gesagt um einen FDC6312P von Fairchild. Zu beachten ist jedoch das im Schaltplan die Pins gespiegelt sind.
Open HR20
Die Software Open HR20 wurde von Dario Carluccio, Jiri Dobry und Thomas Vosshagen entwickelt. Diese Software ist ein funktioneller Nachbau der Original-Software und ist als GPL-2 lizensiert.
1-Wire Slave
Software Vorlage
Als Vorlage für die 1-Wire implementierung verwenden wir "1-Wire Device mit AVR-Mikrocontroller" von Tobias Müller, veröffentlicht unter der GPL-3 Lizenz. Mit dieser Software ist es möglich, einen 1-Wire Slave vollständig in Software zu implementieren.
Phase 1: Proof of concept
Original Arbeit der 1-Wire Slave Quellcode mit dem INT0 des AVRs, dieser ist jedoch bei unserem ATMega169P schon als Line für das Display des HR20 in Verwendung. Als Alternative verwenden wir den PCINT2 der glücklicherweise an die externe Pinleiste geführt wurde. Die Pin Change Interrupts der ATMegas sind jedoch viel simpler aufgebaut als der externe Interrupt INTx . Es können nur Logikänderungen am Pin, nicht aber welche Flanke, erkannt werden. Außerdem teilen sich 8 Pins je einen PC Interrupt. Beim Aufruf des Interrupts muss also noch eine abfrage auf den richtigen Pin und seinem Zustandswechsel erfolgen um die Flankenfunktionalität nachzubilden.
Wie oben beschrieben haben wir beim HR20 nicht den für die 1-Wire integration benötigten INT0 frei. Des weiteren wird auch der 8-Bit Timer (Timer0) bereits in der Open HR20 Software verwendet. Da wir diese so gut wie Unverändert lassen wollen, ist es nötig den externen Interrupt auf den bereits beschriebenen PCINT2 zu legen und auch der Timer Overflow muss von Timer0 auf den 16-Bit Timer1 umziehen. Um dies zu Testen wurde das Projekt OW_Simple gestartet. Dabei handelt es sich um die 1-Wire Slave Vorlage mit allen Änderungen für den ATmega169P des HR20 sowie den Anpassungen der Interrupts. Ziel ist es die 1-Wire Funktionalität als Standalone Software auf dem HR20 zum laufen zu bekommen.
Probleme
Um eine Flankenerkennung für einen Pin Change Interrupt am ATMega zu realisieren, muss man sich den letzten Pin-Zustand merken und beim erneuten Aufruf der Interrupt-Funktion mit dem aktuellen Zustand vergleichen. Nun hat man jedoch das Problem, das alle Interrupts des AVRs gleich priorisiert sind und sich nicht gegenseitig unterbrechen dürfen. Fällt ein Interrupt während der Laufzeit eines anderen an, so wird erst nach Beendigung des aktuellen der neue ausgeführt. Dabei stellt sich jedoch das Problem, das sich in dieser Zeit der Zustand des Pins schon geändert haben kann.
Wir haben keine Möglichkeit bei diesem Typ den Zustand zum Zeitpunkt des Logikwechsels am Pin festzustellen. Dadurch kann es dazu kommen, das wir zwar einen Pinchange-Interrupt bekommen, aber bei der Ausführung die händische Detektion der Flanke fehlschlägt. Wir bekommen nicht alle Bits vom Master mit und kommen aus den Takt.
Erste Versuche die "Wartezeiten" des Timerinterrupts gezielt zu verkürzen zeigten erste Postive Ergebnisse. Die Anzahl der verschluckten Pinchange-Interrupts wurden weniger. Die genauere Analyse ergab jedoch auch, wie gut auf dem Bild rechts zu sehen, das unser Slave die Leitung zu spät auf Low zieht um eine Logische 1 auf den Bus zu schreiben. Und zwar erst wenn die Flanke wieder am steigen ist. Dies kann man gut auf dem Bild rechts an den kurzen Spitzen beim 10 und 13 Bit des unteren Graphen erkennen.
Die Zeiten des Timers sind fest in der 1-Wire Software vorgegeben. Per Defines können diese zwar verändert werden, sind aber zur Laufzeit fest im Programm. Es könnte also sein das die Software nicht immer mit jedem 1-Wire Master vom Timing her zusammenarbeiten kann und erst die passente Werte Messtechnisch oder durch Versuche ermittelt werden müssten.
In diesem Zustand kam zwar eine Kommunikation mit dem Master zustande, aber nach wie vor aus dem Takt, wodurch nach wenigen Übertragenen Bits der Master abbricht. Wie im Bild links zu sehen werden unsere Bits (x) und Komplement-Bits (Cx) korrekt gesendet und vom Master bestätigt (Ax). Dies geht hier für genau 4 Bits (12 Flanken am Bus) richtig. Dann verpassen wir eine Flanke (X) und kommen mit unseren Interrupt erst zum darauf folgenden. Dies verschiebt die Kommunikation, der Master stellt einen Fehler (E) fest und löst einen Reset aus.
Erste Vermutungen
(Anmerkung: Nachfolgende Gedanken erwiesen sich als Falsch)
Dies kommt vermutlich von einer unsauberen Erkennung am PCint. Dieser Löst wohl im Logikübergang ab und zu falsch aus, wenn der Pin noch keinen festen zustand hat. Bei Tests war hier innerhalb weniger Takte ein Zustandswechsel zu beobachten. Eine genaue Ursache konnte bisher noch nicht ermittelt werden. Unschön ist auch dass das Datenblatt des ATmega169P keine genauen Angaben macht, ab welchem Zustand ein Logikwechsel am Pin als solcher auch Interpretiert wird.
Eine "Entprellung" der Datenleitung ist wohl unumgänglich, wenn auch etwas Zeitkritisch, da wir nur maximal 15µS Zeit haben die Fallende Flanke zu erkennen und darauf zu reagieren um selbst die Leitung für eine 0 auf Low zu ziehen. Die minimale Zeit die laut 1-Wire Spezifikationnach jeder Flanke eingehalten werden muss, ist 1µS. Von daher ist es denkbar nach einem Flanken Interrupt ca. 1µS zu warten und dann den Pin erneut abzufragen. Sauberer wäre wohl aber auch, nach dieser Wartezeit, erst im Interruptregister nachzusehen ob ein neuer Pin-Change anliegt, diesen zu löschen, und nur mit dem Pin Wert zu arbeiten, der auch im aktuellen Zustand Sinn macht. Immerhin wissen wir ja immer, ob die Leitung zuletzte Low oder High war.
Lösung
Nach einer genaueren Betrachtung der Signale am Oszilloskop kamen erste Zweifel an den ersten Vermutungen. Das Low Signal vom Master sah nicht sauber aus, es wirkte so als würde es nicht den GND Level des Signals erreichen und zwar nur bei jenen Bits, die vom Slave nicht erkannt wurden. Da wir mit dem PCInt arbeiten, können wir keine Flanken, sondern nur Logische Zustände am Pin erkennen. Also 1 für ≥ 2,0 Volt und 0 für ≤ 0,8 Volt (vgl. TTL Logikpegel) . Erreicht nun das 1-Wire Signal nicht den Ground Level, so wird auch keine Logikwechsel erkannt und kein Interrupt geworfen. Schnell war klar, das der Master es wohl nicht immer schafft, uns eine Saubere Null mitzuteilen. In unserer Probeschaltung befand sich ein 4.7k Ohm Widerstand als Pull Up. Dies ist ein nach der 1-Wire Spezifikation typischer Wert für diesen Anwendungsfall. Jedoch ist der Raspberry Pi in Verbindung mit unserer Schaltung nicht immer in der Lage, die Leitung auf Ground zu ziehen. Eine genaue Nachforschung steht noch aus. Nach entfernen des 4.7k Ohm Widerstandes und aktiveren des Internen Pull Ups am 1-Wire Pin des HR20 wurden unsere Bemühungen sofort mit Erfolg belohnt. Der SEARCH ROM Befehl wurde Fehlerfrei erkannt und unsere 64Bit ID wurde sofort Fehlerfrei an den Master übertragen, der uns in seine Slave Liste mit aufnahm.
Da der interne Pull Up des AVRs zwangsläufig die Batterie des HR20 unnötig leer ziehen würde, haben wir versucht einen passenden externen Widerstand zu finden. Der interne Pull Up hat 20k-50k Ohm, jedoch arbeitet unser ATmega mit einer Spannung von 2,7 Volt. Der Master aber mit 3,3 Volt, daher ist ein größerer Widerstand erforderlich, da mehr Spannung "abgeführt" werden muss. Nach einigen Versuchen war eine Stabile Kommunikation mit einem 56K Ohm Widerstand möglich.
Weitere Versuche
Zur Vorbereitung der Implementation des 1-Wire Busses in die OpenHR20 Software, wurde versucht eine Stabile Buskommunikation auch mit 4 Mhz Systemtakt zu gewährleisten. Dies war nötig, da der Honeywell HR20 Original mit ebendiesem Takt arbeitet. Doch schnell zeigte sich, das bei diesem halben Takt keine Vernünftige erkennung der Flanken mehr möglich war. Schon bei 8 Mhz bewegten wir uns in einem sehr schmalen Zeitfenster, dieses wurde nun noch einmal halbiert.
Da wir das Projekt nun aber ersteinmal Vorran bringen wollen, haben wir beschlossen den Systemtakt der Endsoftware zu erhöhen und später in einer Optimierungsrunde zu versuchen, den Takt wieder zu verringern.
Ergebnis
Der Versuch hat gezeigt das es durchaus möglich ist, den 1-Wire Slave auch mit dem Pin Change Interrupt umzusetzen. Eine Flankenerkennung ist zwar hilfreich, aber nicht zwingend erforderlich.
Mögliche Verbesserungen
Da wir gern unabhängig von der Geschwindigkeit des Masters sein möchten und vor allem Sicherstellen wollen, das die Slave Software auch Fehlerfrei mit anderen 1-Wire Mastern zusammen arbeiten kann, ist eine dynamische Anpassung der Zeitintervalle zur Laufzeit denkbar.
Phase 2: Umsetzung
Nach erfolgreicher Portierung der 1-Wire Slave Software auf den ATmega169P wurde begonnen diese mit der OpenHR20 Software zu verheiraten. Dazu war zuerst eine erhöhung des Systemtaktes auf 8 Mhz nötig. Da wir schon bei Phase 1 darauf geachtet haben Doppelbelegungen von Timer und Ports zu vermeiden, waren sonst keine weiteren Hardware bezogenen Anpassungen nötig.
Probleme
Hardware
Normalerweise arbeitet 1-Wire mit einem Pegel von 5 Volt, unser HR20 jedoch wegen den Batterien nur auf 3,3 Volt (2,7 Volt). Zwar kann man den 1-Wire Bus auch mit 3,3 Volt betreiben, aber eine niedrigere Spannung ist bei längeren Leitungen natürlich eine zusätzliche Problemquelle.
Um die Schaltung des HR20 nicht verändern zu müssen, empfiehlt es sich also einen Pegelwandler von 5 Volt auf 3,3 Volt mit in den Bus zu hängen. Erste Recherchen zeigten den MAX3373E als idealen Kandidaten. Der MAX3372E würde für unseren Anwendungsfall auch ausreichen, 1-Wire arbeitet normal nur mit 16,3 KBit/s, dieser war aber kurzfristig nicht verfügbar.
Jedoch erwies sich der MAX3373E aufgrund seiner extrem kleinen Bauform doch nicht als für uns Brauchbar. Als günstige Alternative sind wir auf ein Dokument von NXP gestoßen, in dem Beschrieben wird, wie man mit zwei Handelsüblichen MOSFETs einen brauchbaren Bidirektionalen Pegelwandler aufbauen kann. Dies hat den Vorteil das wir extrem Günstige Bauteile mit TO-92 Bauform verwenden können.
Für den ersten Versuchsaufbau haben wir uns für BS170 MOSFETs entschieden wie sie für ähnliche Anwendungsfälle schon verwendet wurden. (vgl. I2C-Level-Shifter by Binerry)
Software
Durch die erhöhung des Systemtaktes sind alle Zeitabhängigen Funktionen des HR20 ausgefallen. Dazu zählen unterandrem die Motorlichtschranken und das Drehrad. Eine einfache Anpassung der jeweiligen Timer führte nicht zum gewünschten Erfolg. Ein Debuggen des Zeitverhaltens mit dem Oszilloskop ist nötig.
Verwendung
Analog zum DS18S20 verwenden wir zur Übermittlung von Daten ein Scratchpad. Dabei handelt es sich um einen 64Bit großen Speicherbereich, welchen wir per Befehl auslesen und teilweise auch beschreiben können. Dies ist anfangs für unser Projekt ausreichend, da wir nur die aktuell gemessene Temperatur lesen und die gesetzte Temperatur rücklesen oder beschreiben wollen. Eine Umsetzung der Restlichen HR20 Funktionen wie setzen und lesen der Zeitfenster, Nachtabsenkung und Fenster Offen erkennung sind zwar angedacht, aber noch nicht nötig.
Raspberry Pi
Software
1-Wire
Als 1-Wire Master wird das OWFS 1-Wire File System verwendet.
Infrastruktur
1-Wire Verkabelung
Zur Verbindung der einzellnen Thermostate verwenden wir RJ-12 Kabelverbindungen. Diese sind bei 1-Wire Vernetzungen üblich und als Offener Standard für 1-Wire dokumentiert.
Spannungsversorgung
Ideen Sammlung
iButton Schnittstelle
iButtons sind eine Technik ähnlich der RFID Chips, jedoch auf 1-Wire Basis. Die Optisch einer Knopfzelle ähnlichen iButtons sind klein, robust und könne gut am Schlüsselbund mitgeführt werden.
Es wäre denkbar in jedem Raum einen iButton Reader anzubringen. Damit wäre es möglich ein Vordefiniertes Heizprogramm für den Nutzer zu starten, sobald dieser seinen iButton kurz in den Reader steckt.
Weblinks
Honeywell HR20
1-Wire