Pfad: Home => AVR-DE => Anwendungen => Experimentell => Stromzähler 433MHz   This page in english: Flag EN Logo
Stromzaehler-Logger mit 433MHz AVR-Anwendungen

Stromzähler-Logger mit 433MHz-Sender und -Empfänger


Entwicklungsprojekt! Unfertig! Ungetestet! Software für den Empfang noch in Entwicklung!

Stromzähler mit 433 MHz

Moderne Stromzähler haben eine Infrarot-Diode, die pro verbrauchter kWh 10.000 mal an- und ausgeht. Das hier zählt diese Impulse über eine Viertelstunde, speichert die Viertelstunden-Werte zwei Tage lang in einem EEPROM und sendet diese gespeicherten Werte alle Viertelstunde über einen 433MHz-Sender. Ein 433MHz-Empfänger liest die Messwerte mit und schickt die gesendeten Messwerte über eine RS232-Schnittstelle an einen angeschlossenen Rechner. Der 433MHz-Empfänger hat eine kleine LCD, so dass die Empfangssignale´visuell kontrolliert werden können.

Für das Mitlesen braucht man weder die Pin des Stromzählers noch einen Lese-/Schreib-Adapter für schlappe 40 Euro. Das braucht man, um mit dem Zähler über die IR-Schnittstelle zu kommunizieren. Und das machen die Meisten, nur wir verwenden das hier alles gar nicht, und brauchen das auch nicht.

Bei der Auswertung brauchen wir nur die Viertelstunden-Messwerte mit vier malnehmen und durch 10.000 teilen und erhalten so die kWh pro Stunde, also die Leistung in kW, gemittelt über 15 Minuten. Dazu brauchen wir nur ein Terminalprogramm, um den Datensatz mitschreiben zu können, ihn in eine .csv-Datei zu schreiben und diese dann in ein Tabellenprogramm einzulesen. Der zuletzt gesendete Wert ist immer der letzte gemessene Wert, so dass das Tabellenprogramm leicht das Datum und die Uhrzeiten herauskriegt, zu denen die Werte passen.

Schaltbilder und andere Zeichnungen gibt es in der LibreOffice-Draw-Datei hier, Berechnungen in der LibreOffice-Calc-Datei hier.

Top Hardware Aufbau Software Algorithmen

1 Hardware

1.1 IR-Sensor, ATtiny85-Kontroller und 433MHz-Sender

Schaltbild des Senders Das hier ist die Sensormimik und der 433MHz-Sender, alles gesteuert von einem ATtiny85. Er besteht aus:
  1. dem Infrarot-Empfangs-Transistor BPY62/IV: dieser empfängt die IR-Signale der IR-LED und ist über eine zweipolige Buchse am Gehäuse angeschlossen. Der Trimmer mit 5MΩ stellt den Pegel ein. Über 1kΩ ist dieser auf den Eingang T0 des 8-Bit-Zählers TC0 geschaltet. Der Widerstand trennt den Sensor ab, wenn der Kontroller über die ISP6-Schnittstelle programmiert wird.
  2. dem 433MHz-Sender FS1000A: dieser sendet alle Viertelstunde die Messwerte. Die Sendeleistung über die angeschlossene Antenne mit Lambda-Viertel Länge beträgt maximal 10 mW (bei Einsen). Bei Nullen ist die Sendeleistung auf Null reduziert (Quasi-Amplituden-Modulation, AFSK). Um den Stromverbrauch zu minimieren wird die GND-Leitung des Senders vom Ausgang PB0 des Kontrollers in den langen Sendepausen abgeschaltet. Auch der Dateneingang des Senders ist mit 1kΩ (sowie dem oberen 1k-Widerstand nach Plus) von der ISP6-Programmier-Schnittstelle abgetrennt.
  3. Der Kontroller ATtiny85 wird mit einem 4,096MHz-Quarz getaktet, diese Taktfrequenz wird aber intern auf 256kHz herabgeteilt, so dass der Strombedarf des Kontrollers erheblich reduziert wird. Durch den Quarztakt ist der mit dem 8-Bit-TC1-Zähler erzeugte Viertelstundentakt sehr genau und bleibt deutlich unter der Genauigkeit des Stromzählers. Die Impulszählung erfolgt mit dem 8-Bit-Zähler TC0, der hierfür per Software auf 16 Bit erweitert ist. Das Senden erfolgt defaultmäßig mit einer Baudrate von 500 Bit pro Sekunde, so dass bei gesendeten Nullen 250 Hz am ATAD-Eingang des 433MHz-Senders anliegen. Bei Einsen sind es 500 Hz. Das Übertragungsprotokoll ist weiter unten ausführlich beschrieben.
  4. Der angeschlossene Vierer-Akku-Pack versorgt das Ganze mit Strom, so dass man die Plastikbox in den Keller stellen kann. Die Lebensdauer des Akkus liegt jenseits von zwei Wochen. Beim Umstöpseln vom entladenen Akkupack zum frisch geladenen überbrückt der 10mF-Elko eine Durststrecke von etwa 5 Sekunden.
Die beiden 2mA-LEDs zeigen Folgendes an. Ist der Schalter offen, dann fließt durch beide LEDs ein sehr kleiner Strom (ca. 0,5 mA), beide sind schwach an. Wird der Schalter geschlossen, dann zeigt die grüne LED Bereitschaft, die rote LED aber aktives Senden an.

Noch ein Hinweis zum 5MΩ-Trimmpoti. Wenn man das nicht hat oder nicht kriegt, tut es ersatzweise auch ein 2,2MΩ-Festwiderstand, bei sehr viel Einfall von Umgebungslicht zum Fototransistor auch ein 1MΩ-Widerstand. Und nicht wundern, wenn er nicht zählt, wenn die ISP6-Schnittstelle angestöpselt ist: deren Innenwiderstand dürfte die Mikroamperes am Fototranistor total plattmachen.

Zur Sendefrequenz: Der Sender sendet ungefähr um die 433,9 MHz. Seine Sendefrequenz ist sehr davon abhängig, ob und welche Antenne angeschlossen ist und welchen Abstand die Sendeantenne zu anderen Gegenständen hat. Man verlasse sich also keineswegs auf die 433,9, es können durchaus auch 433,875 oder 434,15 MHz sein. Beim Empfang mit einem FM-Receiver hört man das Ein- und Ausschalten des Senders als Ton, wenn man ihn etwas neben die Sendefrequenz einstellt. Immerhin reicht die Reichweite locker aus, um aus dem Keller bis in meine Küche und das Arbeitszimmer zu senden, für das Wohnzimmer sind die Signale aber zu schwach, weil da noch zwei bis drei zusätzliche Reflexionen nötig sind. Immerhin flackern die beiden LEDs noch ein wenig, und man sieht, dass der Empfänger sich abmüht. Im kommerziellen FM-Empfänger schafft es das Signal nicht mal über die Rauschsperre.

