Pfad: Home => AVR-DE => Anwendungen => tn24-Thermometer => Temperatur über serielles Infrarot mit ATtiny45   This page in english: Flag EN Logo
Thermometer tn45 ir AVR-Anwendungen

Thermometer über serielles Infrarot mit zwei (drei, vier, ...) ATtiny45


Entwicklungsprojekt! Enthält noch ungetestete Hardware, Software noch in Arbeit!

ATtiny45-Thermometer über serielles Infrarot

Wer kennt das nicht? Man will ein schönes Außenthermometer bauen und montieren. Aber wie das Kabel durch das Fenster tun, ohne das Fenster kaputt zu machen?

Hier ist die Lösung: Infrarot geht, ohne Lochbohren, durch das Fenster. Und auf der anderen Seite des Fensters steht ein Umsetzer für die IR-Signale, der diese in serielle Signale umsetzt, sowie ein Laptop herum. Der hat eine serielle Schnittstelle und möchte gerne die Außentemperatur anzeigen - heute mal in Kelvin, morgen in °Celsius und übermorgen in °Fahrenheit (weil gerade mal Besuch aus den USA da ist). Kein Problem: hier ist die universelle Thermosensor-serielles-Interface-via-IR-Wollmilchsau.

Wir brauchen zwei Außentemperatur-Messteilen? Kein Problem, solange die zwei oder drei sich gegenseitig und alle die Umsetzer-LED sehen, einfach welche dazu bauen. Mit dem in der Software eingebauten Prioritätsmechanismus stören die sich gegenseitig nicht und senden nur dann, wenn genau sie dran sind.

Und weil wir gerne die Innenraum-Temperatur mit der Außentemperatur vergleichen wollen, können wir auch noch einen (oder zwei oder drei) Innentemperatur-Messteile verbauen.

Die Schaltbilder gibt es wie fast immer in der LibreOffice-Draw-Datei hier, die Berechnungen in der LibreOffice- Calc-Datei hier.

Top Funktionsweise Hardware Aufbau Software Algorithmen

1 Wie es funktioniert

1.1 Was man braucht

Auf jeden Fall braucht man:
  1. einen Rechner, auf dem ein Terminalprogramm, z. B RealTerm, seinen Dienst tut, und
  2. einen USB-zu-Seriell-Umsetzer, den man auf 1200 Baud oder weniger einstellen kann,
  3. die Infrarot-zu-Seriell-Umsetzer-Platine, die mit einer DB9-Buchse ausgestattet ist und serielle Signale über Infrarot empfängt und serielle Signale mittels einer IR-LED auch aussenden kann (das macht ein ATtiny25), wozu auch ein Trafo-Netzteil gehört, und
  4. einen oder mehrere Thermosensoren, entweder akkubetrieben für Outdoor oder an das Trafonetzteil des Umsetzers angeschlossen für den In-door-Betrieb.

1.2 Ablauf

Ein ATtiny45 misst auf Anforderung die Temperatur und gibt das Ergebnis als Textstring in serieller RS232-Kodierung mit 1k2 an einer Infrarot-Diode aus. Auf der Innenraum-Seite nimmt ein IR-Empfänger die Signale auf und sendet sie über einen RS232-Pegelwandler an eine DB9-Buchse. An die kann der Rechner mit einem DS9-Stecker (mit DS9-zu-USB-Wandler) das Ergebnis mitlesen.

Der ATtiny45 hat eine quarzgetriebene Uhr, die in einem wählbaren Intervall zwischen einer und 65.535 Sekunden (ca. 18 Stunden) die Temperaturmessung automatisch startet und dann Datum, Uhrzeit und Temperatur sendet.

Der ATtiny45 hat auch eine serielle Schnittstelle, die mit 1k2 empfangen kann. Über diese serielle Schnittstelle kann eingestellt werden:
  1. Datum und Uhrzeit,
  2. die Dimension der Temperatur (Kelvin, °Celsius, °Fahrenheit),
  3. die drei Parameter, mit denen die Temperatur in Kelvin aus den ADC-Messwerten errechnet wird (T = a * 128ADC2 + b * 128ADC + c), alle Thermometer sind also eichfähig,
  4. deutsche oder angelsächsische Notation,
  5. und noch vieles anderes mehr, siehe weiter unten im Detail.
Alle wichtigen Parameter (Dimension der Temperatur, a, b und c) müssen nur einmal eingestellt werden, denn sie werden in das EEPROM geschrieben und beim Programmstart (z. B. nach einem Akku-Wechsel) daraus ausgelesen.

1.3 Ablaufdetails

Der IR-zu-Seriell-Umsetzer lauscht auf eingehende Infrarot-Signale. Entdeckt er welche, dann sendet es sie an die RXD-Leitung der DB9-Buchse. Sie werden dann vom Terminalprogramm angezeigt.

Der IR-zu-Seriell-Umsetzer setzt die von der TXD-Leitung der DB9-Buchse kommenden seriellen Signale in Infrarot-Signale um, d. h. bei Low-Signalen gibt die Infrarot-LED ein aktives Signal mit 40 kHz ab, bei High-Signalen bleibt sie ausgeschaltet.

Die via Infrarot angeschlossenen Thermosensoren
  1. haben eine individuelle Kennung zwischen 0 und 9, die sie Meldungen voranstellen, die Kennung gibt auch die Priorität an, mit der der Sensor seine Meldungen sendet,
  2. melden sich beim Einschalten mit ihrer jeweiligen Kennung,
  3. warten auf Sendesignale, die sie wie folgt auswerten:
Top Funktionsweise Hardware Aufbau Software Algorithmen

2 Die Hardware

Die Hardware besteht aus den zwei verschiedenen Typen an Temperatursensoren und aus der IR-zu-Seriell-Umsetzer-Platine (mit dem Trafonetzteil).

2.1 Die Hardware der Temperatursensoren

Die Hardware für Innen- und Außensensoren ist ein wenig unterschiedlich, daher erfolgt eine separate Beschreibung.

2.1.1 Die Hardware des Outdoor-Temperatursensors

Schaltbild des Outdoor-Thermosensors So sieht der Temperatursensor für Draußen aus. Der ATtiny45 wird von einem Quarz getaktet (entweder 7,68 oder 4 MHz oder beliebige andere, siehe Tabellenkalukation).

Die Speisung der Schaltung erfolgt entweder aus einem Li-Ionen-Akku mit 3,7 Volt oder aus drei hintereinandergeschalteten NiMH-Akkus zu je 1,2 Volt. Der Strombedarf ist nur beim Senden recht hoch, daher sollte der Messrhythmus mit Bedacht gewählt werden (z. B. alle 60 Sekunden oder alle 5 Minuten), er kann während des laufenden Betriebs eingestellt werden. Mit einer Seite in der Tabellenkalkulation kann man die Akku-Lebensdauer bei Vollladung abschätzen.

Der ATtiny45 misst regelmäßig (einstellbar zwischen 0 - keine Messung - bis 65535 - Messung alle 18,2 Stunden) die Temperatur seines Innensensors, rechnet diese in Temperaturen um, fügt Datum und Uhrzeit hinzu und sendet die Zeichenkette mit dem Ergebnis über die Infrarot-Diode an den Umsetzer, der sie wiederum in serielle Signale umwandelt und an den Laptop sendet.

