Gefriertruhenüberwachung mit PIC und 2-zeiligem LCD

  • Hallo zusammen!


    Irgendwann im Frühjahr 2021 ist mir aufgefallen, daß meine Gefriertruhe fast immer läuft, wenn ich daran vorbeikomme. Ich habe dann ein Thermometer in die Truhe gelegt und ein Engeriekostenmessgerät angeschlossen. Nach 24 Stunden konnte ich folgende Werte ablesen:

    2,05 kWh Verbrauch, 85% Einschaltdauer und -28°C Temperatur.

    Am Einstellregler zu drehen hat nicht viel gebracht.


    Deshalb habe ich eine Steuerung zum Zwischenstecken in die Netzzuleitung der Gefriertruhe gebaut, die über ein Relais einfach die Stromzufuhr unterbricht.

    Achtung!

    Arbeiten an Netzspannung sind lebensgefährlich und dürfen nur von zugelassenen Elektro-Fachkräften ausgeführt werden!







    Die Berechnung der Einschaltdauer war unerwartet ein größeres Problem bei der Programmierung.

    Die Formel ist ja einfach: ED = Einschaltzeit / Gesamtzeit * 100%

    Je länger nun die Gesamtzeit wird, desto träger reagiert das Ergebnis auf Veränderungen. Deshalb wollte ich für die Berechnung nur die Zeiten der letzten 24 Stunden "gleitend" verwenden.


    Hardwaretechnisch könnte man bei jeder Messung das Zustand-Bit der Strommessung in ein Schieberegister schieben und nach der gewählten Zeit fällt es automatisch hinten wieder raus. Zum Auslesen müsste man das Schieberegister einmal im Kreis drehen und die gesetzten Bits aufsummieren.

    Da ich zum Einen kein so langes (z.B 16 kBit) Schieberegister kenne und zum Anderen die Hardware schon fertig hatte, mußte eine Software Lösung her.


    Jetzt könnte man nach Ablauf der gewählten Zeit beide Zeiten auf 0 setzten und von vorne beginnen. Dann würde die Einschaltdauer immer bei 100% oder 0% beginnen, je nachdem, ob der Kompressor gerade läuft oder nicht. Die Anzeige müßte sich erst wieder angleichen und ein kurzer Blick darauf im Vorbeigehen wäre nicht sehr aussagekräftig.


    Als Kompromiss werden nun nach 19,1 Stunden beide Zeiten halbiert, schon deshalb, weil das einfach durch Rechtsverschieben um 1 Bit geht, ohne wirklich rechnen zu müssen. Anschließend läuft die Messung von 9,56 Stunden Startwert weg. Das wiederholt sich dann im Dauerbetrieb alle 9,56 Stunden. Da in der alten Hälfte wieder eine noch ältere Hälfte steckt usw., nähert sich das Ergebnis nur langsam an den Endwert an, ähnlich einer R-C Ladekurve. Es ist eben ein Kompromiss mit dem man aber gut leben kann.

    Oder kennt jemand eine Methode mit der man tatsächlich nur die Werte der letzten 24 Stunden im Dauerbetrieb gleitend berechnen kann?


    Das Gerät habe ich im August in Betrieb genommen. Da lag die Einschaltdauer bei 40%. Mit abnehmender Umgebungstemperatur ist sie dann immer weiter zurückgegangen bis auf 22% im Winter.


    Für die Programmierung habe ich über 50 Stunden benötigt.


    Diese doch lange Zeit für ein relativ einfaches Projekt liegt auch daran, daß ich zum Ersten mal einen PIC16F1708 Mikrocontroller verwendet habe, weil der bei r... nur 1,55 Euro kostet (Stand 2021).

    Der kennt 49 Befehle statt der mir bisher bekannten 35. Auch hat er kein EEPROM, statt dessen kann man Teile des Programmspeichers neu beschreiben, was unterschiedlich ist.


    Bisher habe ich für Temperaturmessungen immer DS18S20 oder DS18B20 Sensoren verwendet. Beim 1-wire Bus müssen aber Time-Slots im µs-Bereich eingehalten werden. Bei längeren Leitungen gibt es dadurch leicht Übertragungsprobleme, was man hier im Forum auch immer wieder lesen kann.

    Deshalb habe ich nach einem Sensor gesucht, der sich in aller Ruhe auslesen läßt.


    Als Temperatursensor wird hier ein MCP9808 verwendet, den ich aber erst auf eine DIL-Adapterplatine gelötet habe, damit ich ihn anschließen konnte.

    Man kann ihn über den I2C-Bus mit max. 400 kHz auslesen. Wenn sich SCL mindestens 25 ms (Timeout) nicht mehr ändert, also High oder Low bleibt, dann wird die I2C Schnittstelle resetet. Daraus ergibt sich die minimale Taktfrequenz von > 20 Hz. Bei diesem Projekt beträgt der Bus-Takt 12,5 kHz. Auch wenn bei 1,5 m Leitungslänge keine Übertragungsprobleme auftreten sollten.


    Die Mikrocontroller Pins für den Bus werden beide als open Drain betrieben, das heißt auch die Taktleitung braucht einen Pull-up Widerstand. Dadurch ist es dem Slave möglich, wenn er nicht mehr mitkommt, einfach SCL auf Low zu halten (Clock Stretching). Das kannte ich bisher noch nicht.


    Das Programm 'gefriertruhenueberwachung.asm' ist in Microchip Assembler geschrieben, zum Hochladen habe ich die Endung in '.txt' geändert.


    Seit Ubuntu 20.04 und MPLAB X IDE 5.35 kommt immer:

    Configuration Loading Error:

    MPASM is not supported on 64 bit Operating Systems. Please consider migrating your project "Gefriertruhenueberwachung" configuration "default" to XC8 Assembler or continue to use a previously released IDE.


    Die Programmierung funktioniert bisher trotzdem noch.

    Aber soll das heißen, daß Microchips eigene Entwicklungsumgebung die "Muttersprache" der kleinen PICs, die in allen Datenblättern gut dokumentiert ist, nicht mehr unterstützt?

    Mit dem XC8 Compiler habe ich noch keinen Assembler Code zum Laufen gebracht. Das kann natürlich daran liegen, daß ich bisher zu wenig Lebenszeit investiert habe.

    Da fällt mir eine Aussage eines ehemaligen Mathematik Lehrers ein, auch wenn es damals eher um mathematische Gleichungen ging:

    Quote

    ... und wenn man etwas nicht versteht, da muß man bohren, bohren, bohren!

    und an anderer Stelle:

    Quote

    Auch Probieren ist eine Art des Lösens - und nicht immer die schlechteste.


    In diesem Sinne.


    Gruß

    Raspi_9

  • Klingt nett...

    Für die Einschalt dauer würde ich einfach die letzten beiden (oder 4 oder 6 oder 8 ) vollen Ein/Aus-Zyklen nehmen. Wenn du alle paar Minuten mitten in der Ein- oder Aus-Phase berechnest, läuft dir jedesmal der Wert nach oben oder unten weg. Je länger dein Zeitraum für die gleitende Mittelung, desto geringer das Weglaufen, desto größer aber auch die Trägheit. Bei Auswertung voller Zyklen dürfte die Abweichung dagegen geringer sein.

    Es kommt jetzt etwas drauf an, wie lange die Schaltzyklen sind. Nehmen wir an, bei einer gegebenen Hysterese schaltet das Teil alle 20 Minuten, dann kannst du mit einem Zyklus (die letzten beiden Schaltzeiten - aus/ein oder ein/aus) eben alle 20 Minuten einen neuen Wert haben, der recht aktuell ist, aber auch etwas schwanken dürfte. Nimmst du 2, 3, 4 Zyklen (die letzten 4, 6, 8 Schaltzeiten), hast du beständigere und längerfristig zutreffende Werte aber auch eine etwas größere Trägheit. 24 Stunden erscheint realtiv sinnvoll, weil dann Temperaturschwankungen über Tag ausgeglichen werden. Um aber das Weglaufen der Werte zu verhindern, könntest du so viele volle Zyklen in die Rechnung nehmen, wie in den letzten mehr als 24 Stunden durchlaufen wurden, also nicht genau 24 Stunden, sondern ggf. etwas mehr, so dass ein voller Zyklus noch abgeschlossen wird. Andernfalls könntest du zufällig eine ungleiche Zahl von Ein- und Aus-Zyklen haben. Bei ca. 30 Minuten pro Schaltung wären das zum Beispiel 24 Ein- und 23 Aus-Schaltzeiten. Das gibt einen Fehler von 1/47, also über 2%. Bei der nächsten Messung womöglich andersrum, als minus 2%. Dann sind es schon 4% Schwankung. Wenn die überzählige Messung eine lange Schaltzeit hat (nachts, wenn es kühl ist), wird der Fehler noch größer.

    Interessant wären vielleicht auch zwei Anzeigewerte - einer für 24 Stunden und einer für eine kürzere Zeit (1, 2, 3, 4, ... Zyklen) oder gerade Zyklenzahl der letzten mindestens 2 Stunden - also "aktueller" Verbrauch.

    Tatsächlich eine Sache, wo man sich den Kopf zerbrechen kann.

    Oh, man kann hier unliebsame Nutzer blockieren. Wie praktisch!

    Edited once, last by Gnom ().

  • Dein Vorschlag @gnom , zusätzlich eine Kurzzeit-Einschaltdauer anzuzeigen, hat mir keine Ruhe mehr gelassen, da die 2. Zeile eh noch frei war.



    Die Anzeige der Durchschnitts-ED läuft in 'gefriertruhenueberwachung_v2.asm' weiterhin nach der alten Methode, aber nun mit doppelter Messzeit.


    Für die Kurzzeit-ED wird die OnZeit (Kompressor ein) und die OffZeit (Kompressor aus) gemessen.

    Die Formel ist dann: ED = OnZeit / (OnZeit + OffZeit) * 100%

    Immer wenn eine Änderung des Schaltzustandes (Ein oder Aus) erfolgt, steht eine neue Zeit für die Berechnung zur Verfügung und die neue Kurzzeit-ED wird ausgegeben.

    Das ist die kürzeste Möglichkeit, für ein abgeschlossenes Intervall die Einschaltdauer zu berechnen.


    Es geht aber noch weiter, dazu ein Beispiel.

    Beim letzten, abgeschlossenen Intervall war die OffZeit 24 Minuten und die OnZeit 8 Minuten, das ergibt 25% ED.

    Während der dann laufenden OffZeit werden frische Lebensmittel in die Gefriertruhe gelegt. Die Temperatur steigt jetzt schneller an und nach 20 Minuten (neue OffZeit) schaltet der Kompressor wieder ein. Die letzte, abgeschlossene OnZeit ist noch 8 Minuten, das ergibt gerundet 29% ED. Ein Springen der Anzeige von 25% auf 29% ist hier unvermeidlich.

    Der Kompressor wird nun länger laufen, weil das frische Gefriergut immer noch Wärme abgibt.

    Die letzte, abgeschlossene OffZeit ist jetzt 20 Minuten. Nach 8 1/2 Minuten OnZeit beträgt die ED bereits 30% und es geht weiter nach oben. Deshalb wird ab hier die ED ausgegeben mit einem zusätzlichen Pfeil nach oben, als Zeichen, daß das laufende Intervall noch nicht abgeschlossen ist, der Wert aber bereits höher ist als der vorherige und es in diese Richtung weitergeht. Dadurch ist die Anzeige aktueller und es wird ein Sprung vermieden.

    Wenn nach 10 Minuten (neue OnZeit) der Kompressor wieder abgeschaltet wird, beträgt die ED 33%, der Pfeil nach oben verschwindet.


    Programmtechnisch werden die jeweiligen Register alle 2,1 Sekunden inkrementiert und dann eine neue Berechnung durchgeführt. Eine Ausgabe erfolgt aber nur, wenn sich der Schaltzustand des Kompressors geändert hat oder bei laufender OnZeit die letzte Ausgabe überschritten ist (mit Pfeil nach oben) oder bei laufender OffZeit die letzte Ausgabe unterschritten ist (mit Pfeil nach unten).

    Die Pfeile sind übrigens nicht im Standard Zeichensatz des LCD's enthalten, sondern sind selbst definierte Zeichen, die bei der Initialisierung ins CGRAM geschrieben werden.


    Wie man sieht, könnte man mit der Berechnung der Einschaltdauer ein eigenes Thema aufmachen.


    Gruß

    raspi_9