Kapazitaeten des EEPROM und des SRAM Der Sender speichert die gesammelten Daten je nach Konfiguration des Quellcodes entweder in seinem SRAM (Default-Einstellung) oder im EEPROM. Die Speicherkapazität ist in etwa diesselbe, wie die Berechnung rechts zeigt.

Wenn der Sensor ohne den 433-MHz-Sender und ohne Empfängerschaltung betrieben werden soll, können die im EEPROM gespeicherten Daten auch mit dem AVR-Programmiergerät über die ISP6-Schnittstelle ausgelesen werden. Man erhält dann das gesamte EEPROM des tiny in einer hex-Datei.

Diese Version kriegt man, wenn man cStg im Kopf der Software auf 1 einstellt. Dies hat allerdings den Nachteil, dass man nicht ganz genau weiß, bei welchem der Datensätze der erste und der letzte Eintrag war, weil der Schreibzeiger in das EEPROM zyklisch schreibt. Die Zeitzuordnung kann daher maximal um plus/minus einen Tag oder gar mehr (bei einem ATtiny85) verkehrt gehen.

Stellt man cStg auf Null ein, was als Default eingestellt ist, dann werden alle gesammelten Daten nur im SRAM gespeichert und über den Sender versendet. Da die Sendung immer mit dem ältesten gespeicherten Datensatz beginnt und mit dem zuletzt gespeicherten Datensatz endet, ist die zeitliche Zuordnung hier eindeutig möglich.

1.2 433MHz-Empfänger, ATtiny2313-Kontroller, LCD und RS232-Schnittstelle

Schaltbild des Empfängers Dies hier
  1. empfängt die vom Sender in 1.1 gesendeten 433MHz-Signale, und
  2. dekodiert diese, formt sie in Watt um und sendet sie als ASCII-Zeichen über die serielle RS232-Schnittstelle an den Rechner, und
  3. zeigt dabei den Status auf der LCD an.
Die Schaltung wird mit einem Quarz mit 2,4576 MHz getaktet. Der Prozessortakt wird mit dem Taktvorteiler CLKPR durch vier geteilt, um Strom zu sparen. Dieser Vorteiler wird beim Prozessorstart per Software eingeschaltet.

Das Empfangssignal des 433MHz-Empfängers gelangt über ein RC-Filter mit einer Grenzfrequenz von etwa 1,85 kHz auf den INT0-Eingang des Controllers. Das Filter schützt den INT0-Eingang vor Überflutung, solange nur Rauschen empfangen wird und filtert das Eingangssignal für die 500 Baud.

Die LCD ist mit einem 8-Bit-Anschluss an den bidirektionalen Port B angeschlossen, die Pins PD3 (RS), PD4 (RW) und PD6 (E) kontrollieren die LCD. Die Hintergrundbeleuchtung der LCD an den Pins BLA und BLK ist per Default ausgeschaltet, kann aber mittels RS232-Befehlen zwischen 0,4 und 100% eingestellt werden und wird an PD5 per PWM-Signal eingestellt.

An der ISP6-Schnittstelle kann der Prozessor programmiert werden.

Die Stromversorgung des Teils erfolgt mittels eines 4,8V-Akkupacks.

Der Empfänger kann in folgenden Konstellationen betrieben werden:
  1. Mit LCD und mit RS232-Interface wie eingezeichnet (die Konstanten NoLcd und NoRs232 im Quellcode sind auf Null zu setzen), in dieser Einstellung muss die LCD auch angeschlossen sein, weil in der Default-Einstellung sonst das Warten auf das Busy-Signal der LCD die weitere Ausführung blockiert,
  2. Mit LCD und ohne RS232-Interface (die Konstante NoLcd muss auf Null, die Konstante NoRs232 auf Eins gesetzt werden), das zeigt auf der LCD nur den letztgemessenen Wattstunden-Wert an,
  3. Ohne LCD und ohne RS232-Interface sieht man gar nix, der Empfänger werkelt so vor sich hin und teilt der Außenwelt so gar nicht mit, was in ihm so vorgeht.


Init-Meldung der LCD Ist die LCD angeschlossen, erscheint dieses Bild (hier eine zweizeilige LCD). Sobald Daten eintreffen, wechselt die Anzeige dann zu den echten Daten in Zeile 2.

Porteinstellungen bei Realterm Ist das RS232-Interface angeschlossen, dann muss im Laptop ein Terminalprogramm wie z. B. Realterm installiert (gibt es bei SourceForge), gestartet und der Port und die Baudrate eingestellt werden. Ist alles so korrekt und der Change-Knopf erfolgreich gedrückt, erscheint nach dem Umschalten in die Display-Tab beim Einschalten des Empfängers das nachfolgende Bild.

Display im ANSI-Modus Sollte es mit irgendwelchen CR- und LF-Zeichen verunstaltet sein, einfach statt des Defaults der Anzeige diese auf "Display as ANSI" umschalten, dann verschwinden diese und beim Neustarten des Empfängers wird auch der Bildschirm gelöscht.

Das Mitschreiben der gesendeten Daten geht mit dem Tab "Capture": einfach eine Datei auswählen und mit "Start-Overwrite" deren Inhalt überschreiben lassen.

Wer es braucht, kann die Software mit einem Debug-Schalter dazu bringen, die Rohdaten am INT0-Eingang darzustellen (die Konstante DebugSignals im Kopf auf Eins setzen). Die zeitliche Auflösung der Signalauswertung kann dabei zwischen einer Sekunde und 60 Sekunden (eine Minute) vorgewählt werden (Konstante cCountPeriod auf N). Dieser Modus ist unten genauer beschrieben.

Top Hardware Aufbau Software Algorithmen

2 Aufbau

2.1 Sensor und Sender

Aufbau des Sensors und des Senders Aufbau des Senders So passt alles, was man zum Lesen, Speichern und Senden braucht, auf eine kleine Rasterplatine. Links ein größeres Maß, rechts das Kleinste.

Sensor und Sender im Plastikgehäuse Und so sieht das Ganze fertig in ein Plastikgehäuse eingebaut aus. So kann man das in den Keller auf den Zähler stellen, den Sensor mit schwarzem Klebeband auf die Infrarot-Diode kleben und im Wohnzimmer "Völker hört die Signale!" machen. Und zwar hört man auf um die 434 MHz herum, da sollten die Signale sein.