Der Infrarot-Sensor TSOP31240 stellt fest, ob ein anderer Sensor gerade sendet. Falls das der Fall ist, wartet der Sendealgorithmus für eine voreingestellte Zeit, nachdem das letzte IR-Signal einging, und startet das Aussenden der Zeichenkette danach.

Liegt kein Sendevorgang an, dann wartet der Infrarot-Sensor auf eingehende Signale, liest diese ein und speichert sie in einem Pufferbereich im SRAM. Geht ein Zeilenvorschub-Zeichen ein, dann wird die empfangene Zeile ausgewertet. Falls der Befehl an den betreffenden Sensor gerichtet ist, führt er diesen aus.

Die Infrarot-Diode LD274-3 wird aus einer Konstantstromquelle angetrieben. Der ATtiny45-Ausgang PB0 taktet dazu ein 40kHz-Signal. Dieses schaltet eine rote 2mA-Leuchtdiode ein und aus. Die Durchlassspannung der Leuchtdiode treibt die Basis des Transistors, der den Strom durch seine CE-Strecke so einstellt, dass am Emitter die Basisspannung abzüglich der BE-Spannung abfällt. Der Emitter-Widerstand kontrolliert dabei den LED-Strom.

Ist die IR-LED nicht angeschlossen oder kaputt, dann leuchtet auch die rote LED nicht, da die Basis des Transistors und der Emitterwiderstand die Basisspannung dann unter die Brennspannung der roten LED zieht.

Messwerte des Konstantstromreglers Dies sind in blau die gemessenen Spannungen der Konstantstrom-Schaltung. Daraus resultieren die in rot eingezeichneten Ströme und die in violett angegebenen thermischen Leistungen im dauerhaft eingeschalteten Zustand (real sind die Leistungen im Endeffekt halb so hoch).

Die Konstantstromquelle arbeitet mindestens ab 3,3V Betriebsspannung sehr stabil und gleichbleibend. Nur wenn an der LED-Kathode +10V anliegen, wird es für den BC547 etwas eng und er muss eine zu hohe thermische Leistung verbraten. Daher dann der Wechsel zu einem BD439.

Warum ein ATtiny45 und nicht ein ATtiny25? Nun, das Assemblerprogramm ist recht umfangreich, vor allem wegen der RS232-Kommunikation und der vielen Einstellmöglichkeiten. Das hat alles nicht mehr in einen ATtiny25 reingepasst. Selbstverständlich kann auch ein ATtiny85 verwendet werden.

Top Funktionsweise Hardware Aufbau Software Algorithmen

2.1.2 Die Hardware von Indoor-Temperatursensoren

Schaltbild eines Indoor-Thermosensors Prinzipiell können beliebig viele zusätzliche Thermosensoren hinzugebaut werden, nur müssen sich alle Sensoren Infrarot-mäßig sehen, damit keine Sendekollissionen auftreten.

Die für zusätzliche Innenraum-Temperatursensoren nötige Hardware sieht ganz ähnlich aus. Unterschiede gibt es nur in folgender Hinsicht:
  1. Der Betrieb erfolgt aus dem gleichen Trafo-Netzteil, das auch den IR-Seriell-Umsetzer versorgt. Batterien oder Akkus sind daher nicht nötig. Die Versorgungsspannung des ATtiny45 ist auf +5V aus einem Spannungsregler eingestellt.
  2. Da der Betrieb der IR-LED aus der ungeregelten Versorgungsspannung mit ca. 10 V erfolgt, hat die Spannungsversorgung drei Anschlüsse (GND, +5V geregelt, +10V ungeregelt).
  3. Da der Transistor bis zu 10V bei maximal 100mA Konstantstrom verbraten muss, also bis zu einem halben Watt (50% An-Zeit), wird ein etwas größerer Typ eingesetzt.
  4. Statt der Niedrig-Strom-LEDs können normale LEDs eingesetzt werden, die mit einem höheren Strom versorgt werden.
Jeder Sensor kriegt seine eigene Device-Nummer, die er beim Senden und Empfangen auch auswertet, so dass die Sensoren individuell eingestellt werden können.

Man beachte, dass bei der niedrigen Baudrate der Sensoren jeder Sensor etwas Zeit für das Senden der langen Zeichenketten braucht. Stellt man daher sehr kurze Messdauern ein, wie z. B. eine Sekunde, und hat man die Baudrate auf 300 Baud eingestellt, dann kommt nur der Sensor mit der Nummer 0 zum Senden, alle anderen Sensoren verhungern, weil Nummer Null sie nachhaltig am Senden hindert.

2.1.3 Auswahl der Quarze

Mit dem Quarz müssen in Temperatursensoren folgende zeitrelevante Dinge erledigt werden:
  1. Die interne Uhr des Temperatursensors muss im Sekundentakt getaktet werden. Dazu dient der Counter/Timer TC1, der über einen umfangreichen Park an Vorteilern verfügt. Der Vorteiler wird so eingestellt, dass der Quarztakt durch den gewählten Vorteiler eine Ganzzahl ergibt. Diese wird dann durch einen ganzzahligen CTC-Wert geteilt, aus dem sich ebenfalls eine Ganzzahl ergibt. Diese wird dann in einem Register durch eine weitere Ganzzahl geteilt, woraus sich dann genau Eins ergeben muss.
  2. Beim Senden muss die IR-Diode mit der IR-Sendefrequenz (Default: 40 kHz) getaktet werden. Abweichungen vom Sollwert sind dabei um +/- 0,5 kHz noch tolerabel. Darüber wird es mulmig, ob der Empfänger das Signal noch erkennt.
  3. Beim Empfang der seriellen Signale muss die Baudrate stimmen (Default: 1.200 Baud). Abweichungen um +/- 1% sind ok, darüber wird es ebenfalls mulmig, weil der Einfachheit halber auf eine Nachjustierung der Flanken verzichtet wurde und die gesamte Dauer des Zeichens (Startbit plus acht Datenbits = 9 Bit) nur über den Standardtakt (bei 1,200 Baud sind das 833 µs) abgetastet wird.
  4. Nur bei der Uhr ist der Quarz wirklich nötig, schließlich will man die Uhr nicht täglich neu stellen müssen.
Da die Temperatursensoren mit 3,7 V aus einer Li-Zelle arbeiten, kommen Quarze oberhalb von 10 MHz nicht in Betracht, da diese erst ab 4,5 V Betriebsspannung zuverlässig den Tiny takten. Außerdem wollen wir ja so viel Strom sparen wie möglich.

Quarztabelle zur Taktung Die entsprechende Taktung wurde im Tabellenblatt "Taktung_Thermometer" der LibreOffice-Calc-Tabelle hier gerechnet. Für handelsübliche Quarze in Spalte G (rot markierte Frequenzen sind keine Quarze!) wird in Spalte I die resultierende IR-Frequenz gerechnet, Werte von 39,5 bis 40,5 kHz sind noch tolerabel (was mit allen hier abgebildeten Quarzen hinkommt).

