Ein digitales Thermometer oder rede I2C mit deinem Microcontroller

ArticleCategory: [Choose a category, do not translate this]

Hardware

AuthorImage:[Here we need a little image from you]

[Photo of the Author]

TranslationInfo:[Author + translation history. mailto: or http://homepage]

original in en Guido Socher

en to de Guido Socher

AboutTheAuthor:[A small biography about the author]

Guido mag Linux weil es ein wirklich gutes System ist um eigene Hardware zu entwickeln

Abstract:[Here you write a little summary]

Der Atmega8 Microcontroller von Atmel hat jede Menge digitale und analoge Ein-/Ausg�nge. Es ist das ideale Bauteil um Me�elektronik zu entwickeln.

In diesem Artikel werden wir sehen wie man einen Microcontroller mit einem Linux PC �ber eine physikalische RS232 Schnittstelle verbinden kann, ohne aufwendige Adapterschaltungen wie den MAX232 Chip zu benutzen.

ArticleIllustration:[This is the title picture for your article]

[Illustration]

ArticleBody:[The article body]

Einf�hrung

Eine Voraussetzung f�r diesen Artikel ist, da� du die GCC AVR Programmierumgebung, wie in den dem Artikel "Programmieren eines AVR Microcontrollers mit GCC, libc 1.0.4" beschrieben, installiert hast. Nat�rlich kannst du, um �rger bei der Installation zu vermeiden, auch die "AVR programming CD" von http://shop.tuxgraphics.org/ benutzen.


Wenn man so ein enorm m�chtiges Bauteil wie einen Microcontroller benutzt, um analoge oder digitale Signale zu messen, dann m�chte man nat�rlich Schnittstellen zum Auswerten haben und Befehle an den Microcontroller schicken k�nnen. In allen vorangegangenen Artikeln haben wir immer die RS232 Schnittstelle mit einem UART zur Kommunikation benutzt. Der Nachteil ist hierbei, da� man einen zus�tzlichen MAX232 Chip und 4 Kondensatoren braucht. Atmel schl�gt sogar vor, da� man einen externen Quarz f�r den Oszillator benutzen soll damit die UART Kommunikation zuverl�ssig funktioniert. In jeden Fall sind das eine Menge extra Bauteile.... und diese kann man vermeiden!

Die Menge an Daten, die zwischen PC und Microcontroller �bertragen werden m�ssen ist normalerweise klein (nur einige Bytes). Die �bertragungsgeschwindigkeit spielt daher praktisch keine Rolle. Das macht den I2C Bus attraktiv f�r diese Aufgabe.

I2C (ausgesprochen "ei-squ�r-sie") ist ein bidirektionales Kommunikationssystem mit nur zwei Dr�hten. Es wurden von Philips entwickelt und sie haben sich den Namen sch�tzen lassen. Daher nennen es andere Hersteller nicht I2C. Bei Atmel hei�t es TWI ("two wire interface").

Viele von euch benutzen m�glicherweise I2C in ihrem PC ohne es zu wissen. Alle modernen Motherboards haben einen I2C-Bus um Temperatursensoren, L�ftergeschwingigkeit, verf�gbaren Speicher... und alle m�glichen anderen Daten zu lesen. Dieser I2C-Bus ist leider am normalen PC nicht nach au�en gef�hrt (es gibt au�en keine physikalischen Anschlu� daf�r). Wir m�ssen uns deshalb etwas neues �berlegen.

Erst wollen wir aber sehen, wie das "two wire interface" (=TWI = anderer Name f�r I2C) funktioniert.

Wie I2C/TWI funktioniert

Das Datenblatt des Atmega8 (siehe unten) hat eine sehr detaillierte Beschreibung, die auf Seite 160 beginnt. Ich werde deshalb hier nur einen �berblick geben. Danach solltest du in der Lage sein, das Datenblatt zu verstehen.

An einem I2C-Bus hat man immer einen "Master" und verschiedene "Slaves". Die Kommunikation findet zu einem Zeitpunkt immer zwischen dem Master und genau einem Slave statt. Der Master ist das Ger�t, das die Kommunikation beginnt und und den Bit-Takt (clock) kontrolliert. Die zwei Dr�hte des I2C-Bus nennen sich SDA (Datenleitung) und SCL (Clock line, Taktleitung). Jedes der Ger�te mu� von einer separaten Stromversorgung (genau wie bei normaler rs232 Kommunikation) gespeist werden. Die zwei Dr�hte des Busses sind normalerweise �ber 4.7K Widerst�nde mit der logischen Eins (+5V f�r 5V ICs) verbunden. Das ergibt eine elektrische Veroderung zwischen den Ger�ten. Ein Ger�t braucht dann nur die Leitung auf GND ziehen, wenn es eine 0 �bertragen will oder nichts machen, wenn es eine 1 senden will.

Der Master beginnt einen Dialog indem er ein Bitmuster, das als "start condition" gefolgt von der Adresse des Ger�tes das er ansprechen m�chte, schickt. Jedes Ger�t an dem Bus hat eine eindeutige 7 Bit Adresse. Danach schickt der Master ein Bit das anzeigt ob er lesen oder schreiben m�chte. Der Slave (das angesprochene Ger�t) wird nun best�tigen, da� es den Master verstanden hat und schickt ein ack-bit (ack wie acknowledge). Mit anderen Worten wir haben jetzt 9 Datenbits auf dem Bus gesehen (7 Adressbits + read_bit + ack-bit):
| start | 7-bit slave adr | read_data bit | wait for ack | ... data comes here 
Was kommt danach?

Als n�chstes k�nnen wir Daten senden oder empfangen. Die Daten sind immer ein Vielfaches von 8 Bit (1 Byte) und m�ssen durch ein Ack-Bit best�tigt werden. Es werden also immer 9 Bit �ber den Bus geschickt. Wenn die Kommunikation zu ende ist, schickt der Master ein Bitmuster namens "stop condition". Mit anderen Worten der Master mu� wissen, wie viele Daten der Slave schicken m�chte. Das ist aber kein Problem, denn man kann diese Information immer in den Dialog zwischen Master und Slave mit den Daten �bertragen. In unserem Fall werden wir z.B. das Null-Byte am Ende eines Strings benutzen um anzuzeigen, da� der �bertragene String zu ende ist.

Die Daten auf dem SDA Draht sind immer solange g�ltig wie SCL 1 ist. SDA darf sich also nicht �ndern w�hrend SCL 1 ist:
SDA H -\       /---\     /---\          /---\      
    L   \-----/     \---/     \--------/     \------....

SCL H ----\     /-\       /-\     /-\    /-\    /-\ 
    L      \---/   \-----/   \---/   \--/   \--/   \-....


  | START |      1 |       1 |     0 |    1 |    0 | 
Das Beste an diesem Protokoll ist, da� man kein genaues synchrones Taktsignal braucht. Das Protokoll wird immer noch funktionieren wenn der Takt etwas wackelt (Jitter).

Genau diese Eigenschaft macht es m�glich, I2C in einer ganz normalen Benutzerapplikation zu implementieren. Man braucht kein Kernelmodul oder spezielle Hardware (wie UART). Genial oder?

Die Idee

Wie schon gesagt k�nnen wir den PC internen I2C Bus nicht benutzen. Stattdessen benutzen wir einfach einige Leitungen der RS232 Schnittstelle. Unsere Kommunikationsschnittstelle ist also immer noch RS232 aber wir brauchen keine MAX232 Hardware, keine Kondensatoren, .... etc

Der schwierige Teil ist nun das I2C Protokoll neu in einer Linuxapplikation zu implementieren und zu testen. Ich habe daf�r 5 Wochen gebraucht bis es 100%ig funktionierte und du kannst es einfach kopieren :-). Ich hoffe du erkennst den Wert dieses Programms, wenn du es benutzt.
Als Anwendung f�r unser neues I2C Protokoll werden wir ein Thermometer bauen. Du kannst nat�rlich auch irgend etwas anderes messen oder einfach Lichter ein/aus-schalten. Es ist deine Entscheidung.