IR-LED-Detektor-Schaltung IR-LED-Detektor Um die IR-LED und den Sensor zu testen, habe ich mir auf dem Steckbrett (rechts) die links stehende Schaltung aufgebaut. Sie leistet gute Dienste beim Einstellen des Sensors und ist recht empfindlich. Leuchtet nur die rote, sieht der Sensor keine Infrarot-Strahlen. Leuchtet nur die grüne ist die IR-LED dauernd an. Blinkt rot und grün im Wechsel sehr schnell, liegt eine Rechteckspannung an der IR-LED. Blinkt die rote und die grüne LED unregelmäßig, liegt Störstrahlung vor, die in die hochohmige Schaltung über die Anschlussleitung zum Fototransistor hereinkommt (z. B. vom Zähler).

Damit sollte es gelingen, den Sensor-Fototransistor genau vor die IR-LED zu positionieren.

2.2 Empfänger und RS232-Umsetzer

Aufbau des Empfaengers Aufbau des Empfaengers, groessere Version Und das passt alles auf eine weitere kleine Rasterplatine (oder auch auf eine etwas größere). Die LCD ist nach unten hin angeschlossen, d. h. dass die Buchsenleiste auf der Lötseite der Platine befestigt wird. Dazu lötet man die Buchsenleiste von unten her ein und lässt dabei einen kleinen Spalt frei. Nach dem Einlöten der ATtiny2313-Fassung verbindet man die zehn Lötpunkte mit den jeweiligen Nachbarn. Oder man nimmt zweiseitig kaschiertes Material, das ist stabiler und viel einfacher zu verdrahten.

Empfänger auf dem Steckbrett Der Empfänger im Detail Das ist die Schaltung auf dem Steckbrett. Die LCD und der Quarz haben auf Anhieb korrekt funktioniert. Nur die Empfangssoftware hat ein wenig herumgezickt.

Rechts ist der eigentliche Empfänger gezeigt. Ich habe dem Datenausgang zwei 2mA-LEDs spendiert, jeweils mit Widerständen von 1k8 gegen plus und minus. Die zeigen beim Empfang beide gleiche Intensität, während sie beim Rauschen unregelmäßig hin und her flackern.

2.3 Stückliste

Stueckliste von Sender und Empfaenger Dies sind alle Teile, die man so braucht. Die Preise sind vom Juni 2023. Bauteile mit mehr als 5% Anteil an den Gesamtkosten sind rot hinterlegt.

Da der Empfänger nur wenige Minuten pro Tag benötigt wird, ist kein eigener Akkupack dafür vorgesehen. Für die Versorgung ist eine 2,5mm-Buchse und ein passender Stecker mit in der Stückliste. Daran kann man einen Batteriesatz mit vier Akkus oder drei 1,5V-Batterien (AA oder AAA) anschließen. Die Stromversorgung kann aber auch mittels der ISP6-Schnittstelle aus dem Programmiergerät erfolgen, dann kann ein Euro gespart werden.

Wer sparen will, kann die Schaltung auch ohne die LCD aufbauen. In diesem Fall wird die Konstante NoLcd in der Empfängersoftware auf Eins gesetzt. Das senkt die Gesamtkosten um die 7,50€ für die LCD und weitere Kleinbeiträge, die dann nicht mehr benötigt werden (10k-Poti, 16-Pin-Stecker- und -Buchsenleiste).

Und wer gar keine RS232-Schnittstelle braucht, setzt NoRs232 im Quellcode auf Eins und kann sich die entsprechenden Bauteile auch sparen. Der Pin RxD am ATtiny2313 muss dann nicht unbedingt dauerhaft auf Null gelegt werden, da das UART in diesem Fall gar nicht erst initialisiert wird.

Top Hardware Aufbau Software Algorithmen

3 Software

3.1 Grundsätzliches zum Protokoll

Zunächst einmal was Grundsätzliches: das Protokoll der Datenübertragung habe ich selbst erfunden, es ist mit nix kompatibel, nur mit sich selbst. Versuche es daher nicht mit irgendwelchen Bibliotheken: es gibt keine, die das hier alles kann.

Zunächst einmal: ich mag keine Datenübertragung, bei denen Null- und Eins-Bits unterschiedlich lang dauern. Das macht Berechnungen der Sendedauer unmöglich, weil sie von den gesendeten Inhalten abhängig sind ("Länge ist irgendwas zwischen alles Nullen und allen Einsen."). Bei mir sind alle Bits gleich lang: sie dauern zwei Millisekunden (oder was man als Baudrate in der Software so eingestellt hat). Einsen kriegen einen weiteren Polaritätswechsel zur halben Zeit, nach 1.000µs. Sowas nennt man Manchester-Kodierung.

Und: um den Null-/Eins-Erkenner im Empfänger bei Laune zu halten: Nach jeder Millisekunde kommt in jedem Fall ein Pegelwechsel. Damit der Empfänger gar nicht erst auf die Idee käme, das Rauschen zu interpretieren, kriegt er immer Signale.

Und damit er sich von Anfang an an das Gezappele richtig gewöhnen kann, kriegt er eine gelungene Mischung von vielen Nullen und Einsen zu Beginn (0x0F = 0b00001111). Los geht es erst, wenn der Empfänger ein Erkennungsbyte von 0x55 (=0b01010101) kriegt. Ab da geht es los mit den Daten.

Und davon kommen reichlich: ist das gesamte EEPROM oder SRAM eines ATtiny85 mit Daten gefüllt (und die Software unterstellt, dass das immer der Fall ist, auch wenn nur 0xFF drin steht), müssen 512 Datenbytes übertragen werden. Das sind 4.096 einzelne Datenbits. Bei einer Baudrate von 500 (wie defaultmäßig eingestellt) dauert das etwas länger als sechs Sekunden.

Und: hat der Empfänger einen einzigen Pegelwechsel verpasst, dann merkt das die Empfangs-Software sofort und geht auf Tauchstation. Macht nichts, in 15 Minuten kommt ja der nächste Datenschwall. Da braucht es kein CRC oder anderes Gedöns, Schrott wird sofort erkannt und mit einem Neustart bestraft.

Was auch immer sich auf 433MHz so tummeln mag: Störungen des Datenflusses werden so bemerkt und eine Viertelstunde später auch wieder ausgebügelt. Und: wenn der Störer auch genau alle Viertelstunde sendet, macht man das Gerät halt für einige Minuten aus (den riesigen Ladekondensator entladen nicht vergessen) und dann erst wieder an.

3.2 Software des Sensors/Senders