Spalte K berechnet die resultierenden Baudraten beim Empfang. Man sieht, dass auch die Baudraten noch innerhalb der Toleranz liegen. Nur bei Quarzen mit sehr niedriger Frequenz ist Vorsicht geboten.

Die Spalten J und L berechnen das Quadrat der Abweichung von der Sollfrequenz, die Spalte M addiert beides. Mit Hilfe des Minimums in Zelle M2 kann man den optimalen Quarz für seine eigenen gewählten Bedingungen herausfinden.

Die Spalten N bis Q berechnen die für den TC1 erforderlichen Zahlen, die zur Taktung des 1-Hz-Signals für Uhrzeit und Datum gebraucht werden. Der Prescaler in Spalte N nutzt das erweiterte Spektrum des TC1 im ATtiny45.

Der ausgewählte Quarz gilt für die Temperatursensoren. Wie man sieht, ist nur der 7,68-MHz-Quarz ideal für alle drei Aufgaben. Nur mit dieser Frequenz treffen wir alle drei benötigten Frequenzen ganz genau. Wer will, kann aber auch abweichende Frequenzen verwenden, man muss es nur der Software beibringen.

Damit das ganz bequem geht, gibt es noch den gelb markierten Kopierbereich in diesem Tabellenblatt. Einfach alles einstellen, was hellgrün ist und dann den gelben Bereich mit Strg-C kopieren und mit Strg-V im Quellcode ablegen.

Top Funktionsweise Hardware Aufbau Software Algorithmen

2.2 Die Hardware des IR-Seriell-Umsetzers

Der IR-Seriell-Umsetzer empfängt die IR-Signale der Thermosensoren und wandelt sie in serielle Signale auf RS232-Spannungsniveau um. Umgekehrt setzt er von der seriellen Schnittstelle kommende Zeichen in Infrarot-Signale um und sendet diese mittels IR-Leuchtdiode an die Sensoren.

2.2.1 Schaltbild des IR-Seriell-Umsetzers

Schaltbild des IR-zu-Seriell-Umsetzers Der IR-zu-Seriell-Umsetzer besteht aus
  1. einer DB9-Buchse, die der zweiseitigen Kommunikation mit dem Rechner über einen USB-Seriell-Wandler dient,
  2. einem MAX232, der die Signalpegel sende- und empfangsmäßig auf RS232-Niveau bringt,
  3. dem Infrarot-Empfänger-Modul TSOP31240, das Infrarot-Signale empfängt, nach Frequenz filtert und an seinem Ausgang ausgibt,
  4. einem quarzgetakteten ATtiny25, der bei aktivem Sendesignal mittels eines Konstantstromreglers - mit einer roten Leuchtdiode und dem Transistor BD439 - eine IR-Sende-Diode im 40kHz-Rhythmus taktet,
  5. einer 6-poligen ISP-Schnittstelle, über die der ATtiny25 in der Schaltung programmiert werden kann.
Für den IR-zu-Seriell-Umsetzer ist nur das 40-kHz-Signal der IR-Diode zeitkritisch. Es kann daher fast jeder Quarz verwendet werden, er muss nur im Quellcode des Umsetzers angegeben werden. Bei mir ist es ein 4 MHz, das passt ganz genau. Ohne Quarz, also nur mit dem internen RC-Oszillator als Taktgeber, habe ich bei 5V Betriebsspannung 43 kHz gemessen. Das stellt nicht mehr sicher, dass 40kHz-Sensoren da noch ansprechen. Es darf also ruhig ein Quarz als Taktgeber sein.

Top Funktionsweise Hardware Aufbau Software Algorithmen

2.2.2 Trafo-Netzteil für den IR-Seriell-Umsetzer

Schaltbild des Trafonetzteils fuer den IR-zu-Seriell-Umsetzer Das ist das Trafonetzteil. Es liefert ungeregelte 10V für den Betrieb der Infrarot-LED sowie geregelte 5V für den ATtiny25 und den MAX232.

Das Netzteil unter 110 mA Laststrom Unter Last mit zwei Infrarot-Dioden im Gegentakt muss das Netzteil bis zu 110 mA Laststrom bringen. Das Bild zeigt, dass es dieses Maximal-Szenario glatt übersteht.

An die Anschlussbuchse für weitere Innenraum-Thermosensoren können weitere Sensoren aus diesem Netzteil versorgt werden. Da die IR-LEDs dieser Sensoren immer nur dann senden, wenn die IR-LED des Umsetzers inaktiv ist und wenn auch kein anderer Sensor gerade sendet, kann man recht viele Sensoren gleichzeitig an diesem Netzteil betreiben, ohne dass es zu Überlastung kommt. Ab etwa fünf wird es wegen der vielen grünen LEDs, die bei der Indoor-Variante immer an sind, aber kitzlig auf der 5V-Leitung. Dann diese in der Sensor-Software lieber als Outdoor-Variante konfigurieren, dann bleibt die grüne LED aus und geht nur beim Blinken kurz an.

Top Funktionsweise Hardware Aufbau Software Algorithmen

3 Aufbau

Ich habe alle Schaltungen auf Lochrasterplatinen aufgebaut. Daher gibt es hier auch keine gedruckten Schaltungen. Da alle Teile sehr einfach gestrickt sind, sollte ein PCB-Layout einfach zu erstellen sein.

3.1 Aufbau der Temperatursensoren

So sieht der Sensor in echt während der Aussendung aus.

Aussen-Sensor Bestueckung Thermosensor auf Lochraster Das ist die Bestückung der Temperatursensoren für draußen. Die Innenraum-Sensoren sind genauso aufgebaut, die drei Unterschiede sind:
  1. Die Stromversorgung von +5V für den Prozessor und +10V für die IR-LED werden separat zugeführt, dafür entfällt der teure Akku mit seiner Halterung.
  2. Wegen der höheren Leistung des Transistors wird ein BD439 anstelle des BC547 eingesetzt.
  3. Die beiden Widerstände vor der grünen und der roten LED sind ein wenig kleiner.
  4. Das Blinken ist nun umgekehrt: die grüne LED ist dauernd an und geht beim Blinken aus.
Von den Abmessungen her ist die Platine üppig dimensioniert. Wer unter chronischem Platzmangel leidet, kann es noch viel, viel kleiner realisieren.

Soll der Sensor draußen aufgestellt werden, dann ist, falls Regen auf die Schaltung fallen könnte, noch eine Regenabdeckung nötig. Falls man die Schaltung in eine Plastikschachtel verpacken will: das verzögert natürlich das Ansprechen des Sensors bei raschen Temperaturwechseln ein wenig. Und man sollte den IR-Sensor und die IR-LED außerhalb des Gehäuses anbringen, weil (auch durchsichtiges) Plastik die IR-Strahlung merklich absorbiert und damit Sende- und Empfangssignale abdämpft.

3.2 Stückliste der Sensoren

Stueckliste fuer den Aussensensor Dies ist die Stückliste für alle Bauteile des Außen-Thermometers. Drei Viertel des Gesamtpreises von 23€ gehen für die Lithium-Zelle und deren Halterung drauf. Wer sparen will: bei diesen beiden Teilen macht es dann mal wirklich Sinn, der Rest sind Peanuts. Ich habe die Li-Zelle und die Halterung für umme gekriegt (umme = südhessisch für umsonst), daher bitte bissige Bemerkungen über die gelogenen 9800 mAh unterlassen, denn einem geschenkten Gaul ...