In einem zweiten Artikel werden wir ein LCD-Display hinzuf�gen. Mit anderen Worten es wird ein Thermometer bei dem man die Temperatur �ber den Linux PC oder direkt �ber eine Anzeige ablesen kann. Das Display kommt in einem zweiten Artikel um diesen hier nicht zu �berladen.
ntc
NTCs sind klein, billig und ausreichend genau

Der Temperatursensor

Es gibt schon fertig kalibrierte Temperatursensoren (einige von ihnen reden sogar I2C ;-) aber diese sind recht teuer. NTCs sind viel billiger und fast genauso gut selbst ohne Kalibrierung. Wenn man sie kalibriert kann man Genauigkeiten bis hinter dem Dezimalpunkt erreichen.

Ein Problem von NTCs ist ihre Nichtlinearit�t. Es ist aber eigentlich nur eine Frage der Halbleiterphysik hier die richtige Formel zu finden und diese nicht lineare Kurve zu korrigieren. Der Microcontroller ist ein kleiner Computer und mathematische Operationen sind �berhaupt kein Problem. NTCs sind temperaturabh�ngige Widerst�nde. Der Widerstandswert R eines NTCs bei einer gegebenen Temperatur ist:
ntc formula
T oder Tc ist die Temperatur, die wir suchen. Rn ist der Widerstandswert bei 25'C. Man kann NTCs mit 4.7K, 10K, ... kaufen. Rn ist dieser Wert.