Die Software für den Sensor im ATtiny85/45/25 in Assembler-Format kann man hier herunterladen. Sie ist per Default auf einen Quarz von 4,096 MHz, eine Baudrate von 500 Bd, mit 15 Minuten Intervallzeit, mit der Device-Nummer 1 und auf das Speichern im SRAM eingestellt.

Wer was anderes möchte stellt die entsprechenden Konstanten im Kopf des Quellcodes um. Bitte bei der Baudrate nicht weniger als 250 einstellen, sonst wird der Tiny zu langsam zum Programmieren.

Bitte nicht vergessen, die ISP-Frequenz auf sehr niedrigen Wert einzustellen (die Studio 4.19 will immer mehr als 5 kHz) und den Quarz als Taktquelle in den Fuses einzustellen, sonst stimmt es mit dem Timing nicht.

3.3 Software des Empfängers

TBD Ich weiß, ich weiß: die Software hat das absolute Maximum an .IFs, .ELSEs und .ENDIFs. Das ist dadurch bedingt, dass LCD und RS232-Schnittstelle abschaltbar sind und dass auch noch diverse Debugschalter aktiv sein können. Wer schon definitiv weiß, wie seine Hardware aussehen soll und dass er niemals debuggen will, kann die ganzen .IFs, .ELSEs und .ENDIFs aus dem Quellcode rauswerfen. Das wird eine mühsame Angelegenheit, weil es davon sage und schreibe 51 Stück im Quelltext gibt. Man mache sich also auf eine größere Session gefasst.

3.4 Analyse von empfangenen Datensätzen

TBD

Top Hardware Aufbau Software Algorithmen

4 Algorithmen

TBD

4.1 Algorithmen beim Senden

Im Folgenden sind die Algorithmen beim Senden beschrieben.

4.1.1 Bits senden

Senden von binaer 00 Das Bild zeigt das Senden zweier Null-Bits: zum Ende jedes Bits kehrt sich die Polarität um, so dass auch bei fortgesetztem Null-Senden jeweils Pegelwechsel stattfinden, die dem fortdauernden Einschwingen der Regelung im Empfänger dienen. Bei defaultmäßen 500 Baud wechselt der Ausgang mit einer Frequenz von 1.000 Hz.

Senden von binaer 10 So sehen die beiden Bits 1 und 0 aus: bei der Eins zu Beginn wechselt die Polarität nach der halben Zeit noch einmal, bei der Null nicht. Würde man lauter Einsen senden, läge am Sende-Eingang eine Frequenz von 2.000 Hz.

Senden von binaer 11 Das ist das Bild beim Senden zweier Einsen.

4.1.2 Sendeprotokoll

Sendeprotokoll Das ist das gesamte gesendete Protokoll, es wird alle 15 Minuten so ausgesendet.

Es beginnt mit einer einleitenden Phase, die für eine Sekunde lang 0x0F aussendet. Das dient dazu, die Null/Eins-Erkennung im Empfänger zu trainieren. Der Empfänger schwingt sich damit ein.

Auf diese einleitende Phase sendet der Sender ein Byte mit einem Sync-Signal, binär 0b01010101. Dieses Byte dient der Synchronisation: ab jetzt beginnt der Datenstrom.

Es folgt ein Byte, das die Nummer des Devices angibt. Hat man mehrere verschiedene Geräte am Senden, kann man damit die Auswertung nach Gerät vornehmen.

Nun folgt ein Byte, das die Intervalldauer in Minuten angibt. Es kann (und wird) zum Umrechnen der Zählerimpulse in Wattstunden verwendet werden.

Nun beginnt der Datenstrom. Gesendet wird jeweils das LSB und das MSB aus dem SRAM oder EEPROM. Es beginnt immer mit dem ältesten Eintrag und endet mit dem letzten Eintrag. Da das Schreiben in das SRAM/EEPROM zyklisch erfolgt, kriegt man so immer 256 Datenworte gesendet (beim Speichern im SRAM einige wenige weniger, beim ATtiny45/25 entsprechend ebenfalls weniger).

Der Datensatz endet mit 0xFEFE, weil diese Kombination nicht im Datenstrom vorkommen kann. (Hinweis: 0xFFFF kann vorkommen, wenn das EEPROM noch nicht vollständig mit Daten befüllt ist.)

Nach Beenden der Aussendung wird der Sender abgeschaltet.

Es macht übrigens keinen Unterschied, ob man nur die sechs letzten Ergebnisse, die letzten 128 Ergebnisse oder alle 256 Ergebnisworte sendet, denn für die Sendedauer, und damit den Stromverbrauch des 433MHz-Senders, macht das kaum einen relevanten Unterschied: entscheidend für die Dauer ist die Einleitungsdauer von einer Sekunde.

4.1.3 Timing

Der Timer TC1 dient einerseits der Zeitmessung (15-Minuten-Intervall) als auch, beim Senden, dem Timen des Ausgangssignals.

Beim Senden torkelt der Ausgang OC1A beim TC1-CTC und sorgt so automatisch für das Senden von Nullen. Handelt es sich um eine Eins, dann sorgt der Compare-Match-B-Interrupt von TC1 etwa zur Halbzeit für ein zusätzliches Torkeln. Das Torkeln beim Compare-Match-B wird dadurch realisiert, indem das Compare-B-Register um 9 Taktzyklen niedriger als die halbe Zeit eingestellt wird. Liegt eine Eins vor, dann wird der Compare-B-Interrupt eingeschaltet. Beim Interrupt wird der PINB-Eingang von PB1 mit einer 1 beschrieben, was das Torkeln auslöst. Ist das Senden nicht gestartet, setzt der CTC den OC1A-Ausgang high, denn dem Sendemodul ist GND weggeschaltet.

4.1.4 Zähler

Timer TC1 beim Senden und als Intervall-Timer Beim Default-Fall arbeitet der Quarzoszillator mit 4,096 MHz, wird mit CLKPR durch 32 geteilt und taktet den Prescaler von TC1 mit 128 kHz. Bei einem Compare-A-Wert von 255 erfolgt alle zwei Millisekunden ein Compare-Match-A-Interrupt. Die Uhr wird nach acht Interrupts abwärts gezählt (rBitCnt zählt beim Senden die Bits), für das 15-Minuten-Intervall muss daher bis 15(Minuten) * 60(Sekunden/Minute) * 500 (Int/Sek) * 128.000 (Hz) / 256 / 8 = 56.250 zählen. Damit andere Quarze und Teilerraten auch gehen, ist hierfür ein Drei-Byte-Zähler nötig.