3.3 Aufbau des Umsetzers

Bestueckung des Umsetzers auf einer Rasterplatine Das ist die Bestückung des Umsetzers mit Trafonetzteil auf einer Viertel-Euro-Platine. Die externen Verbindungen zu dem IR-Sensor-Modul und der IR-LED sind mit zwei Schraubklemmen realisiert, die Verbindung zur DB9-Buchse mit einer zweireihigen Stiftleiste. Für den Anschluss von In-door-Sensoren sind die Betriebsspannungen +5V und +10V an einer weiteren Schraubklemme verfügbar. Die Netzspannung wird an einer weiteren Schraubklemme zugeführt.

3.4 Stückliste für Umsetzer und Trafonetzteil

Stueckliste fuer Umsetzer mit Trafonetzteil Das hier ist die Stückliste für den IR-zu-Seriell-Umsetzer mit seinem Trafonetzteil. Ganz schön viele Kleinteile, mit knapp 20 Euronen sind Sie dabei.

Top Funktionsweise Hardware Aufbau Software Algorithmen

4 Software

Die Software für den Umsetzer und die Temperatursensoren befinden sich noch in der Entwicklung. Ich werde sie hier posten, wenn sie fertig sind.

Die Software ist für den ATtiny45 optimiert. Mit einem ATtiny25 erwies sich das Flash als zu eng. Insbesondere die RS232-Kommunikation benötigt ziemlich umfangreichen Code, daher hier der 45.

Bitte nach dem Brennen des Flash unbedingt auch noch die Fuses für den Quarzbetrieb noch beachten und setzen, sonst stimmt das ganze Timing rein gar nicht.

Top Funktionsweise Hardware Aufbau Software Algorithmen

5 Algorithmen

In den folgenden Kapiteln sind die Algorithmen beschrieben, die bei der Software verwendet werden.

5.1 Algorithmen beim Umsetzer

Flussdiagramm Blinkmechanimus Der Umsetzer arbeitet mit einem ATtiny25. Seine Aufgabe ist recht einfach: wenn das Sendesignal von der DB9-Buchse auf Low (nach dem MAX232-Inverter auf High) geht, sendet er mit 40 kHz über die IR-LED. Wenn nicht, macht er die IR-LED aus.

Verantwortlich für diese Umschaltung (IR-LED aus oder an) ist der INT0-Interrupt, der bei jedem Flankenwechsel anschlägt. Findet dieser eine Null am INT0-Eingang (PB2) vor, stellt er den OC0A-Ausgang auf Clear, die IR-LED geht aus. Ist es eine Eins, stellt er den OC0A-Ausgang auf Toggle um und die IR-LED geht an.

Für dieses Teil habe ich mir aber ein nettes Gimmick ausgedacht: die grüne LED an Pin PB1 (OC1A) blinkt im inaktiven Zustand mit einer niedrigen Frequenz (Default: 2 Hz). Geht der INT0-Eingang an PB2 aber auf Eins, weil am seriellen Eingang mindestens eine einzige Eins eintrifft, wird die Blinkfrequenz der LED auf den höheren Wert (5 Hz) umgestellt. Diese höhere Frequenz wird für einen einstellbaren Zeitraum nach dem Eintreffen des letzten Mark-Impulses von der seriellen Schnittstelle fortgesetzt.

Der Ausgang OC1A wird dazu dauerhaft auf Toggle eingestellt, der Compare-A-Wert bleibt auf Null. Damit bewirkt jeder Null-Durchgang von TC1 ein Umschalten des Blinkeingangs. Die Frequenz dieses Umschaltens wird bei 4 MHz Takt mittels eines Vorteilers von 4.096 und einem Compare-C-Wert von 243 eingestellt. Das teilt die Quarzfrequenz 4.000.000 / 4.096 / (243 + 1), so dass der OC1A-Ausgang mit 4 Hz torkelt, was einer Blinkfrequenz von 2 Hz entspricht. Bei 5 Hz Blinkfrequenz erledigt das ein Vorteiler von 2.048 und ein CTC-Wert von 195 (Compare C = 194), so dass OC1A mit 4.000.000 / 2.048 / (194 + 1) = 10 Hz torkelt.

Erscheint eine Eins am INT0-Eingang, wird auf jeden Fall schon mal der Torkelzähler rTgl auf seinen voreingestellten Wert gesetzt. Ist die Toggle-Flagge T im Statusregister schon auf Eins, ist die Routine fertig. Ist sie noch Null (beim ersten Eintreffen einer Eins am INT0-Eingang), dann wird der Zähler TC1 auf die höhere Blinkfrequenz umgestellt und der OCIE1B-Interrupt eingeschaltet.

Dieser Interrupt (rechts im Flussdiagramm) vermindert rTgl. Erreicht dieser Null, wird die T-Flagge auf Null gesetzt, der OCIE1B-Interrupt abgestellt und der Zähler TC1 wieder auf die langsamere Blinkfrequenz umgestellt.

Top Funktionsweise Hardware Aufbau Software Algorithmen

5.2 Algorithmen beim Thermosensor

Dass die Software der Thermosensoren ziemlich komplex ist, sieht man an den aktiven Interrupt-Vektoren. Sie sehen so aus:

;
; **********************************
; R E S E T  &  I N T - V E C T O R S
; **********************************
	rjmp Main ; Reset vector
	rjmp Int0Isr ; INT0
	reti ; PCI0
	rjmp Oc1aIsr ; OC1A
	reti ; OVF1
	reti ; OVF0
	rjmp ErdyIsr ; ERDY
	reti ; ACI
	rjmp AdccIsr ; ADCC
	reti ; OC1B
	rjmp Oc0aIsr ; OC0A
	reti ; OC0B
	reti ; WDT
	reti ; USI_START
	reti ; USI_OVF

Sechs der 15 Vektoren sind in Gebrauch, hinter dem Oc0aIsr stecken dabei in Wirklichkeit drei verschiedene Arten von Reaktionen, je nachdem ob gerade gesendet, empfangen oder auf den Sendestart gewartet wird.

Die einzelnen Bestandteile der Thermosensoren sind im Folgenden nacheinander im Detail beschrieben.

Top Funktionsweise Hardware Aufbau Software Algorithmen

5.2.1 Die Uhr im Thermosensor

Flussdiagramm des Blinkers Jeder Thermosensor hat eine eingebaute Quarzuhr. Das ermöglicht es, dass alle gesendeten Temperaturen mit Datum und Uhrzeit gestempelt sind. Das Datum aller Quarzuhren kann mit dem Befehl "D=26.02.23" über die serielle Schnittstelle eingestellt werden, die Uhrzeit mit "T=12:34:56". Danach gehen alle Sensoren auf gleiches Datum und Uhrzeit.

Zur Taktung der Uhr teilt der Timer TC1 den Prozessortakt durch einen Vorteiler und im CTC-Modus durch den Compare-A-Wert. Erreicht der Timer den Compare-A-Wert, wird der OC1A-Interrupt ausgelöst.