Die Schaltung

circuit diagram
Schaltplan. Klick auf den Plan um eine genauere Ansicht zu erhalten.
Nun haben wir alles um das digitale Thermometer zu bauen. Wir nehmen zwei NTCs. Einen f�r innen und einen f�r die Au�entemperatur. Du kannst noch mehr Sensoren anschlie�en. (conn3, Pin PC2 ist z.B frei). In dem Schaltbild sieht man schon das LCD-Display. Ich wollte vermeiden, da� f�r den n�chsten Artikel wieder eine neue Schaltung gebaut werden mu�.

In der Schaltung findet sich eine ein LED. Das kostet nicht viel und ist sehr n�tzlich zum debuggen. Ich habe es oft benutzt als ich die I2C State-machine f�r die Kommunikation zwischen PC und Microcontroller entwickelt habe. Im normalen Betrieb lassen wir die LED einfach blinken um zu zeigen, da� Messwerte genommen werden.

Die Schaltung ist ansonsten ganz einfach. Der Analogdigitalwandler in dem Microcontroller wird benutzt um den Spannungsabfall an einem NTC zu messen. Dieser wird dann in einen Temperaturwert �bersetzt.

Der Atmega8 hat verschiedene M�glichkeiten die Referenzspannung des Analogdigitalwandlers zu w�hlen. Man kann entweder 5V (AVcc) oder einen interen 2.56V Referenz benutzen. F�r die Innentemperatur brauchen wir einen viel kleineren Bereich. +10'C bis +40'C sollten ausreichen. Wir nehmen daher hier die 2.56V Referenz und erhalten die doppelte Genauigkeit, da jetzt 1024 m�gliche digitale Werte auf 0-2.56V verteilt sind. Das ergibt eine Genauigkeit von 2.5mV (genauer als die meisten digitalen Voltmeter!).

Der CD Anschlu� an der RS232 Schnittstelle ist ein Eingang und wir schlie�en ihn daher an die SDA Leitung des I2C Bus an. DTR und RTS sind Ausg�nge. Wenn der PC Daten-bits auf den Bus gibt, dann �ndert er einfach DTR. Der I2C Master, hier der Linux PC, kontrolliert die SCL (Takt) Leitung. Mit anderen Worten SCL ist ein Ausgang an dem RS232 Anschlu�.

Der 78L05 wird benutzt um eine stabile Stromversorgung und eine Referenzspannung zu erhalten. Du kannst daher fast jede Art von Stromversorgung benutzen. DC oder AC zwischen 7.5V ond 12V. 9V ist eine gute Wahl.

Die Platine erstellen

get this kit from the tuxgraphics shop
tuxgraphics.org verkauft alle n�tigen Bauteile zusammen mir einer ge�tzten Platine.
Man kann nat�rlich auch die Lochrasterplatine aus dem vorangegangenen Artikel benutzen. Dazu mu� man die LED auf Pin 11 uml�ten und die neuen Bauteile hinzuf�gen.

Wenn du jedoch eine Schaltung bauen m�chtest, die auch gut aussieht, dann macht es mehr Sinn eine neue Platine zu �tzen, denn diese Schaltung ist einfach viel komplexer als die Testschaltung aus dem ersten Artikel. Nachdem ich Iznogood's Linuxfocus Artikel �ber gEDA gelesen hatte, beschloss ich dieses Mal gEDA anstelle von Eagel zu benutzen. gschem, das Schaltplanzeichenprogramm von gEDA ist sehr gut. Die Bibliothek der vorhandenen Symbole ist wesentlich kleiner als bei Eagle und so mu�te ich mein eigenes Symbol f�r den Atmega8 entwerfen, aber ging erstaunlich einfach. Viel problematischer ist pcb, das Programm zum Zeichnen der Platine. Wenn man vorher Eagle benutzt hat wird man zun�chst irritiert sein, da� sich die Gummibandverbindungen von den Bauteilen entfernen lassen. Um sicher zu sein, da� das richtige Gummiband an dem richtigen Bauteil h�ngt mu� man sie von Zeit zu Zeit neu erzeugen (Connects->Optimize rats-nest). Man sollte sich auch sehr sicher sein, da� der Schaltplan komplett ist, denn nachtr�glich �nderungen werden nur halb manuell �bertragen und es einfach dabei Fehler zu machen. top view, position of components