4.1.5 Flussdiagramm Senden

Flussdiagramm beim Senden Das rechte Ablaufdiagramm ist der Ablauf beim Senden über die CTC-Routine des 8-Bit-Timers TC1. Der CTC macht das Torkeln zum Ende jedes Bits automatisch und stellt damit die Baudrate ein.

Bei der ersten Entscheidung wird die Flagge bTx abgefragt, ob das Senden aktiv ist. Wenn das nicht der Fall ist, wird der 8-Bit-Zähler rBitCnt um Eins erniedrigt. Ist dieser dann nicht Null, geht es aus der ISR zurück. Wenn er Null erreicht, geht es mit dem 24-Bit-Zeitzähler weiter unten weiter.

Bei aktivem Senden (bTx = 1) wird das nächste Bit aus dem Senderegister rTx nach links ins Carry geschoben. Falls es eine Eins ist, wird der OCIE1B-Interrupt (ganz unten rechts) eingeschaltet. Dieser bewirkt ein weiteres Torkeln zur halben Bitdauer. Wenn es eine Null ist (Carry ist Clear), unterbleibt dieser Interrupt.

Auch in diesem Fall wird rBitCnt um Eins erniedrigt. Erreicht dieses noch nicht Null, wird aus dem ISR zurückgekehrt. Ist es Null, wird mit einem ICALL die Routine mit der Adresse in ZH:ZL ausgeführt, die das nächste zu sendende Byte in rTx zurückliefert. rTx kann ein Frame-Byte oder ein Datenbyte sein. Die Routinen, auf die ZH:ZL zeigen, führen durch das Protokoll, sie werden etwas weiter unten detailliert beschrieben.

Alle vorhergehenden Teile münden hier nun in die Zeitmessung: es folgt das Abwärtszählen des 24-Bit-Zählers in rCnt2:rCnt1:rCnt0. Erreicht dieser Null, wird die Flagge bTO gesetzt. Diese Flagge setzt auch den Zähler neu. Die Verwendung der drei SBC-Instruktionen mit Null im Register rimp (das erste mit gesetztem Carry-Bit) verwendet eine sehr spezielle Einrichtung im ATMEL-Instruktionsset bei SBC: die Z-Flagge wird beim SBC nur dann auf ihrem vorherigen Zustand belassen, wenn das Ergebnis gleich Null ist, ansonsten wird sie gelöscht.

Das Abwärtszählen des 24-Bit-Zählers ist ein wenig speziell. Durch das einleitende CLR rimp wird die Z-Flagge gesetzt (Achtung! LDI rimp,0 würde das nicht tun!). Durch Setzen von Carry und anschließendem SBC der Null in rimp wird das LSB um Eins erniedrigt. Die beiden folgenden SBC von Null bewirken das Abwärtszählen der oberen 16 Bits, immer wenn das Carry gesetzt ist. Die Z-Flagge im SREG ist bei den AVR beim SBC so konstruiert, dass sie bei Gleichheit Eins bleibt, aber nur dann, sofern sie vorher auch Eins war. Kam bei einem der drei SBC Ungleichheit heraus, kommt die Z-Flagge gelöscht heraus. Nur wenn alle drei SBC mit gesetzter Z-Flagge Null anzeigen, kommt die Z-Flagge gesetzt heraus. Mit dieser Methode lassen sich Zähler mit beliebiger Länge zuverlässig abwärtszählen. Das Subtrahieren von Null, jeweils mit Carry, ist dabei auch noch viel schneller als drei Sprungbefehle. Da es bei PH4 um jeden Takt geht, ist diese Methode zu bevorzugen.

Die Ausführungszeiten in Takten sind jeweils an allen Instruktionen angegeben.

Sendestart Phase 0 Dies ist die Routine zum Start. Vorher wurde die Adresse von PH0 in das Doppelregister ZH:ZL geschrieben, so dass das erste ICALL an diese Adresse führt. Die Routine schreibt ein Byte 0x0F in das Senderegister und lädt eine einsekündige Wiederholung in das Zählregister YH:YL. Die Adresse in ZH:ZL zeigt dann auf die Routine PH1.

Senden der Praeambel Dieser Teil sendet das Prämbelbyte 0x0F für eine Sekunde lang. Ist der Zähler abgelaufen, wird das Synchronbyte gesendet und der Adresszeiger auf das Datensenden in PH2 umgestellt.

PH2 In der Phase 2 (in PH2) wird die Device-Nummer gesendet und die Phase 3 eingeleitet.

PH3 Dies sendet die Intervalldauer in Minuten. Sie kann zwischen 1 und 35 sein. Außerdem wird die aktuelle SRAM- oder EEPROM-Eingabeadresse in das Zählregister YH:YL geschrieben. Nun zeigt die Adresse auf den ältesten Eintrag im SRAM oder im EEPROM, mit dem das Senden begonnen wird. Die Sende-Routine für die Daten in Phase 4 (PH4) wird als nächste aktiviert.

PH4 In Phase 4 (PH4) werden nun die gespeicherten SRAM- oder EEPROM-Daten byteweise gesendet. Dazu wird beim Speichern im SRAM (cStg=0) rTx mit LD aus dem Speicher gelesen und die Adresse in YH:YL um Eins erhöht. Beim Speichern im EEPROM (cStg=1) wird YH:YL in das EEPROM-Adressregister geladen und das EEPROM-Lesen aktiviert. Das EEPROM-Byte steht nun in EEDR bereit und wird in rTx eingelesen. Man beachte bei den Ausführungszeiten, dass das EEPROM-Lesen die CPU für vier Takte lang anhält. Nach dem Lesen aus dem EEPROM wird die Adresse in YH:YL noch um Eins erhöht.

In beiden Fällen wird dann überprüft, ob das Ende des SRAMs/EEPROMs erreicht ist. Falls das der Fall ist, wird mit dem Lesen aus dem SRAM bei sStart und beim EEPROM mit Null wieder von vorne begonnen (zyklisches Lesen). Außerdem wird geprüft, ob die EEPROM-Eingabe-Adresse in rStgH:rStgL erreicht ist. Falls das der Fall ist, wird der Zähler Y auf drei gesetzt und als das Nächste Phase 5 eingeleitet.

PH5 In Phase 5 (PH5) wird zwei mal 0xFE als Endezeichen gesendet. Sind zwei 0xFE gesendet, wird eine Null gesendet und Phase 6 eingeleitet.

PH6 Phase 6 schaltet den Sender aus: die bTx-Flagge wird gelöscht, der Ausgang OC1A wird High gesetzt, die Timer-Interrupts auf OCIE1B werden ausgeschaltet und die Ground-Leitung des Senders wird auf High gestellt. Damit ist das Senden beendet.