In der entsprechenden Interrupt-Service-Routine wird, abhängig von der Anzahl an cTc1Bits folgendes ausgeführt:
  1. cTc1Bits = 0: Die Flagge bSec im Flaggenregister wird gesetzt.
  2. cTc1Bits = 8: Ein 8-Bit-Zähler im SRAM, sTc1Cnt, wird erniedrigt. Erreicht er Null, wird die Flagge bSec gesetzt und der Zähler neu mit cTc1Cnt gestartet.
  3. cTc1Bits > 8: Ein 16-Bit-Zähler im SRAM, sTc1Cnt+1:sTc1Cnt, wird um Eins erniedrigt. Erreichen beide Bytes Null, wird die Flagge bSec gesetzt und der Zeiger neu mit cTc1Cnt gestartet.
Der solchermaßen durch den Vorteiler, durch den CTC-Compare-A-Wert und den Null-/Acht-/16-Bit-Teiler geteilte Wert ergibt den Taktwert, mit dem die grüne LED blinken soll. Dies kann eine Sekunde, eine halbe Sekunde, eine Viertel-Sekunde oder jeden Wert in der Zelle B57 der Tabellenkalkulation in der Tabelle "Taktung_Thermometer" sein.

Die weitere Bearbeitung der Zeitinformation erfolgt außerhalb der ISR in der Routine HdlSec:.

Die Taktung der grünen LED erfolgt mit diesem Takt. Die Flagge bBlk zeigt an, ob gerade aktiv geblinkt wird. Ist sie gesetzt, dann wird durch Ausgabe an das PINB-Portregister der Portausgang invertiert und der Blinkzähler um Eins reduziert. Erreicht dieser Null, wird die bBlk-Flagge abgeschaltet.

In den Zähler Z+dBlink muss immer ein geradzahliger Wert eingetragen werden, denn nach dem Ende des Blinkens muss sowohl die netzbetriebene als auch die akku-betriebene Version wieder bei ihrem Ausgangs-Ruhestand ankommen.

Der 8-Bit-Zähler in Z+dSecCnt zählt die Teile der Sekunde ab, die bis zu einer Sekunde nötig ist.

Das Erhöhen der Uhr um eine Sekunde beginnt mit der Abfrage, ob das aktuelle Messintervall ungleich Null ist. Ist das der Fall, wird der 16-Bitzähler in sMeasCnt+1:sMeasCnt um Eins erniedrigt. Wenn er Null erreicht, wird er neu mit dem Messintervall in sMeasInt+1:sMeasInt gestartet und die nächste Messung gestartet. Sind 128 Messungen ausgeführt, wird die Temperatur berechnet, in eine Zeichenkette umgeformt und diese über die serielle Schnittstelle ausgesendet (siehe die nächsten drei Unterkapitel).

Addieren einer Sekunde zu Uhrzeit/Datum Das Erhöhen der Sekunde der Uhrzeit setzt, wenn der Tag zu Ende ist, auch das Datum um Eins höher.

Das hier ist der Algorithmus, um die Zeit und eventuell das Datum um eine Sekunde zu erhöhen. Links die Uhrzeit-Erhöhung, rechts am Ende des Tages die Datumserhöhung. Der umfangreiche Verhau rechts dient dazu, zu erkennen, ob schon der nächste Monat anbricht. Irgendwelche Beschwerden zur Kompliziertheit bitte an Papst Gregor in 15.-ten Jahrhundert richten, der diese Kompliziertheit gebraucht hat, um das nervöse Eiern der Erde um die Sonne korrekt abzubilden.

Da der Messzyklus schon zu Beginn gestartet worden ist, stellt sich die Frage, ob der nächste Messzyklus nun den alten oder den neuen Zeitstempel tragen wird (was ein Unterschied von bis zu einem Jahr sein kann). Nun, diese Sekundenerhöhung wird erst ganz und in allen gregorianischen Verästelungen durchgezogen, bevor die eventuell schon gesetzte bAdc-Flagge ausgewertet werden wird. Irgendwelche Schutzmaßnahmen gegen erst teilweise Zeit-und-Datums-Setzungen sind daher nicht vonnöten.

Top Funktionsweise Hardware Aufbau Software Algorithmen

5.2.2 Messen der Temperatur im Sensor

Der Temperatursensor im ATtiny45 ist an der Multiplex-Adresse 0b1111 in ADMUX verfügbar. Da zum Temperaturmessen der AD-Wandler auf die interne Referenzspannung von 1,1V eingestellt werden muss, sind auch die REF-Bits in ADMUX entsprechend einzustellen.

Quadratische Funktion ADC-zu-T Das Handbuch des ATtiny45 gibt folgenden Zusammenhang zwischen der Temperatur und dem ADC-Resultat an:

°CADC
-40230
25300
85370


Dahinter steckt alles andere als eine glatte lineare Funktion, wie das Diagramm rechts zeigt. Aus den gemessenen ADC-Werten soll die Temperatur in K errechnet werden. Hier sind die beiden linearen Funktionen zu sehen, wie sie sich aus den beiden unteren und den beiden oberen Daten ergeben. Weder die Steigungen noch die Ordinatenabschnitte sind bei beiden Funktionen irgendwie gleich. Auf einer solchen Basis lässt sich allenfalls ein grobes Schätzometer basteln, aber nix mit einer irgendwie genaueren Kommastelle bei der Temperatur.

Quadratische Funktion ADC-zu-T Wie schon in einem anderen Projekt (siehe hier) habe ich daher eine quadratische Gleichung entwickelt, mit der diese Werte viel besser zu interpolieren sind: T = a * ADC2 + b * ADC + c. Wobei T die Temperatur in Kelvin sein sollte. Mit den Originalwerten von ATMEL sind die im Diagramm angegebenen Werte für die drei Parameter der Funktion erkennbar.

Der Parameter a, der quadratische Teil, ist negativ, d.h. die Kurve ist leicht nach unten durchgebogen. Auch der Parameter c ist negativ. Aber der lineare Anteil b ist alles andere als 1, wie ATMEL es vorschlägt.

Nun ist die Multiplikation mit 0,000510 oder mit 1,198980 nicht so ganz nach dem Geschmack von Assembler-Programmierern: das schreit zu sehr nach der Fließkommabibliothek, und die passt nicht in den Flash vom ATtiny45. Aber im Gegensatz zum C-Abhängigen weiß sich der Assembler-Programmierer auch anders zu helfen. Und das geht so.

Die resultierende Temperatur soll mit 0,1° Auflösung ausgegeben werden. Wenn wir T mit 10 multiplizieren, kriegen wir schon mal hier die Kommazahl weg und wir müssen bei der Ausgabe der Temperatur nur vor der letzten Ziffer ein Dezimalkomma einschmuggeln.

Und natürlich müssen wir die Temperatur mehrfach messen, damit wir das zufallsbedingte Klappern des letzten ADC-Bits loswerden. Um noch genauer zu werden, können wir sogar 128 Messungen vollführen und aufsummieren, ohne dass ein 16-Bit-Addierer überzulaufen droht. Ein Überlauf träte dann erst bei 191°C auf, aber da ist der Prozessor schon anderweitig kaputt und verschmolzen.

