Anzeige
Die Anzeigeeinheit verwendet einen ATmega128 mit,
wie auch der Sensor, ebenfalls 3,6864 MHz.
Dieser wurde gewählt weil er zwei serielle Schnittstellen hat, eine zur
Messeinheit und eine zu einem PC (RS
Das Bluetooth-
Die Anzeige fragt also einmal pro Minute den Wasserstand der Zisterne
ab, errechnet daraus die enthaltene Wassermenge und zeigt sie an.
Nebenbei errechnet sie auch die Differenz zum Vortag und zur vergangenen Stunde. Die Uhrzeit, die
dabei angezeigt wird, bezieht sich auf den letzten Einschaltzeitpunkt,
sie kann jedoch über die serielle Schnittstelle (oder über Bluetooth oder
dem Homebus) auf die tatsächliche
Tageszeit eingestellt werden. Alternativ
kann ein DCF77-
Zur Ermittlung des Wasserstandes werden 10 Messwerte des Sensors gemittelt. Danach wird die Versorgungsspannung des Sensors abgeschaltet. Dies spart nicht nur Strom, es verringert auch die Eigenerwärmung was wiederum der Genauigkeit der Temperaturmessung zugute kommt. Außerdem wird der Sensor so zurückgesetzt falls er sich einmal "aufhängen" sollte.
Die Praxis hat gezeigt, dass die Entfernungsmessung sehr genau und wiederholbar arbeitet. Tatsächlich kann man bei laufenden Messungen während der Wasserentnahme die Liter direkt mitverfolgen. Während es regnet ist die Wasseroberfläche jedoch ziemlich in Bewegung und auch Spritzer können Fehlmessungen verursachen sofern man nicht über einen beruhigten Zulauf verfügt, deshalb die Mittelung.
Die Anzeigeeinheit ist für always on
gedacht und enthält deshalb auch
einige Maßnahmen zur Energieeinsparung. Der Stromverbrauch liegt laut
eines Energiemessgeräts von Conrad Electronic bei 0,0 W (also
unterhalb der Messauflösung
von ca. 2 W).
Als Gehäuse habe ich mich für ein Heidenreich ZA16 entschieden, das zufällig greifbar war. Es eignet sich zur Wandmontage, ist einfach zerlegbar und die Front passt perfekt für das gewählte Display. Es ist nicht gerade stylish aber neben den anderen Geräten im Heizungsraum macht es sich doch ganz gut...
Anschluss der Messeinheit
Für den Anschluss der Messeinheit wurde ein Standard-Klingeldrähte
) funktionieren. Von
parallellaufenden Steuerkabeln sollte man aber besser absehen (Wenn sie nun
schon mal drin sind, nun ja, probieren Sie es. Wenn sie 80 cm unter der Erde liegen
sollte es wohl auch wenig EMV-
Die Anzeige schaltet die 15 V (Unreg) über eine einfache Konstantstromquelle
bestehend aus T1, D1 und R3 an. Damit wird ein Spannungseinbruch
in der Anzeigeeinheit und/oder Überlastung von T1 verhindert.
Die Konstantstromquelle kostet
im Vergleich zu einem simplen
Schalttransistor gerade einmal zwei Dioden (als
SMD in einem Gehäuse erhältlich und wirklich billig) und einen Widerstand.
Die Stromquelle ist dennoch nicht kurzschlussfest. Wenn die Sensorversorgung
kurzgeschlossen ist liefert T1 etwa 40 mA aus der Versorgung was einer
Verlustleistung von ca. 0.6 W entspricht. Dies würde eine Überhitzung und den
Ausfall von T1 innerhalb weniger Sekunden bewirken.
Der 15 Ω-
Terminierung
Laut Lehrbuch müssen die Leitungen einer RS485-
Die 120 Ω sind leider auch keine Naturkonstante sondern der Wellenwiderstand der typischerweise verwendeten Leitung. Wenn Sie andere Leitungen verwenden müssen sie den Terminierungswiderstand anpassen um optimale Ergebnisse zu erzielen.
Was ist Wellenwiderstand?
Einstein sagt, es gibt nichts schnelleres als das Licht. Wenn nun die Stromquelle am Display einschaltet, woher weiß sie was am Ende der Leitung für eine Last anliegt? Obwohl die Leitung vielleicht nur 10 m lang ist (Licht braucht dafür im Vakuum etwa 30 ns). Nun, sie weiß es nicht. Zunächst fließt der Strom der dem Wellenwiderstand der Leitung entspricht. Am Ende angekommen wird geht ein Teil des Stromes in die anliegende Last, der Rest wird reflektiert und kommt 30 ns später wieder an der Stromquelle an. Dort äußert er sich als negative (oder auch positive, je nach Last) Spannung, die in Reihe mit der Versorgung nun einen höheren (oder niedrigeren) Strom in die Leitung treibt. So überlagert er sich mit dem Strom der bisher geflossen ist und der Strom pegelt sich letztlich auf den tatsächlich benötigten Wert ein. Dabei können an der Last Überschwinger eintreten die im Extremfall das Doppelte der anliegenden Spannung ausmachen.
Tatsächlich ist die Signalgeschwindigkeit in den typischerweise verwendeten Leitungen nur etwa 2/3×c so dass wir hier eher von 45 ns für 10 m ausgehen müssten.
Im Alltag denkt man da nicht weiter darüber nach aber das passiert jedes mal wenn Sie das Licht einschalten!
Eine Terminierung ist nötig, wenn die Anstiegszeiten des Signals in die Nähe der Laufzeit auf der Leitung kommen. Wir verwenden Slew Rate limited Treiber, also Treiber mit bewusst verringerter Anstiegszeit, was Reflexionen reduziert. Zudem reagiert der Empfänger nicht auf Flanken sondern tastet das Signal jeweils in der Mitte eines Bits (bei 9600 Baud also nach etwa 50 µs) ab. Bis dahin sind Reflexionen längst abgeklungen. Deshalb habe ich auf die Terminierung der Sensorleitung verzichtet. Bei mir funktioniert dies mit etwa 10 m Sensorkabel absolut problemlos. Auch auf dem Oszilloskop ist nichts von Reflexionen zu sehen.
Tatsächlich wären etwaige Reflexionen in 50 µs etwa 500 mal durch die Leitung gelaufen. Bis dahin sind sie allein durch den ohmschen Widerstand der Leitung völlig aufgezehrt, sie sind einfach weg.
Bei höheren Baudraten wäre die maximale Kabellänge ohne Terminierung kürzer. Die Reflexionen müssen bis zur Abtastung unter die Schaltschwelle des Empfängers abgeklungen sein um den korrekten Signalpegel sicher zu erkennen.
Ich empfehle, die Leitungen nicht zu terminieren. Es ist schlicht unnötig weil alle Reflexionen bis zum Abtastzeitpunkt abgeklungen sind.
Wenn Sie es trotzdem tun wollen, müssen Sie den Konstantstrom erhöhen, also R3 verringern und konsequenterweise auch R8 um den nötigen Basisstrom zu treiben, weil sonst die Versorgungsspannung am Sensor während des Sendens einbrechen würde.
Meine Wahl für diesen Fall: R3=6,8 Ω, R8=4,7 kΩ aber dies ist nur eine Prognose, ich habe nicht terminiert und habe das auch nicht getestet.
Damit erhöhen Sie zwangsläufig die Belastung der Display-
Wenn Ihr Sensorkabel allerdings sehr lang ist (einige zig oder hunderte von Metern) sollten Sie mit dem Oszilloskop nochmal nachmessen bevor Sie den Sensor vergießen.
Schnittstellen
Die Anzeigeeinheit verfügt über zwei USARTs. USART0 wird verwendet zur
Kommunikation mit der Messeinheit über einen RS485 physical Layer,
USART1 kann als Bestückungsvariante oder auch durch Jumpern
entweder
über Bluetooth, RS232 oder RS485 mit einem Host-PC kommunizieren. Die
Senderichtung geht dabei immer über alle Schnittstellen, nur der
Empfang wird umgejumpert
.
Das zugehörige Jumperfeld ist riesig (zumal laut Datenblatt das
Bluetooth-
Die Unterstützung für RTS/CTS-Handshake kann per Define in den Sourcen
erfolgen oder per Konfiguration. In meinen Sourcen ist das Handshake aktiviert,
sie können es jedoch durch ein Kommando deaktivieren.
Dies ist nötig, wenn an der Host-
Der USART unterstützt über Interrupt-Flags das für RS485 als
Halbduplex-
Kommunikation mit dem Host
Die Anzeigeeinheit kommuniziert mit 9600 Baud, 8N1 mit dem Host (PC
oder Laptop). Da im Zusammenhang mit PCs das 9. Bit eher problematisch ist
wurde hier auf die Verwendung desselben
verzichtet und die gesamte Kommunikation erfolgt in lesbaren
ASCII-Zeichen. Die Schnittstelle ist immer aktiv. Auf ein Select
Device
, wie es im Bus mit mehreren Geräten nötig wäre, wurde vorerst
verzichtet.
Das vorgesehene Bluetooth-
Die Sende- und Empfangsroutine ist interruptgesteuert. Senden erfolgt klassisch über einen FIFO im SRAM. Beim Empfang werden die Daten gesammelt bis ein <LF> eintrifft. Dann wird die gesamte Zeile auf einmal ausgewertet. <CR>s werden ignoriert. Ein Kommando beginnt immer mit einem Kommandowort gefolgt von eventuellen Parametern, jeweils durch Leerzeichen getrennt.
Und wenn kein <LF> kommt? Jeder drückt doch <Return> nach einem Kommando!
NEIN! Das ist der klassische Buffer Overflow Attack! Zeichen kommen auch noch
wenn sie nicht mehr erwartet werden wenn der Host nicht gutartig
ist oder
es auch nur EMV-Probleme gibt.
Und sie werden dann in einem Speicherbereich gespeichert, der eigentlich gar nicht
dafür vorgesehen war. Die Folgen können vermurkste Variablen und damit falsche Anzeigen,
ein schlichter Absturz oder auch die
Ausführung von unbeabsichtigtem oder fremdem Code sein!
Ich habe mich hier für einen Buffer Wrap
entschieden, d.h. Zeichen, die nicht
mehr in den Puffer passen überschreiben ihn von vorne wieder. Man könnte auch
Zeichen ignorieren sobald der Puffer voll ist, das ist Geschmackssache.
Hauptsache, nicht über den Puffer hinaus schreiben!
Ein solcher Angriff kann in beide Richtungen gehen: Er sendet mehr Zeichen als Sie erwarten oder er provoziert mehr Antworten als Ihr Sendepuffer verkraften kann. Seien Sie auf beides vorbereitet!
Glücklicherweise gestatten es die unterschiedlichen Formate von
Host-Kommandos und Telegrammen des Bluetooth-
Ein Bluetooth-LMX9830_READY
, welches das
Bluetooth-SPP_INCOMING_LINK_ESTABLISHED
und, falls die
Verbindung abbricht, möglicherweise abwechselnd ein SPP_LINK_RELEASED
.
Durch diese Telegramme können wir erkennen ob überhaupt ein
Bluetooth-
RTC
Timer0 erzeugt einhundert mal pro Sekunde einen Interrupt als
universeller Timer. Nebenbei wird daraus eine HH:MM:SS-
Am Ende der Hauptschleife wird ein Sleep ausgeführt, der einerseits nichts kostet, den Stromverbrauch des Controllers andererseits aber erheblich senkt da bis zur nächsten 1/100 Sekunde deutlich weniger verbraucht wird.
DCF77
Zur Synchronisation mit der offiziellen Normalzeit kann ein
externer DCF77-
Ein spezieller Typ ist nicht erforderlich, er muss jedoch mit 5 V
Versorgungsspannung arbeiten können und ein TTL-
Ein sehr simpler Algorithmus sorgt für ein 'sanftes' Nachführen der RTC.
Wenn die empfangene Zeitinformation um mehr als 60 s von der RTC abweicht
wird die Zeit hart
gestellt. Dazu müssen zwei aufeinanderfolgende Telegramme
empfangen werden, die bis auf 60 s die gleiche Abweichung zur RTC aufweisen.
(Tatsächlich habe ich auch schon Telegramme mit fehlerhafter Zeit empfangen,
die trotzdem als Fehlerfrei erkannt wurden. Mehrfache Bitfehler die zufällig
die korrekte Prüfsumme ergeben machen dies möglich.)
Dabei können Minuten- oder Stundenereignisse
verlorengehen da sie nur vom Timer Interrupt ausgelöst werden.
Bei kleineren Abweichungen läuft die RTC 1% schneller oder langsamer bis die Abweichung weniger als 1 s beträgt, d.h. ein Timer Interrupt wird ausgelassen oder ein fiktiver zusätzlicher Interrupt wird eingefügt.
Auf diese Weise gehen im Gegensatz zum harten Stellen der Uhrzeit keine Sekunden- oder Minutenereignisse verloren.
Dadurch wird allerdings auch die Genauigkeit der Uhr auf ±1 s zur hochgenauen Normalzeit des DCF77 reduziert. Sicherlich noch ausreichend um den geplanten Zug zu erreichen...
Sie können das stat-Kommando benutzen um zu sehen ob die DCF-
Auf dem Display erscheint ein Antennensymbol (¡) wenn ein Telegramm störungsfrei empfangen wurde. Die Systemzeit muss dann jedoch noch nicht stimmen da sie erst beim zweiten Telegramm gesetzt wird. Umgekehrt kann bei korrekter Systemzeit das Antennensymbol erlöschen wenn der Empfang gestört ist. Die Zeit läuft dann quarzgenau weiter.
DCF77-Empfänger
Es rentiert sich nicht, hier in paar Euro zu sparen um einen billigeren
Empfänger einzusetzen. Er würde Ihnen mehr Ärger und Zeit kosten als
die paar Kröten wert sind!
Wenn sie es billig haben wollen, schlachten Sie eine chinesische 5 €-
Verwenden Sie einen hochwertigen Empfänger wie den Meinberg RU226 und achten Sie auf die Montageanleitung! Der Empfänger muss mit der Querseite der Ferritantenne möglichst genau nach Frankfurt zeigen (da befindet sich der Sender) und darf nicht auf Metall oder in der Nähe metallischer Oberflächen oder Leiterschleifen montiert werden.
Auch Störsender
wie das Display selbst und
insbesondere sein Bluetooth-
Die DCF77-alten
Fernseher in der Nähe betreiben könnte auch dieser
einen störungsfreien Empfang verhindern.
Bei mir im Labor hatte ich überall Störungen (viele Computer und andere Störquellen) bis auf eine kleine Stelle auf meinem Schreibtisch. Wenn Sie Empfangsprobleme haben, verschieben Sie den Empfänger um einen halben Meter und probieren Sie es erneut. Irgendwann muss es klappen...
Signal-Ausgänge
Da noch Klemmen des Gehäuses unbenutzt waren, habe ich noch zwei potentialfreie Signalausgänge hinzugefügt. Es handelt sich dabei um die Fototransistoren eines Optokopplers, die für externe Schaltaktionen zur Verfügung stehen. Für jeden von diesen kann eine Schwelle festgelegt werden oberhalb und/oder unterhalb derer der Ausgang aktiv ist.
Die Fototransistoren haben einen gemeinsamen Emitter, sie sind also geeignet, zwei Eingänge einer externen Schaltung gegen deren Masse zu ziehen.
Jeder Ausgang hat zwei Parameter, Aktiv unterhalb
und Aktiv oberhalb
.
Die Werte sind in Litern, der Wertebereich ist von 0 bis 65535.
Ein Aktiv oberhalb
von 65535 wird also niemals schalten, ebenso wenig wie
ein Aktiv unterhalb
von 0 l.
Durch intelligente Wahl derselben sind mehrere Konfigurationen möglich, z.B.
- Ausgang 1: Warnung wenn Füllstand < 1000 l
Ausgang 2: Schaltet Nachspeiseventil wenn Füllstand < 200 l - Ausgang 1: Aktiv wenn Füllstand <500 l,
Ausgang 2: Aktiv wenn Füllstand >5800 l (Überlaufwarnung)
Wenn Sie einen Ausgang nicht benutzen wollen und die Leistung des
Optokopplers sparen wollen, setzen die Aktiv unterhalb
auf 0 und
Aktiv oberhalb
auf 65535. Dann ist der Optokoppler niemals aktiv.
Dies ist auch der Default wenn Sie nichts anderes parametrieren.
Elektrische Sicherheit der Ausgänge
Die Ausgänge sind durch Optokoppler von der Schaltung getrennt, allerdings nur
mit etwa 5 mm Isolationsabstand. Die Schaltung die sie daran
anschließen darf die Leitungen deshalb nicht mit der Netzspannung verbinden sonst
verlieren Sie den Isolationsabstand zum Display und dem Sensor!
Manche Leute meinen, 3 mm sind genug, na ja, no
risk no fun
, ich bevorzuge in solchen Fällen allerdings better
safe than sorry!
Sie dürfen damit also z.B. nicht direkt einen Thyristor schalten, der mit dem Netz verbunden ist. Sie können jedoch den Eingang einer SPS oder einer anderen, vom Netz getrennten Schaltung (z.B. den Parallelport eines PCs) steuern.
Eine Klemme neben der Netzversorgung bleibt frei um 8 mm Sicherheitsabstand zum Netz einhalten zu können.
Anzeige
Hinweis: Die Low-Cost 2×16-vernachlässigt
. Lesen Sie bitte trotzdem die folgenden Zeilen da sie
auch für die 4×20-
Die Anzeige (zwei Zeilen à 16 Zeichen) ist wie folgt aufgebaut:
1234L<PChh:mm:ss
±1234 l/h
±1234*
Die erste Zeile zeigt dabei permanent die Füllmenge in Litern und die
Zeit seit der
letzten System-l
angezeigt und beim
Mittelwert ein großes L
.
Die Zeichen ab Position 5 (<PC
) sind Error-<
erscheinen falls
weniger als 10 Messwerte für die Entfernung empfangen wurden (sehr
wahrscheinlich überhaupt keines, was auf eine unterbrochene
Sensorleitung oder Sensordefekt hinweist) oder ein >
falls mehr
als 10 Werte empfangen wurden. Eigentlich sollte das Display den Sensor
nach dem 10. Wert abschalten. Das >
weist auf einen Defekt im
Bereich der Konstantstromquelle um T1 hin, d.h. das Display kann die
Sensorversorgung nicht abschalten.
Das P
bedeutet Parity-Error und das C
Checksum-
Ein S
erscheint, wenn in der letzten Minute kein einziges Telegramm vom Sensor
empfangen wurde (Sensor Dead
).
Die angezeigte Wassermenge ist bei Erscheinen von mindestens einem dieser Flags unzuverlässig und möglicherweise veraltet oder völlig falsch.
Die Error-
Die zweite Zeile wechselt zyklisch zwischen folgenden Anzeigen:
- Wasserstandsänderung vergangene Stunde und laufende Stunde (mit abschließendem
*
).
Eine positive Menge bedeutet dabei eine Erhöhung des Wasserstandes (Regen) und eine negative entsprechend eine Erniedrigung, also Wasserentnahme. - Anzahl der Power-On, Watchdog- und Brownout-
Resets (wird nur bei Bedarf eingeblendet und weist auf Hard- oder Softwarefehler hin) - Wasserstandsänderung letzter Tag (gestern) und laufender Tag (heute, mit abschließendem
*
) - Sensortemperatur in °C und daraus errechnete Schallgeschwindigkeit in m/s
- Puls-Laufzeit in ms und errechnete Entfernung der Wasseroberfläche vom Sensor in m
Erweiterte Anzeige
Für den Autor hat sich die Low-Cost-Version mit einem zweizeiligen Display als unzureichend erwiesen. So gibt es die Möglichkeit, im Sourcecode auch ein vierzeiliges Display mit 20 Zeichen pro Zeile auszuwählen wenn man bereit ist, sich diesen Luxus auch in Hardware zu gönnen (tatsächlich reden wir hier nur von ein paar Euro!).
Dann werden folgende Werte auf einem vierzeiligen Display wie
z.B. auf einem Winstar WH2004A angezeigt:
1234L<PChh:mm:ss ¡Ê
01234 l/h 01234* Î
01234 l/d 01234* Î
12.3°C 340.1m/s Î
Die erste Zeile ist identisch mit der 2×16-
Die vierte Zeile wechselt zyklisch zwischen folgenden Anzeigen:
- Temperatur in °C und daraus errechnete Schallgeschwindigkeit in m/s
- Anzahl der Power-On, Watchdog- und Brownout-
Resets (wird nur bei Bedarf eingeblendet) - Puls-Laufzeit in ms und errechnete Entfernung der Wasseroberfläche vom Sensor in m
Nur in der erweiterten Anzeige ist auch ein Antennensymbol für den DCF77-Empfang und der Balken zu sehen, der den Füllstand intuitiv erfassbar darstellt!
Ganz rechts wird ein vertikales Balkendiagramm für den Füllstand angezeigt. So können sie optisch den Füllstand mit einem Blick erfassen.
Die 4×20-Anzeige wurde aufgrund der geringen Mehrkosten zum Standard definiert und ich unterstütze das 2×16-Display nicht mehr aktiv. Wenn Sie in Ihren Sourcen die 2×16-Anzeige wählen kann es sein, dass sie nicht wie erwartet funktioniert. Ich bemühe mich auch weiterhin, das 2×16-Display zu unterstützen aber ich teste dies nicht weiter. Verwenden Sie das 4×20-Display und Sie haben keine Probleme.
Hinterleuchtung
Das gewählte LC-Display besitzt eine LED-
Sound
Da wir noch Portpins und Timer frei haben entschloss ich mich,
einen Piezo-Musik
ist dabei monoton, ich wollte eigentlich keinen Synthesizer programmieren...
Sequenzen können programmiert werden für
- Den Systemstart
- Aktiver Signalausgang 1
- Aktiver Signalausgang 2
- Stundenschlag
Allerdings sind die Sequenzen selbst derzeit nur im Sourcecode änderbar und nicht konfigurierbar.
Die Sequenz für den Systemstart ertönt nach jedem Reset und ist nicht deaktivierbar.
Die Sequenz für Signalausgang 1 wird in jeder Minute zur 10. Sekunde wiederholt und klingt etwas aggressiver. Ausgang 1 ist deshalb besser für dringliche Meldungen geeignet.
Die Sequenz für Ausgang 2 ist dezenter und wird nur zu jeder vollen Stunde in der 20. Sekunde wiederholt.
Da dies möglicherweise nervig sein könnte ist eine Zeitspanne programmierbar, außerhalb derer keine akustischen Meldungen erfolgen.
Zusätzlich gibt es eine soundmask mit der folgende Meldungen aktiviert werden können:
- 1: Signalausgang 1 ertönt immer
- 2: Signalausgang 2 ertönt immer
- 4: Stundenschlag ertönt (innerhalb der Freigabezeit)
Um die soundmask zu berechnen, addieren sie die oben genannten Werte
die Sie benötigen. Wenn Sie z.B. Signalausgang 1 immer hören wollen
und den Stundenschlag wünschen ist die soundmask folglich 5.
Der Stundenschlag ist eigentlich nichts, was wirklich in ein Gerät wie dieses
gehört aber ich habe mir lange überlegt, was man aus dieser Hardware noch
machen könnte und aus Langeweile und purem Übermut habe ich ihn implementiert.
Ein Besucher meiner Website hat mir letztlich doch noch eine Idee gegeben (zu Zeiten als Google noch die Suchbegriffe übermittelte): Ab der ersten Serienversion gib es den
Analogausgang
Für Nostalgie-Versionen kann auch auf das LCD verzichtet und ein 100 µA Drehspulmesswerk eingesetzt werden, dass dann den Füllstand in % anzeigt.
Ich habe die Mittelwertbildung des PWM-Signals von Timer 1 C einem RC-Glied überlassen
und für die Umwandlung in einen Analogwert den zweiten, bisher ungenutzten
OpAmp als spannungsgesteuerte Stromquelle benutzt, der somit ein weitgehend
AC-freies Signal erzeugt.
Das Signal ist nicht GND-
Über X12 wird das Messwerk angeschlossen. Zusätzlich zum
analogen Signal steht auch noch das dimmbare Beleuchtungssignal
sowie +5 V zur Verfügung, falls ihr Messwerk eine Beleuchtung
besitzt.
Verwenden Sie für die Zuleitung zum Messwerk eine
verdrillte Zweidrahtleitung, ebenso wie für die Zuleitung
zur Beleuchtung um Übersprechen zwischen dem Analogsignal und dem
steilflankigen Beleuchtungssignal zu minimieren.
Die Pin-Reihenfolge von X12 ist verpolungstolerant
d.h. bei verkehrt herum gestecktem X12
schlägt das Instrument ins Negative aus und die Beleuchtung ist
verpolt, was für Skalenlämpchen egal ist und selbst LEDs tolerieren sollten.
Der Strom ergibt rechnerisch bei 2,7 V am RC-Glied
100 µA so dass Bauteiltoleranzen gut per
Software ausgeglichen werden können.
Eine entsprechende Kalibrierungs-
Der gewählte OpAmp ist kein echter Rail-To-Rail Typ deshalb können wir nicht den gesamten 5 V Spannungshub ausnutzen. Er kann 0 V recht gut darstellen aber Ausgangsspannungen nahe VCC werden nicht erreicht.
Da der Timer 8 Bit Auflösung hat kann der Anzeigewert nur auf etwa 1% genau eingestellt werden aber genauer kann man ein analoges Messwerk ohnehin kaum ablesen. Messungen mit einem genauen Digital-Amperemeter bestätigen eine Genauigkeit besser als 1% des Vollausschlags.
Wenn Sie auf das LCD verzichten, setzen Sie unbedingt den Display-Typ
auf Analog. Die meisten Funktionen würden zwar auch mit LCD-
Nun, das war wohl die letzte Inspiration die ich von einem Besucher bekommen
sollte denn seit September 2013 scheint Google keine Keywords mehr zu übermitteln.
Deshalb kann ich nur empfehlen, benutzen Sie nicht Google für die Suche.
Nur Google weiß noch, wonach sie gesucht haben. Ich kann meine Seite und mein Projekt nicht mehr
verbessern denn ich erfahre nicht, wonach sie gesucht haben
(wer sie sind erfahre ich sowieso nicht, auch wenn Google es wahrscheinlich weiss).
Benutzen sie nicht Google!
Natürlich können Sie trotzdem Google benutzen wenn Ihnen danach ist
und Sie können mir einfach eine Email schreiben, was ihnen an meiner
Seite fehlt. Aber dieser Datenschutz-
Stackchk
Ein Modul namens Stackchk
wurde hinzugefügt um die Reserve an freiem Speicher
(also zwischen Heap und Stack) zu schätzen. Dies ist nur aktiv wenn Sie die Variable
WITH_STACKCHK
per #define erzeugen. Sie können das in den Project-Properties
unter Compiler
-Symbols
erledigen. Andernfalls reduzieren sich alle Calls
auf die Funktionen auf ein simples Return.
Ein guter Optimizer sollte Calls auf ein Return eliminieren. Leider ist dies
in der aktuellen Version nicht der Fall aber wir verlieren dadurch lediglich
drei Bytes an Programmspeicher, was normalerweise kein Problem darstellt.
In der aktuellen Version zeigt dies knapp 300 Bytes Reserve so dass wir uns keine Gedanken über eine Stack-Kollision machen müssen.
Kommandos
Folgende Kommandos sind bisher implementiert:
- Calibrate: Erlaubt die Kalibrierung der Spannungsteiler. Der Benutzer wird nach den genauen Werten der jeweiligen Spannungen gefragt und der Controller errechnet daraus die Korrekturwerte für den AD-
Wandler.
Die normale Funktion des Displays wird während der Kalibrierung angehalten. Das Backlight wird abgeschaltet um den Ripple auf der Unreg zu reduzieren. Besser ist es jedoch, das Gerät zur Kalibrierung mit 24 V= aus einem Labornetzgerät zu versorgen.
Dieses Kommando endet stets mit einem Neustart des Geräts. - ClearErrors: Löscht alle Fehlerzähler (Watchdog und Brownout) sowie die Fehlermeldung des Displays.
- DCFInv <0|1>: invertiert das Signal des DCF77-
Empfängers. 0 bedeutet nicht invertierend, 1 entsprechend invertierend. Um herauszufinden, welche die richtige Einstellung für Ihren Empfänger ist, beobachten sie die blaue LED. Sie muss jede Sekunde kurz aufblitzen. Wenn sie die meiste Zeit an ist und nur kurz dunkel wird ist die Einstellung falsch. - Debug <...>: schaltet Debug-
Ausgaben ein oder aus. Ohne Parameter werden sämtliche Debug- Ausgaben deaktiviert. Zum Aktivieren sind folgende Schlüsselwörter möglich (auch mehrere, jeweils durch Leerzeichen getrennt): - sensor: Zeigt empfangene Sensordaten.
- dcf: Zeigt Informationen zum DCF77-Empfang. Das ist ziemlich 'gefährlich' da hierbei
interruptgesteuerte Routinen vom Interrupt aus aufgerufen werden. Dies kann mit
einem
Aufhängen
des Displays enden wenn der Sendepuffer voll ist. Es sollte deshalb nur dann verwendet werden wenn Sie wirklich debuggen wollen und nicht nur 'interessehalber' lauschen wollen!
- DumpConf: Erzeugt eine lesbare Interpretation des Konfigurationsspeichers.
- FTest: Führt einen einfachen Factory Test durch.
Dieses Kommando endet stets mit einem Neustart des Geräts. - GetSensorValues: Liefert die aktuellen Sensordaten (Volumen und Temperatur). Dies kann regelmäßig benutzt werden um z.B. Grafiken oder Statistiken zu erzeugen.
- Help: Listet alle verfügbaren Kommandos mit einer kurzen Beschreibung.
- Reset: Ist eigentlich nur für Debugzwecke interessant und bewirkt einen Watchdog-Reset.
- SetBright <Brightness>: Setzt die Helligkeit des LCD-
Backlights. Dies hat keinen Einfluss auf die dauerhafte Hinterleuchtung, es setzt lediglich die Helligkeit während der Beleuchtungsphase. Relative Angaben sind möglich durch ein vorangestelltes Vorzeichen (also z.B. +10, -10). Ohne Vorzeichen wird der Wert absolut gesetzt. Der Wertebereich ist von 0 (aus) bis 255 (maximale Helligkeit).
Der Vorgabewert ist 255, also maximale Helligkeit.
Die Entscheidung ob Sie permanente oder akute Hinterleuchtung wünschen kann derzeit nur über den Taster getroffen werden. Auch sie wird durch ein write-Kommando permanent. - SetCistern <Typ> <Tiefe>
<Fläche|Durchmesser> <Kapazität> [<Länge>]:
Definiert die Abmessungen der Zisterne.
Typ bestimmt die Form der Zisterne:- const: Die Zisterne hat eine konstante Oberfläche über die Füllhöhe (beispielsweise ein stehender Zylinder oder ein Würfel).
- horiz: Die Zisterne ist ein liegender Zylinder.
- sphere: Die Zisterne ist kugelförmig.
Fläche|Durchmesser ist die Größe der Wasseroberfläche in Quadratmeter für den Typ "const" bzw. der Durchmesser des liegenden Zylinders oder der Kugel.
Kapazität ist das maximale Fassungsvermögen, also das Volumen bei dem die Zisterne bis zum Überlauf gefüllt ist. Sie ist nicht nur bei der Analog-Anzeige relevant sondern, seit es das Bargraph- Display gibt, auch für das LCD nötig. Sie bestimmt wann der Balken auf 100% steht.
Länge ist nur für den liegenden Zylinder wichtig und kann bei anderen Typen weggelassen werden.Insbesondere bei den Typen "horiz" und "sphere" ist zu befürchten, dass niedrige Pegel nicht zuverlässig erkannt werden da Reflektionen der Zisternenwand früher eintreffen als die von der Wasseroberfläche! Diese Geometrien halte ich für ungeeignet um per Ultraschall vermessen zu werden.
- SetContr <Contrast>: Setzt den Kontrast des LCD-
Backlights. Relative Angaben sind möglich durch ein vorangestelltes Vorzeichen (also z.B. +10, -10). Ohne Vorzeichen wird der Wert absolut gesetzt. Der Wertebereich ist von 0 bis 255. Wenn das Display schwarz ist, erhöhen sie den Wert, wenn es Hell ist (ohne sichtbarem Text), verringern sie ihn.
Der Vorgabewert ist 25 was bei Raumtemperatur lesbaren Text garantiert. - SetDisplay <Type>: Setzt den Typ des verwendeten Displays.
Type kann dabei 4×20, 2×16 oder analog sein.
Eigentlich wollte ich den Display-Type als Konstante programmieren so dass er zur
Kompilierungszeit festgelegt ist. Dies würde Speicherplatz im Flash sparen. Da der
Controller jedoch so immense Ressourcen bereit hält habe ich es als konfigurierbare
Variable implementiert. So können Sie den Anzeigetyp wählen ohne die Sourcen neu zu
kompilieren zu müssen.
Der Vorteil für die Fertigung ist klar: man hat nur ein Sourcefile, das für alle Display-Typen passt. - SetPTime <seconds>: Setzt die Zeit für die automatische
Display-
Weiterschaltung. Vorgabe: 4 Sekunden. Dies ist ein uint_8, die maximale Zeit ist daher 255 s. - SetPTimek <seconds>: Setzt die Zeit bevor nach einem
Tastendruck wieder zur automatischen Display-
Weiterschaltung gewechselt wird. Vorgabe: 60 s. Dies ist ein uint_8, die maximale Zeit ist daher 255 s. - SetSignal <number> <low> <high>:
Setzt die Schaltschwellen für einen Signal-
Ausgang. Der Ausgang wird aktiv wenn der Zisterneninhalt kleiner als low oder größer als high Liter beträgt. Number kann 1 oder 2 sein. - SetSpontaneous <liters>: wenn <liters> ungleich 0 ist
werden Änderungen des Volumens spontan gemeldet sofern sie größer
als <liters> sind. Mit
0
werden spontane Meldungen deaktiviert.
Achtung: wenn sie dies aktivieren und kein Gerät dauerhaft (Bluetooth!) an der seriellen Schnittstelle angeschlossen ist, kann dies zumAufhängen
des Geräts führen wenn zusätzlich RTS/CTS aktiviert ist! - SetTime <hh:mm>:setzt die Zeit (hart) auf den angegebenen Wert. Falls DCF77 empfangen werden kann wird diese jedoch beim nächsten gültigen Telegramm aktualisiert. Bei hartem Setzen der Zeit können Sekunden- Minuten- oder Stundenereignisse verloren gehen.
- SoundEnable <hourfrom> <hourto> [<soundmask>]: Töne werden nur in den Stunden von hourfrom bis hourto erzeugt um die Nachtruhe zu gewährleisten. Der Bereich liegt von 0 bis 24. Töne werden nur erzeugt, wenn die aktuelle Stunde größer oder gleich hourfrom und kleiner als hourto ist. soundmask erlaubt einige Spezialbehandlungen bestimmter Sequenzen. Für mehr Details siehe Sound. soundmask ist 0 wenn Sie sie nicht anders angeben.
- Status:Listet den Zustand aller Sensoren des Displays, also der Spannungswerte
und der Display-
Temperatur. Die Temperatur ist nicht die Raumtemperatur sondern die Temperatur innerhalb des Display- Gehäuses. Sie wird benutzt um den Kontrast des Displays an die Umgebungstemperatur anzupassen (bisher nicht implementiert). - Update:startet ein Firmware-
Update des Sensors. Der normale Betrieb wird angehalten. Die Anzeige wartet dann auf das Intel- Hex- File des Sensors und programmiert ihn entsprechend. Danach wird ein Neustart ausgeführt. Sobald eine Zeile empfangen wird, die in einem Intel- Hex- File nicht vorkommen kann (die also nicht mit einem Doppelpunkt beginnt, auch eine Leerzeile!) wird das Kommando beendet.
Dieses Kommando endet stets mit einem Neustart des Geräts.
Es ist nur verfügbar wenn die Sourcen mitWITH_UPDATE
kompiliert wurden (in display.h). Hier die Gründe, warum es dieses Flag überhaupt gibt. - UseRts: Soll RTS/CTS-
Handshake benutzt werden? Geben Sie 0 für nein und 1 für ja an. Dieses Kommando gibt es nur, wenn in den Sourcen USE_RTS
definiert ist. - Write: Schreibt den Inhalt des Konfigurationsspeichers in das EEPROM. Dies sollte nach jeder Änderung der Konfiguration erfolgen da die Änderungen sonst nach einem Reset verloren gehen.
Abkürzen von Kommandos
Kommandos sind Case-
Beachten Sie: alle Änderungen der Konfiguration (einschließlich der Kalibrierung) werden zunächst nur im temporären Speicher abgelegt und erst durch ein Write-Kommando permanent!
Parameter können nicht abgekürzt werden. Sie können z.B. deb dcf schreiben anstatt debug dcf aber deb d wird nicht funktionieren!
Kommandos mit Neustart
Einige Kommandos enden mit einem Neustart des Geräts.
Dies wird durch einen Watchdog-
Nach einem echten Power-Down-Reset (aus- und wieder einschalten) sollte diese
jedoch verschwinden.
Debug-LEDs
Zum Debugging habe ich dem Display noch vier verschiedenfarbige LEDs spendiert. Solange die Schaltung nicht in 1000-er Stückzahlen läuft ist der finanzielle Aufwand vernachlässigbar, später kann man sie weglassen. In der aktuellen Firmware zeigen sie folgendes an:
- Grün zeigt die Zeit, die der Controller in der Hauptschleife im Sleep verbringt, also wie viel Rechenzeit noch übrig bleibt. Wenn die grüne LED sehr dunkel wird ist der Controller voll ausgelastet.
- Rot ist an während des ADC-
Interrupts. - Gelb ist an während des Timer 0 Interrupts
- Blau ist das Empfangssignal des DCF77 und kann ihnen beim Ausrichten der Antenne nützlich sein.
Diese Signale sind auch für das Oszilloskop über X9 zugänglich.
Die blaue LED wird auch für den Fertigungstest benötigt und sollte daher nur mit sehr guten Gründen geändert werden!
Helligkeit
Damit kann man es wohl niemandem recht machen. Die einen sagen, es verbrennt ihnen die Netzhaut,
andere meinen aus 5 m Entfernung kann man sie kaum noch erkennen. Ich habe einen Mittelweg
gewählt und sie mit jeweils 10 mA bestromt. Damit sind moderne LEDs, sagen wir, hell.
Ein vierpoliger Jumper ermöglicht
den Anschluss des Tastkopfes eines Oszilloskops um die Zeiten exakt zu messen.
Überrascht hat mich die Helligkeit der grünen Vishay-
Natürlich können Sie die LEDs auch für andere Zwecke gebrauchen. Die Sourcen haben Sie ja...
Factory Test
Ich habe einen einfachen Factory Test implementiert, der in der Lage ist Kurzschlüsse zwischen zwei Ausgängen oder einem Ausgang und der Versorgung zu erkennen.
Eingänge können damit nicht überprüft werden da die Software den Zustand der Eingangsleitungen nicht beeinflussen kann.
Dazu wird ein walking zero
und ein walking one
durchgeführt, d.H. alle Ausgänge werden
gesetzt und ein einzelnes 0-Bit wandert durch alle Pins. Solange nur dieses Bit 0 ist und
alle anderen 1 bleiben ist alles OK. Anschließend werden alle Pins auf 0 gesetzt und
eine 1 wandert durch alle Bits. Damit können viele (aber nicht alle) Kurzschlüsse
erkannt werden.
Alle Versorgungsspannungen werden gemessen und mit vordefinierten Grenzwerten verglichen. Die Kalibrierungsprozedur muss vorher durchgeführt werden um die Grenzwerte sicher zu erkennen.
Außerdem kann er den SWUnreg-Switch überprüfen da er die anliegende Spannung messen kann. Er zeigt die Anstiegszeit der SWUnreg (bis auf 90% von Unreg) und deren Abfallzeit (auf 10% von Unreg) die, bei gegebenen Prüfbedingungen (angeschlossener Sensor, 10 m Kabel), vorhersagbar sind. Damit kann die Funktion der Konstantstromquelle überprüft werden. Typische Werte für die Anstiegszeit in diesem Fall sind eine knappe Mikrosekunde und für die Abfallzeit etwa 20 ms.
Er kann jederzeit mit dem Kommando FTest aufgerufen werden. Beachten Sie dabei, dass kurze Spikes z.B. auf den Signalausgängen oder den seriellen Schnittstellen auftreten, die evtl. unerwartete Nebenwirkungen zeigen.
Der Factory Test endet stets mit einem Reset des Displays
LITERS_T
LITERS_T ist ein typedef für alle Volumeneinheiten im System und in meinen Sourcen als double definiert.
Manche Leute mögen sagen, ein Integer wäre genug. Ich benutze jedoch
für die meisten Berechnungen Fließkomma-
- Der Controller hat genug Reserven um die Berechnungen in Echtzeit durchzuführen.
- Fließkommawerte funktionieren auch noch, wenn sie an Stellen negativ werden, an denen ich nicht damit gerechnet habe.
- Fließkommawerte funktionieren auch mit unerwartet großen oder kleinen Werten,
auch wenn sie in Zwischenergebnissen auftreten, und es gibt wesentlich weniger Stellen im
Sourcecode, die Sie dann anpassen müssen.
(Denken Sie z.B. an a/b*c, das Ergebnis in Ganzzahl-
Arithmetik kann 0 werden wenn b und c groß sind!) Kaufmännische
Genauigkeit ist nicht erforderlich, d.h. vereinfacht ausgedrückt, 1+1=1.9999973 ist absolut in Ordnung!- Die ESA hat eine hunderte Millionen Dollar Ariane 5-Rakete verloren wegen eines Integer-
Überlaufs. Der Mehraufwand, diese Daten in Fließkomma zu halten, wäre vergleichsweise vernachlässigbar gewesen.
Wenn Sie komplexe Berechnungen durchführen müssen, tun Sie dies in Fließkomma-==
-Operator dann prinzipiell nicht verwendbar ist. 2 ist eben
nicht gleich 1.9999973!
Für mich gibt es nur wenig Gründe, von diesem Prinzip abzuweichen:
- Sie müssen Berechnungen im Interrupt durchführen. Dann kann der Zeitbedarf das Timing
anderer Interrupts stören (zumal bei ATMega-
Controllern Interrupts nicht unterbrochen werden können, auch nicht durch Interrupts höherer Priorität). Aber müssen sie das wirklich? - Ihre Anwendung ist extrem kritisch bezüglich der Leistungsaufnahme. Fließkommaberechnungen
sind elektrisch
teurer
als Integerberechnungen. Wenn Ihr System 10 Jahre mit einer Lithiumbatterie auskommen muss sind Sie möglicherweise gezwungen auf Ganzzahl-Arithmetik auszuweichen - Sie müssen Datenströme mit konstanter Datenrate (z.B. Audio- oder Videodaten) bearbeiten. Dies in Gleitkomma zu tun kann bei hohen Stückzahlen einfach zu teuer werden.
- Sie müssen große Datenmengen im Speicher halten. Ganzzahlen sind kleiner als Fließkommazahlen. Aber selbst dann kann es ratsam sein, sie in Fließkomma zu berechnen.
- Der gewählte/vorgegebene Controller hat nicht genug Speicher für die Fließkomma-Bibliothek. Ein ATtiny oder so...
Beide Listen erheben keinen Anspruch auf Vollständigkeit. Wenn Sie zu dem Schluss kommen, int_16 reicht für LITERS_T, definieren Sie es um. Ich kann ihnen jedoch nicht garantieren dass es einfach so funktioniert obwohl ich mich bemüht habe, die Schnittstellen kompatibel zu halten. Verwenden Sie auf keinen Fall vorzeichenlose Typen! Ihr Volumen kann negativ werden wenn die Zisterne 1 cm tiefer ist als Sie gemessen haben. Die Auswirkungen könnten Sie sonst überraschen!
Layout
Hier ein paar Hinweise zum Layout.
Allgemein müssen in Stromkreisen mit hohem di/dt
induktive Anteile der Leiterbahnen minimiert werden.
Hohes di/dt treten in unserer Schaltung natürlich im
DC/DC-
Die Induktivität sinkt mit der Breite der Leiterbahnen und wächst mit der Länge und der umschlossenen Fläche.
Verwenden sie breite Leiterbahnen. 0.3 mm sind nicht genug, auch wenn sie den Strom theoretisch tragen können. 1 mm ist immer noch zu schmal. Verwenden Sie Flächen, so breit und kurz wie nur irgend möglich! Machen Sie sich klar, welchen Rückweg der Strom nehmen muss und verlegen Sie Hin- und Rückweg so eng wie möglich nebeneinander (bzw. übereinander) um die umschlossene Fläche zu minimieren. Jeder Millimeter den Sie sparen können verbessert das Ergebnis.
Da der Rückweg regelmäßig über GND führt muss die Groundplane die erste unter der Bestückungsseite sein!
DC/DC-Konverter
Für den DC/DC-Konverter bedeutet dies:
U8 schaltet, somit ergibt sich das höchste di/dt in den
Kreisen um U8. Minimieren Sie die Fläche
um C10, U8, L2, C12 sowie D2, L2 und C12.
PWM Dimming
Für den Dimmer-Schaltkreis bedeutet dies:
Minimieren Sie die Fläche um C5, Backlight, R12 und T3