Man beachte, dass das letzte Bit der abschließenden Null noch nicht vollständig gesendet ist. Da die Null als Füll-Byte dient, macht das nichts aus. Wer auf eine vollständige Null mit allen acht Bits Wert legt, muss eine weitere Null ausgeben. Die Änderung ist sehr einfach zu bewerkstelligen: durch Einfügen einer Phase 5a, die in rTx eine Null zurückliefert und dann erst PH6 involviert. Man kann bei der zweiten Null auch einfach rBitCnt auf Eins setzen, dann wird nur ein einziges 0-Bit ausgegeben und es wird danach ausgeschaltet. Das hat allerdings den Nachteil, dass die Uhr um bis zu sieben Millisekunden verkehrt geht (was bei einer Viertelstunde weniger ausmacht (ca. 0,0008%) als übliche und normgerechte Stromzähler genau zählen: +/- 1%).

Bei erneutem Laden von rTx schlagen maximal folgende Anzahl N an Taktzyklen zu Buche.

Phasemax N SRAMmax N EEPROM
09
111
27
39
41828
511
611
Max1828

Die maximale Anzahl an Takten der OCIE1A-ISR beträgt daher beim Senden aus dem SRAM 34 + 18 = 52 Takte, beim Schreiben aus dem EEPROM 34 + 28 = 62 Takte. Das ist beim EEPROM etwas weniger als ein Viertel der beim Default zur Verfügung stehenden Takte (256) und etwas weniger als die Hälfte der Takte bis eventuell der OCIE1B-Interrupt zuschlägt (nach 128 Takten). In sehr ungünstigen Fällen mit sehr ungewöhnlichen Baudraten kann die TC1-CTC-Phase bis herab zu 128 reichen, so dass der Comp-B nur noch bei 63 liegt. Selbst diese ungewöhnliche Konstellation wird also bewältigt, da noch immer ein Takt Platz bleibt. Beim Schreiben aus dem SRAM ist die Spanne bis zum OCIE1B-Interrupt noch viel größer.

Und: die Maximalanzahl wird nur im aller-ungünstigsten aller Fälle benötigt, so dass für Anderes (z. B. für einen TC0-Überlauf mit 14 Taktzyklen) noch genug Zeit bleibt. Alle anderen Fälle brauchen deutlich weniger Taktzyklen (siehe Tabelle, bei Phase 4 sind es 22 bis 27 Takte). Die kürzeste Ausführungszeit beim Nichtsenden beträgt 17 Takte, wenn rBitCnt noch nicht Null ist. Das sollte der Regelfall sein, was einem niedrigen Stromverbrauch beim langwierigen Zählen der Stromzählerimpulse zugute kommt. Der höchste Strombedarf wird aber ohnehin beim Senden von Einsen verbraten (17 bis 18 mA, wenn eine Antenne angeschlossen ist, siehe Tabellenblatt "duration").

Es ist ein wahrer Segen, dass der AVR-Befehlssatz ICALL (und IJMP) enthält. Damit kann auch ziemlich komplizierte Abläufe sehr rasch erledigen. Kein Hangeln mit SBRC/SBRS durch Ketten aus sechs Flaggen z. B., wie man es hier machen könnte. Währenddessen verhungert der TC1-CompB-Interrupt komplett und schlägt zu spät zu.

4.2 Algorithmen beim Empfang

Die folgenden Unterkapitel beschreiben Algorithmen im Empfänger.

4.2.1 Registerplan beim Empfang

Der folgende Plan gibt einen Überblick über die Registerbelegung beim Empfang.
RegisterNameBelegung
R0 bis R12(Diverse)Beim Debuggen als Zähler
R27:R26X, XH:XLAls Zeiger in den Empfangspuffer, beim Debuggen auch in den Sendepuffer
R29:R28Y, YH:YLRS232-Sendepuffer: Adresse des nächsten zu sendenden Bytes im Sendepuffer
R31:R30Z, ZH:ZLAdresse zur Behandlung des folgenden Bytes sowie als Vielzweckregister

4.2.2 Auswertung des Empfangssignals

Das Empfangssignal des 433MHz-Empfängers ist an den INT0-Eingang des ATtiny2313 angeschlossen. Der INT0-Eingang ruft bei jedem Pegelwechsel an INT0 den externen Interrupt auf. Dieser wertet dieses Empfangssignal aus.

Mit jedem Pegelwechsel wird die abgelaufene Zeit aus dem 16-Bit-Zähler TC1 eingelesen und der Zählerstand neu gestartet.

Die Dauer jedes TC1-Ticks ist von einer Reihe von Faktoren abhängig (siehe auch das Tabellenblatt "clock-RX" in der LibreOffice-Calc-Datei):

EinflussgrößeDefaultMinMax
Quarzfrequenz2,4576 MHz1 MHz20 MHz
CLKPR41128
TC1-Prescaler111.024
TC1-Tick1,63 µs1 µs6,5536 ms
TC1-Overflow0,1 s0,065 s7 Minuten
Min. Baudrate10160,0024

Das ergibt eine riesige Spanne an Messzeiten, damit kriegt man alles gemessen, was so an Pulsen hereinkommt.

Bei der Default-Einstellung ist jeder TC1-Tick 4 * 1 / 2.457.600 = 1,63 µs lang. Der Zähler kann maximal bis zu 0,1 Sekunden lange Signale zählen. Bei einer 433MHz-Senderate von 1.000 Baud dauert ein Nuller-Bit 1 ms, der Zähler erreicht dann 614. Bei einer Senderate von 4.000 Baud sind es 154, bei einer sehr langsamen Übertragung mit 100 Baud sind es 6.144. Minimal kann mit einem Vorteiler von 1 eine Baudrate bis herab zu 10 Baud bewältigt werden.

Die folgenden Zeiten sind bei der Auswertung von Bedeutung:

ZeitphaseBaud=4000Baud=1000Baud=100
Mindestdauer62,5 µs250 µs2,5 ms
TC1=38TC1=154TC1=1.536
Null/Eins-Erkennung125 µs500 µs5 ms
TC1=77TC1=307TC1=3.072
Time-Out312,5 µs1,25 ms12,5 ms
TC1=192TC1=768TC1=7.680

Man beachte aber, dass bei so kurzen Zeiten wie TC1=38 die Uhr auch richtig gestellt werden muss. Sind beim Bearbeiten in der Interrupt-Service-Routine schon 20 Takte vergangen, seit der INT0 physisch ausgelöst wurde, muss der Zähler nicht bei Null starten, sondern bei 20.