Auch das Aufsummieren steigert noch mal die Genauigkeit. Unsere Gleichung lautet daher eher
10*T = a * 128*ADC2 + b * 128*ADC + c

Im Blatt "Temp-Skalierung" der LibreOffice-Calc-Datei hier kriegen wir a, b und c ausgerechnet.

Unterschied zwischen Linearfunktion und quadratischer Funktion Das hier demonstriert den Unterschied zwischen der Linearfunktion und der Quadratfunktion bei einer Temperatur zwischen 45 und 50°C. Das Delta (rote Kurve, rechte Skala) beläuft sich durchgängig auf mehr als ein halbes Grad, so ist eine Auflösung von +/-0,2° linear nicht erreichbar, nur die quadratische Funktion bietet das. Das bisschen Differenz lohnt schon den erhöhten Aufwand, damit unser Temperatursensor mit gutem Gewissen 0,1° vermelden kann und seine echte Auflösung unter ein Grad kommt.

Top Funktionsweise Hardware Aufbau Software Algorithmen

5.2.3 Umrechnen der Messungen in Temperaturen

Noch eine weitere Hürde ist das Multiplizieren mit 3,114E-07 und mit 0,093670. Damit wir damit weiterkommen, hat der Assembler-Programmierer noch einen Trick in petto: er multipliziert die 3,114E-7 einfach mit 65.536 * 65.536, was 1.337 gibt, und lässt dafür die vier unteren Bytes des Ergebnisses einfach wegfallen. Genauso mit 0,093670: mit 65.536 malgenommen gibt das gerundet 6139, dafür ignoriert er die beiden unteren Bytes des Ergebnisses.

Das ergibt die in der Spalte L versammelten Assembler-Codezeilen:

; Parameters, export from spreadsheet to source code
  .equ cParA = 1337 ; 65536*65536*a in 10*T=-a*128ADC*128ADC+b*128ADC-c
  .equ cParB = 6139 ; 65536*b in 10*T=-a*128ADC*128ADC+b*128ADC-c
  .equ cParC = 156 ; c in 10*T=-a*128ADC*128ADC+b*128ADC-c

Mit diesen generischen Werten rechnet der Temperatursensor so lange, bis er über die serielle Schnittstelle andere Werte geschrieben kriegt.

Sowohl die 128-er ADC-Summe als auch die drei Parameter passen in 16 Bits. Man braucht daher nur
  1. den Parameter b mit der 128-er-Summe multiplizieren und speichern, und dann
  2. den Parameter a mit der 128-er-Summe multiplizieren, durch 65.536 teilen und erneut mit der 128-er-Summe multiplizieren, sowie dieses Ergebnis vom vorherigen abziehen, und
  3. den Parameter c vom vorherigen Ergebnis abziehen (von den obersten zwei Bytes), und
  4. von den vier Bytes die untersten beiden zum Runden zu verwenden
und schon hat man die Temperatur in Kelvin (mal 10).

In Abhängigkeit von den beiden Flaggen bTC und bTF muss man daraus eventuell noch die Celsius oder Fahrenheit ermitteln, indem man 273,15 (mal 10) abzieht und, bei Fahrenheit noch zusätzlich mit 1,8 (mal 10) malnimmt und 32 (mal 10) hinzuaddiert. Falls dieses Ergebnis negativ ist, muss man eine Flagge setzen und die Differenz aus 65536 - Wert bilden. Die 16-Bit-Zahl ist das Ergebnis in 10*Temperatur.

Top Funktionsweise Hardware Aufbau Software Algorithmen

5.2.4 Eintrag der Temperatur in den Sendepuffer

Der Rest ist nun schlichtes Handwerk:
  1. den Sendezeiger X auf den Anfang des Puffers setzen,
  2. .
  3. das Kennzeichen des Sensors (0 bis 9) und ein Minus-Zeichen rein,
  4. das Datum in der richtigen Formatierung (deutsch/englisch) in den Sendepuffer, gefolgt von einem Minus,
  5. die Uhrzeit, getrennt mit ":", in den Sendepuffer, gefolgt von einem "=",
  6. falls die Temperatur negativ ist, ein Minuszeichen dazu,
  7. die Temperatur als positive Ganzzahl mit einem Punkt oder Komma vor der letzten Ziffer,
  8. Wagenrücklauf, Zeilenvorschub, das Cursorzeichen und die abschließende Null rein,
  9. den Sendezeiger X wieder auf Anfang, und
  10. die Warteflagge setzen, um den Sendepuffer auszusenden.
Ab jetzt ist der Sender für 250 ms lang damit befasst, das Ergebnis an die serielle Schnittstelle zu senden (siehe nächstes Unterkapitel).

Top Funktionsweise Hardware Aufbau Software Algorithmen

5.2.5 Senden des Sendepuffers

Die Taktung beim Senden Das hier zeigt die Taktung eines seriellen Zeichens am Sende-Ausgang OC0A: die IR-LED ist entweder mit 40kHz am Torkeln (TGL), wenn das Startbit oder ein Eins-Bit gesendet wird, oder es wird Null, wenn Stop-Bits oder Null-Bits gesendet werden (CLR). Man beachte noch, dass das DB9-Signal TXD im MAX232 einmal invertiert wird, bevor es zum INT0-Eingang des ATtiny25 gelangt.

Unmittelbar nach dem Senden des zweiten Stop-Bits beginnt das Aussenden des Startbits für das n&auchl;chste Byte.

Flussdiagramm Senden Ist die Flagge bTx gesetzt, dann sendet der Sensor gerade.

Beim Senden wird der X-Zeiger dazu verwendet, um auf das nächste zu sendende Zeichen im Sendepuffer sTx zu zeigen. Der Sendepuffer ist null-terminiert, bei Null wird die Sendung beendet.

Der Sende-Algorithmus wird vom TC0-Compare-A-Interrupt angetrieben. Da dieser Interrupt auch beim Warten vor dem Senden (siehe nächstes Unterkapitel) und beim Empfang (siehe übernächstes Unterkapitel) verwendet wird, erfolgt zunächst die Abfrage, ob die bTx-Flagge gesetzt ist. Falls das der Fall ist, wird zum Sendezweig verzweigt (links) und der 16-Bit-Zähler rCntH:rCntL abwärts gezählt. Dieser Zähler zählt die Anzahl an Torkelvorgängen, die für das Senden eines Bits nötig sind. Bei 1.200 Baud sind das 67. Ist diese Anzahl noch nicht erreicht, ist die ISR vorzeitig zu Ende und es darf weiter getoggelt werden.

Falls das Zählergebnis Null ist, wird der 16-Bit-Zähler wieder mit der Zähldauer neu geladen. Nun wird die Anzahl gesendeter Bits um Eins vermindert. Ist diese Null, dann wird das nächste Zeichen aus dem Puffer gelesen. Ist dieses Zeichen Null, wird das Senden beendet, indem
  1. die Sendeflagge bTx gelöscht wird, und
  2. der Timer-Interrupt für TC0 gel&aouml;scht wird (so dass nur noch der Uhren-Interrupt in TC1 aktiv bleibt), und
  3. die OC0A-Ausgabe auf Clear geschaltet wird.