Ich benutzte den orangen Layer zum zeichnen. Irgendwie erzeugten die anderen verf�gbaren Farben einfach keine Ausgabe beim Drucken. Das Problem ist jedoch, das dieser orange Layer offenbar auf der Seite liegt, wo die Bauteile sind. Man mu� das Ergebnis also spiegeln. Letztendlich entschloss ich mich, die wesentlichen Teile des Layout mit pcb und den Rest mit gimp zu zeichnen.

Dank shop.tuxgraphics.org brauchst du nicht mit gef�hrlichen Chemikalien zu hantieren oder in verschiedenen Gesch�ften nach den richtigen Komponenten suchen. tuxgraphics verkauft alle Teile, die man f�r diesen Artikel braucht.

Der Aufbau

Beim Zusammenbau sollte man auf die Teile achten, bei denen die Polarit�t wichtig ist: Elektrolytkoindenstoren, Dioden, Z-Dioden, 78L05, LED und Microcontroller.

Bevor man den Microcontroller in den Sockel steckt sollte man die Stromversorgung mit einem Me�ger�t testen. Falls diese nicht funktioniert bekommt man nicht nur falsche Werte, sondern zerst�rt m�glicherweise auch den Microcontroller. Als n�chstes kann man die Schaltung an den RS232 Anschlu� des Linux PCs anschlie�en un mit dem i2c_rs232_pintest Programm die verschiedenen Signalkombinationen auf den SDA und SCL Anschl�ssen zu testen.
i2c_rs232_pintest -d 1 -c 1
i2c_rs232_pintest -d 0 -c 1
i2c_rs232_pintest -d 1 -c 0
Dieses Programm setzt die Spannungspegel auf den RTS (als SCL genutzt, Option -c) und DTR (als SDA genutzt, Optio -d) an der RS232 Schnittstelle. RS232 hat Spannungen von +/- 10V. Hinter den Z-Dioden sollte man jedoch nur -0.7 f�r eine logische Null und +4-5V f�r eine logische Eins messen.

Erst wenn diese Tests bestanden sind, sollte man den Microcontroller in den Sockel setzen.

I2C Kommunikation nutzen.

Lade das linuxI2Ctemp tar.gz File herunter (siehe Referenzen) und entpacke es. Die I2C Kommunikation ist in 2 Dateien implementiert:
i2c_avr.c -- die i2c Zustandsmaschine f�r den atmega8
i2c_m.c   -- das komplette i2c Protokoll f�r die Linuxseite.
Ich habe dem atmega8 die Slave Adresse "3" gegeben. Um den String "hello" and den atmega8 zu senden w�rde man folgende C Funktionen ausf�hren:
address_slave(3,0); // tell the slave that we will send something
i2c_tx_string("hello");
i2cstop(); // release the i2c bus

Auf der Microcontrollerseite w�rde man den String mit
der folgenden Funktion empfangen:
i2c_get_received_data(rec_buf);
Ganz einfach. Das lesen von Daten aus dem Microcontroller geht �hnlich.

Wie warm ist es?

Um den Code f�r den Microcontroller zu kompilieren und zu laden, sind die folgenden Befehle n�tig:
make
make load
Um die Programme i2c_rs232_pintest und i2ctemp_linux zu compilieren tippt man:
make i2c_rs232_pintest
make i2ctemp_linux
... oder man kann die vorkompilierten Versionen aus dem "bin" Verzeichnis benutzen.

Um Temperaturwerte zu lesen nimmt man einfach:
i2ctemp_linux
... und die Werte f�r Innen- und Au�entemperatur werden auf den Bildschirm gedruckt. Um diese Daten �ber einen Webserver zur Verf�gung zu stellen empfehle ich nicht das i2ctemp_linux Programm direkt vom Webserver aus laufen zu lassen, da es recht langsam ist. Besser ist es einen cron-Job zu schreiben, der regelm��ig eine html-Datei erzeugt. Ein Beispiel daf�r findet sich in der README Datei des linuxI2Ctemp Paketes.

Zusammenfassung

Das I2C Protokoll braucht sehr wenig extra Hardware und ist optimiert f�r kleine Datenmengen. Das ist genau das, was wir brauchen, wenn wir Me�daten von dem Microcontroller lesen. Eine elegante L�sung.

In diesem Artikel lag der Schwerpunkt auf der Hardware. Wenn dir dieser Artikel gefallen hat, dann schreibe ich noch einen zweiten Artikel, in dem die Software beschrieben wird. Speziell wie die Analogdigitalwandlung und die Implementation des I2C Protokolls funktionieren. In diesem zweiten Artikel kommen auch das LCD Display und Celsius nach Fahrenheit Konvertierung hinzu.

Referenzen