Zeiten beim Empfang von Signalen Zu Beginn oder beim Erreichen von 1,25 ms (=767, rote Hinterlegung rechts) sowie bei einem Unterschreiten der Signal-Mindest-Dauer von 0,25 ms Dauer (=154, rote Hinterlegung links) wird der Timer jeweils auf Null gesetzt. Ebenso bei einer korrekten Signaldauer zwischen 0,75 und 1,25 ms (=460..766, grüne Hinterlegung): hiermit wird der Empfang eines Bits erfolgreich abgeschlossen. Tritt ein INT0 im Zeitraum zwischen 0,25 und 0,75 ms (=154..459, orangene Hinterlegung), dann handelt es sich um eine Eins und die Einser-Flagge wird entsprechend gesetzt.

Sync-Fehler beim Empfang von Signalen Was geschieht nun, wenn die Synchronisation verloren geht und das Rücksetzen des TC1-Zählers fälschlich zu Beginn eines Einser-Bits erfolgt? Folgt ein Einser-Bit, wird auch dieses Bit korrekt erkannt und behandelt. Folgt aber ein Null-Bit, dann wird der Fehler erkannt, denn der Zähler läuft dann über die CTC-Grenze von TC1. Die weitere Umsetzung der empfangenen Signale wird unterbunden und der Empfänger wartet auf das nächste Sync-Signal, das nach einer Viertelstunde kommen wird. Da auf diese Weise nur dann eine vollständige Übertragung eines Datensatzes erfolgt, wenn bei jeder Null ein korrektes Synchronisieren erfolgte, findet diese Prüfung etwa 2.056-mal pro Datensatz statt. Auf den zusätzlichen Einsatz einer Prüfsumme konnte daher verzichtet werden.

Das Programm braucht in der SRAM-Version 216 Worte, in der EEPROM-Version 243 Worte des Flashspeichers, passt also bequem auch in einen ATtiny25.

4.2.3 Flussdiagramm Empfang

Flussdiasgramm des Empfangs mit INT0-Interrupt Das ist der Empfang der Bits mittels INT0-Interrupt-Service-Routine. Jeder Pegelwechsel am INT0-Eingang führt zu seiner Ausführung.

Zu Beginn wird SREG gesichert und der Zählerstand von TC1 eingelesen. Von diesem Zählerstand werden 0,25 ms (cFail) abgezogen. Tritt dabei ein Carry auf, dann war das Signal zu kurz: die Synchronisation wird abgeschaltet, der Zähler auf den Anfang (hier: auf 19 Taktzyklen) gesetzt und nach Wiederherstellen von SREG die ISR verlassen. Das Setzen von TCNT1 auf 19 macht den Sinn, dass ja seit dem Beginn der ISR bereits 19 Takte abgelaufen sind, die beim Erkennen der 0,25 ms (im Default-Fall mit TCNT1 = 155) zu mehr als 10% Verlängerung der Zeit führen würden.

Lag kein Carry vor, werden 0,5 ms subtrahiert (cOne). Wenn ein Carry auftritt, ist es eine Eins, die in der bBit-Flagge abgelegt wird.

Wenn kein Carry vorlag, dann handelt es sich um das Ende eines Bits. In diesem Fall wird
  1. der Zähler auf den Anfangswert 20 gesetzt, und
  2. das Empfangsbyte rByte um eine Position links geschoben, und
  3. wenn das Bit eine Eins war (Flaggenbit bBit gesetzt), um Eins erhöht, und
  4. das Flaggenbit bBit gelöscht, und
  5. falls das Sync-Bit nicht gesetzt war, wird rByte auf das Synchron-Byte 0x55 geprüft, und und die ISR beendet.
  6. war das Sync-Bit gesetzt, wird die Anzahl Bits in rBitCnt um Eins vermindert,
Insgesamt braucht die Routine maximal 39 Taktzyklen, was bei einer Taktfrequenz von 307,2 kHz ca 127 µs entspricht. Das RC-Filter vor dem INT0-Eingang wird so eingestellt, dass es nicht zum Überrennen und Fluten des INT0-Interrupts mit Nonsens-Signalen kommen kann.

Das kleine Diagramm oben rechts zeigt, was passiert, wenn der CTC-A-Interrupt zuschlägt. Dies ist der Fall, wenn zwischen zwei INT0's mehr als 1,25 ms liegen. Das setzt die bSync-Flagge auf Null, so dass der Empfänger den Empfang abbricht und wieder auf das Synchronisations-Byte wartet. Da die gesamte ISR nur 14 Taktzyklen braucht, mit Aufwachen und Flaggen-Abfrage etwa 20, und da sie nur alle 1,25 ms zuschlägt, braucht sie nur 2,6% der Prozessorzeit. Es lohnt daher nicht, zum Stromsparen den Interrupt abzuschalten und erst wieder beim Eintreffen des ersten INT0 wieder einzuschalten (zumal INT0-Interrupts wegen des Rauschempfangs in den langen Sendepausen - trotz des RC-Filters - immer mal wieder eintreten könnten).

4.2.4 Umwandlung der Zählerwerte

Die eingegangenen Bytes, die von der INT0-ISR im Register rRx übergeben werden, sind Binärdaten. Diese müssen zum Senden über die RS232-Schnittstelle in ASCII verwandelt werden.

Um unabhängig von der Intervalldauer zu werden, werden die Zählimpulse mit einem Faktor multipliziert und damit die Leistung in Watt ausgegeben. Der Faktor ergibt sich aus
  1. der Anzahl Zählimpulse, die der IR-Sensor pro Kilowattstunde sendet (normalerweise 10.000 / kWh, manche auch nur 500 / kWh),
  2. der Dauer der Intervallzeit in Minuten, die zu Beginn der Datenübertragung gesendet wird.
Die Formel zur Umrechnung von Zählimpulsen N in P (in Watt) lautet dann
F = 60(min/h) / t(min) / 10.000(Pulse pro kWh) * 1.000(Wh/kWh) = 60 / 10.000 * 1.000 / t(min) = 6 / t(min)

Da 6 / t ab t=7(min) immer kleiner wird als Eins, nehmen wir die Zahl mit 256 mal und streichen erst nach dem Multiplizieren das letzte Byte weg. 256 * 6 / t ergibt bei t = 15 Minuten 102,4. Das passt locker in eine 16-Bit-Zahl. Auch bei 1 Minute und bei 60 Minuten sowie bei 500 Pulsen/kWh ergeben sich bei 16 Bits keine Über- oder Unterläufe.