Wenn das Zeichen nicht Null war, wird rBit auf 11 gesetzt (1 Startbit, 8 Datenbits, 2 Stop-Bits) und OC0A auf Torkeln eingestellt (was das Startbit sendet).

War rBit beim Dekrementieren nicht Null, wird rimp auf OC0A-Clear eingestellt und geprüft, ob Stopbits gesendet werden (rBits<3). Falls dies nicht der Fall ist, wird das nächste zu sendende Bit aus dem Register rTx in das Carry geschoben. Handelt es sich um eine Eins, wird rimp auf OC0A-Toggle eingestellt. Der Wert von rimp wird schließlich in das Kontrollregister A von TC0 geschrieben.

Alle Ausführungszeiten, als Taktzyklen in rot dargestellt, bleiben unterhalb der Schwelle von 38 Taktzyklen, die bei einem Quarztakt von nur 3 MHz und einer IR-Frequenz von 40 kHz bis zum nächsten TC0-CompA-Interrupt verbleiben. Einzig im Falle, dass der Wartezyklus gerade beendet wird und das Senden des ersten Zeichens im Puffer beginnt, wird diese Schwelle erreicht. Da für die nächste Interrupt-Auslösung aber noch fünf Takte nötig sind, ist auch dies keine Verzögerung von Relevanz. Da ein Interrupt-Verlust erst nach weiteren 38 Taktzyklen einträte, ist auch dies sehr unwahrscheinlich und nahezu ausgeschlossen. Da während des Senden andere Interrupts ausgeschaltet sind (INT0-Interrupt, ADC-Interrupts) oder nur sehr kurz sind (nur sehr selten auftretende TC1-Compare-Matches), kann es auch nicht durch andere Interrupts zu Konflikten kommen. Weil der Quarz statt 3 aber 4 MHz hat, sind es ohnehin 55 Taktzyklen bis zum Eintritt des nächsten Interrupts und über 90 bis zum Verlust eine Interrupts.

Torkeln des PB0-Ausganges mit 40 kHz beim Senden des Startbits Das hier ist das Impulsdiagramm am OC0A-Ausgang, wenn das Startbit gesendet wird. Die Anzahl Torkeleien passt dabei exakt zur Baudrate (1 / 1200 = 833µs).

Torkeln des PB0-Ausganges beim Senden von 0b0101 Das hier zeigt das Torkeln des OC0A-Ausganges, wenn ein Startbit und das oberste Nibble des Datenbytes 0x55 mit 1.200 Baud gesendet wird. Die IR-Sendefrequenz von 40 kHz wird genau eingehalten, die LED ist 50% der Zeit an. Das erste Bit, das Startbit, wird gefolgt von dem obersten Sendebit, einer Null. Danach kommt eine Eins, wieder eine Null und noch eine Eins. Alle Signaldauern dauern gleich lang. So mag es der IR-Empfänger.

Torkeln des PB0-Ausganges beim Senden von 0x55 Das ist nun das ganze 0x55-Byte und der Beginn des nächsten Startbits. Man erkennt das doppelte Stopbit (8N2) zwischen diesem und dem nächsten übertragenen Zeichen.

Torkeln des PB0-Ausganges beim Senden von zwei mal 0x55 Das ganze nun zwei Male. Der Zwischenraum der beiden Stopbits dauert die halbe Baudrate, bei ca. 1.200 Baud sind das knapp 600 Hz.

Top Funktionsweise Hardware Aufbau Software Algorithmen

5.2.6 Wartezeit vor dem Senden

Damit sich die Temperaturmeldungen mehrerer Sensoren nicht gegenseitig stören, wartet der Prozessor mit dem Senden eine Zeit lang ab, während keiner der anderen Sender senden darf. Wird in dieser Zeit ein Sendesignal eines anderen Sensors bemerkt, beginnt diese Abtastzeit von vorne.

Da der Abtastzeitraum jedes Sensors eine individuell lange Zeitdauer andauert, ist gewährleistet, dass alle Sensoren nacheinander in der vorgewählten Reihenfolge mit dem Senden drankommen.

Flussdiagramm der Wartezyklen vor dem Senden Das ist der Ablauf der Wartezyklen. Er ist als weiterer Teil in der TC0-Compare-A-Interrupt-Service-Routine eingebaut und wird dann angesteuert, wenn sowohl die bTx- als auch die bRx-Flagge aus sind und wenn die bRq-Flagge (Rq = Request TX) gesetzt ist. Wenn alle drei Flaggen Null sind, wird der OCIE0-Interrupt ausgeschaltet.

Ist der Infrarot-Empfänger-Ausgang am PB2-Eingang auf Null, dann sendet gerade ein anderer Sensor. Dann wird der Zähler wieder mit seinem Ausgangswert neu gestartet und die Wartezeit beginnt von vorne.

Wenn nicht, dann wird der Zähler um Eins vermindert. Ist er noch nicht Null, wird einfach weiter gewartet. Der Abtastzeitraum (Taktung von TC0, Anzahl Interrupts) erfolgt mittels Konstanten, die von der Taktfrequenz, der eingestellten Baudrate und der ID des Sensors abhängig ist, ihre Berechnung erfolgt in der Tabellenkalkulation.

Hat der Zähler Null erreicht, dann wird mit dem Senden begonnen. Dazu wird
  1. die Request-Flagge gelöscht, und
  2. die Sende-Flagge gesetzt, und
  3. der X-Zeiger auf den Beginn des Textpuffers gesetzt, und
  4. das erste Zeichen in das Senderegister eingelesen, und
  5. der INT0-Interrupt ausgeschaltet, da ja jetzt das Senden beginnt und der Interrupt schaden würde, und
  6. der Zähler auf die Anzahl IR-Signale pro seriellem Bit eingestellt, und
  7. der CompareA-Wert von TC0 auf den IR-Sende-Wert eingestellt, und
  8. der Prescaler von TC0 auf Eins umgestellt.
Danach wird das Startbit gesendet, wozu an die entsprechende Teilroutine des Sende-Algorithmus gesprungen wird.

Alle weiteren Bits des ersten Bytes werden bei gesetzter bTx-Flagge ausgesendet.

Top Funktionsweise Hardware Aufbau Software Algorithmen

5.2.7 Empfang in den Empfangspuffer

Taktung beim seriellen Empfang Beim Empfang ist die Flagge bRx im Flaggenregister gesetzt. In diesem Fall tastet jeder TC0-Compare-Match-A-Interrupt den IR-Sensor-Eingang auf das nächste eingehende Bit ab.

Da der Tipper beim seriellen Senden viele, viele Millisekunden braucht, bis er die nächste Taste gefunden (beim System Kolumbus: jede Taste eine Entdeckung) und betätigt hat, beginnt der Empfang jedes einzelnen Zeichens, wenn das Startbit am INT0/PB2-Eingang eintrifft. Dann stellt sich der INT0-Interrupt wieder aus und es beginnt das Einsammeln der 11 Bits. Das Sammeln erfolgt jeweils zu einem Zeitpunkt um die Mitte des Bits herum, weshalb der Zeitraum zwischen INT0 und dem Abtasten des siebten Datenbits etwa ein-ein-halb Bits Dauer andauert. Danach erfolgt jeweils das Abtasten nach dem Ablauf einer Bitdauer.