Das Dividieren von 256*60/10.000*1.000 = 1.536 (bzw. von 256*60/500*1000 = 30.720) durch die Minuten übernimmt eine 16-/8-Bit-Division. Die ergibt bei 15 Minuten und 10.000(Pulsen/kWh) einen Wert von gerundeten 102 bei einem echten Wert von 102,4. Das Abrunden verursacht damit einen Fehler von -0,39%, was deutlich unterhalb der Zählergenauigkeit bleibt (+/-1%).

Mit diesem Faktor F werden alle Zählimpulswerte multipliziert und durch 256 geteilt (gerundet), so dass das Ergebnis in Watt als Ganzzahl auf der LCD und über die RS232-Schnittstelle ausgegeben werden kann.

Die Sendung über RS232 beginnt mit STX (STX = Start of text = 0x02). Als allererstes kommt die Devicenummer. Diese wird mit der Zeichenkette "N=" eingeleitet und durch fortgesetztes Subtrahieren von 100 und danach von 10 in Dezimalformat umgewandelt. Dann kommt die Intervalldauer in Sekunden, die mit " I=nn" und abschließendem CR/LF gesendet wird. Durch Setzen des UDRIE-Interrupts wird die Aussendung auf der RS232-Schnittstelle gestartet und beim Erreichen des Linefeed-Bytes das UDRIE-Bit zurückgesetzt.

Die nun eintreffenden Datenbytes werden gepaart, mit F multipliziert und durch fortgesetztes Abziehen von 10.000, dann 1.000, dann 100 und dann 10 in Dezimal-ASCII verwandelt. Alle Paare werden mit Wagenrücklauf/Zeilenvorschub und dem Null-Byte abgeschlossen. Das Senden endet mit 0xFEFE, was dezimal 65.278 ergibt, was aber als ETX-Zeichen über die RS232-Schnittstelle gesendet wird (ETX = End of text = 0x03). Das Time-Out von TC1 startet dann die Suche nach dem nächsten Sync-Byte erneut.

Mit dem Debug-Schalter Debug0x0F werden die vor der Synchronisation eintreffenden 0x0F gezählt, um herauszufinden, wieviele Prämbel-Bytes der Empfänger verschluckt, bis er eingetaktet ist. Diese werden in einem Zwei-Byte-Zähler gezählt und auf der LCD angezeigt. Wenn der Debugschalter gesetzt ist, wird dieser Teil der LCD nicht überschrieben, weder mit Status- noch mit Fehlermeldungen.

4.2.5 Senden über die RS232-Schnittstelle

Das Senden über das UART erfolgt aus einem Puffer im SRAM heraus. Der Y-Zeiger zeigt auf das nächste zu sendende Byte im Puffer. Zum Starten des Sendens wird der UDRE-Interrupt eingeschaltet. Dieser bleibt eingeschaltet, solange beim Senden kein Linefeed-Byte (0x0A) angetroffen wird.

Der Zeiger Y wird beim Zusammenstellen der Zeile im SRAM-Sendepuffer gleichzeitig auch als Eingabezeiger verwendet, da er zum Senden erst nach der Zusammenstellung im Puffer gebraucht wird.

Da die serielle Ausgabe über die RS232-Schnittstelle mit 9k6 * 8/11 * 2/7 = 1.995 Baud etwa doppelt so schnell ist als die 433MHz-Übertragung mit 1.000 Baud, kann es auch nicht zum Vollschreiben des SRAM-Puffers kommen. Bitte bei Änderungen an den voreingestellten Baudraten dringend darauf achten!

4.2.6 Debugging des Zeichen-Einganges

Um zu sehen, welche Signale mit welcher Qualität am INT0-Eingang eingehen, schaltet man
  1. das RS232-Interface mit ".equ NoRs232 = 0" ein,
  2. schließt ein RS232-Interface (z. B. einen USB-zu-Seriell-Wandler) an den TXD-Ausgang am MAX232 an den Pin 2 der DB9-Buchse (RXD) an,
  3. stellt die eingestellte RS232-Baudrate von 9.600 Baud (default) an demjenigen Port ein, den das Betriebssystem dem USB-Seriell-Wandler zugeteilt hat (beim Windows hilft da der Gerätemanager, um den COM-Port herauszufinden),
  4. den 433MHz-Empfänger an den INT0-Eingang.
Realterm-Analyse der Signale In der Software stellt man die Konstante DebugSignals auf Eins ein und wählt die Dauer der Analyseperiode in cCountPeriod zwischen 1 und 60 Sekunden.

Das ergibt mit 20 Sekunden Zählzeit die erzielte Anzeige. Nach den ersten 20 Sekunden sind 340 Pegelwechsel (p=340) am INT0-Eingang eingetreten, vor allem Rauschen. Davon waren 107 zu kurz (s=107), 130 erfüllten das Kriterium für eine Eins (1=130), 103 erfüllten das Kriterium für eine Bitlänge (b=103). Bei 76 dieser Signale trat ein Time-Out auf, d. h. TC1 ist übergelaufen (t=76). Es wurde kein Sync-Byte erkannt (y=0).

Zwischen 80 und 100 Sekunden traf eine Sendung mit Bits ein. Leider ist nicht nur die Anzahl Pegelwechsel drastisch angestiegen, sondern auch die Anzahl zu kurzer und die Anzahl zu langer Signale. Ein Sync-Byte wurde leider nicht identifiziert.

4.2.7 Anzeigen auf der LCD

Die LCD kann ein- oder zweizeilig sein. Diese Größe steht in der Konstanten "LcdLines".

Ist LcdLines = 1, dann erscheint beim Einschalten zunächst eine Zeile mit dem Programmnamen, nach einigen Sekunden dann die eigentliche Anzeigemaske. Bei LcdLines = 2 bleibt der Programmname in Zeile 1 erhalten, die Anzeigemaske erscheint zusätzlich in Zeile 2.

An Daten wird in der Ausgabemaske angezeigt:
  1. der letzte übertragene Datenwert als fünfstellige Dezimalzahl in Watt,
  2. hinter D= (für Device) steht die Nummer des Sensors als dreistellige Dezimalzahl, und
  3. im Rest der Zeile stehen Statusmeldungen (Fehleranzeigen, Anzahl der empfangenen Datenbytes, etc.


Top Hardware Aufbau Software Algorithmen

5 Betriebserfahrungen

TBD

Lob, Tadel, Fehlermeldungen, Genöle und Geschimpfe oder Spam bitte per Email an mich (info und die Web-URL-Adresse), ich freue mich über alle Arten von Rückmeldungen.

©2023 by http://www.avr-asm-tutorial.net