Sind Startbits plus acht Datenbits plus das erste Stopbit abgetastet, ist das Zeichen komplett, der Empfangsmodus wird wieder verlassen und der INT0-Interrupt wird wieder aktiviert.

Weil der IR-Seriell-Umsetzer durch die Infrarot-Kopplung vom Computer gesendete Zeichen auf der seriellen Schnittstelle zurücksendet, und damit einen Loop darstellt, brauchen eingegangene Zeichen vom Thermosensor nicht mit einem Echo zurückgespielt werden. Das vereinfacht das Programm, da daher nicht ständig von Empfang auf Senden umgestellt werden muss. Es wäre möglich (z. B. sich die Sende-LED und das Empfangsmodul beim Umsetzer nicht sehen würden), aber meistens ist das unnötig, weil das Fensterglas genug IR-Strahlung zurückspiegelt.

Flussdiagramm fuer den Empfang Vor dem Empfang wartet der IR-Empfänger TSOP31240 auf den Eingang von 10 IR-Impulsen und aktiviert danach seinen Ausgang, indem er ihn auf Null zieht. Der ist an PB2=INT0 angeschlossen. Der negative Impuls an PB2 löst einen INT0-Interrupt aus. Dies schaltet den INT0-Interrupt aus, setzt die bRx-Flagge im Flaggenregister, setzt den Bitzähler rBits auf 9 und startet TC0 mit folgenden Einstellungen: Nun läuft folgendes ab:
  1. Der Zähler rBit wird um Eins erniedrigt. Wird er Null, dann ist der Empfang eines Zeichens zu Ende. Wenn nicht geht es wie folgt weiter.
  2. Immer, wenn die Zeit im Zähler rum ist, wird der Zustand des Eingangs abgefragt. Ist er Null, wird eine Eins in das Register rRx von rechts nach links eingeschoben. Ist er Eins, wird eine Null eingeschoben.
  3. Das Vergleichsregister wird auf die Dauer cTc0Rx bis zum Einlesen des nächsten Bits eingestellt (bei 4 MHz und 1200 Baud sind das 52, denn 4.000.000 / 64 / 1200 = 52, wegen der Verzögerung durch den Interrupt bleibt es dabei).
Wenn der Empfang eines 8-Bit-Zeichens beendet ist, was etwa in der Mitte des ersten Stop-Bits eintritt, dann geht folgendes ab:
  1. Das empfangene Zeichen wird im SRAM-Puffer sRx gespeichert, auf den der Y-Zeiger zeigt.
  2. Es wird getestet, ob sich der Empfangszeiger danach auf dem Ende des Empfangspuffers befindet. Ist das der Fall, wird der Y-Zeiger auf den Anfang des Empfangspuffers gestellt und ein unbekannter Befehlscode an den Anfang geschrieben, was bei der Auswertung eine Fehlermeldung provoziert.
  3. Danach wird ein Zeichenkette-Ende-Zeichen an die nächste Position im Empfangspuffer geschrieben.
  4. Weitere Interrupts von TC0-Compare-A werden unterbunden, nur die Uhr in TC1 läuft weiter.
  5. Die bRx-Flagge wird gelöscht, der weitere Empfang dadurch unterbunden. Er wird erst wieder eingeschaltet, sobald das nächste Startbit eintrifft.
  6. Dann wird getestet, ob es sich bei dem empfangenen Zeichen um einen Zeilenvorschub handelte. Falls das der Fall ist, wird die Flagge bRxL gesetzt, die die Auswertung der empfangenen Zeile veranlasst.
  7. Ist das Zeichen kein Wagenrücklauf, werden die INT0-Interrupts wieder zugelassen und der Prozessor wartet auf das nächste Startbit.
Noch eine Überlegung zu Empfangsfehlern durch Fehlzeiten. Ein Fehler bei der Taktung tritt ein, wenn sich der Abtasttakt um eine halbe Bitzeit nach vorne oder hinten verschöbe. Da neun Bits zu lesen sind, wäre das der Fall, wenn der Takt sich um 52 / 9 pro Bit verschöbe. Das sind knapp mehr als fünf Takte pro Empfangs-Bit. Da der Vorteiler mit 64 läuft, machen da wenige Prozessortakte Verzögerung praktisch gar nichts aus.

Der Empfänger spricht erst nach 10 IR-Takten an, bleibt dafür aber noch etwas nach Verschwinden des Signals eine Weile lang an. Dadurch werden alle Signale etwas später erkannt, der Unterschied bleibt aber der Gleiche. 10 IR-Takte entsprechen bei 40 kHz einem Zeitraum von 250 µs. Der Abtastzeitraum liegt hingegen bei 896 µs, für ein halbes Bit 498 µs. Also ist da ebenfalls noch jede Menge Platz dazwischen.

Insgesamt ist da also noch viel Luft für Fehltakte, bis ein echter Lesefehler einträte.

Top Funktionsweise Hardware Aufbau Software Algorithmen

5.2.8 Auswertung der empfangenen Zeile

Befehle an Thermosensoren Stellt der Prozessor nach dem Bearbeiten der Interrupts fest, dass das Flaggenbit bRxL gesetzt ist, muss die eingegangene empfangene Zeile ausgewertet werden.

Zunächst wird die eingegangene Zeile umformatiert:
  1. Alle ASCII-Kontrollzeichen, Leerzeichen und Minussymbole werden aus der Empfangszeile entfernt.
  2. Alle Kleinbuchstaben werden in Großbuchstaben umgewandelt.
Dann wird die verbleibende Zeile ausgewertet:
  1. Ist das erste eingegangene Zeichen eine Ziffer zwischen Null und Neun, dann wird geprüft, ob es sich um die eigene Sensornummer handelt. Ist das nicht der Fall, wird die weitere Auswertung abgebrochen.
  2. Dann wird das Zeichen auf folgende Zeichen überprüft: "D, T, M, K, C, F, A, B, ?, H". Auf die Zeichen "D, T, M, A, B, C" KANN ein "=" folgen. Ist das der Fall, werden, kann bei den folgenden Zeichen folgendes veranlasst werden:
  3. Wird ein Fehler festgestellt, kommt eine aussagekräftige Fehlermeldung zurück und die grüne LED blinkt einmal, ansonsten wird entweder mit Datum, Uhrzeit und aktueller Temperatur oder mit dem aktuellen Parameterwert geantwortet und die grüne LED blinkt drei mal.
Bitte beachten: bei Umstellungen mit "TK/TC/TF, M, A, B, C" werden die geänderten Werte in das EEPROM geschrieben. Sie werden bei nachfolgenden Prozessorstarts von dort jeweils mit ihrem letzten Stand eingelesen. Diese Befehle müssen daher beim Neustart nicht erneut gesendet werden.

Viel Erfolg bei der Kommunikation mit den Teilen.

Top Funktionsweise Hardware Aufbau Software Algorithmen


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