Wenn etwas schiefgeht, ist es nicht immer die Schuld des Programmierers. Es könnte auch an der Hardware liegen (bzw. dem Elektroingenieur, der diese entworfen hat). Wenn man ein System als Bastler entwickelt, ist man aber meist beides: Der Elektroingenieur und der Programmierer (sodass man sich immer selbst die Schuld geben darf). In diesem Blogbeitrag werfen wir einen Blick auf einige der Dinge, die auf der Hardware-Seite schiefgehen können, speziell bei Projekten mit AVR-MCUs.

Häufige Probleme

Es ist eigentlich selbstverständlich: Es lohnt sich die Verkabelung doppelt und dreifach zu überprüfen, bevor man an anderer Stelle anfängt zu suchen! Gefühlte 90% der Probleme resultieren aus fehlenden oder falschen Verbindungen. Und es kann Stunden kosten, diesen Fehlern auf die Spur zu kommen.

Daneben gibt es speziell mit AVR-MCUs oft Probleme, falls man einige kritische Dinge in der Schaltung nicht berücksichtigt. Bei Problemen (und auch sonst) lohnt es sich immer, die folgenden Dinge zu überprüfen:

  1. Gibt es einen 0,1 μF Abblockkondensator zwischen dem Vcc-Pin und dem GND-Pin der MCU (mit sehr kurzen Verbindungen zu den Pins) und einen weiteren globalen Abblockkondensator von 10 μF? Ohne diese Kondensatoren kann es auf den Stromversorgungsleitungen der MCU zu Spannungsspitzen und -einbrüchen kommen (siehe Bild oben), was oft zu erratischem Verhalten der MCU führt.
  2. Sind die AVcc- und AGND-Pins (die analogen Versorgungsspannungspins) mit Vcc bzw. GND verbunden? Sie sollten es sein, auch wenn der ADC (der Analog-Digital-Wandler) nicht verwendet wird, da diese Pins auch einige der digitalen Pins mit Strom versorgt. Für die Performanz des ADC ist es wichtig, einen separaten Abblockkondensator für AVcc und AGND zu haben.
  3. Ist der AREF-Pin angeschlossen? Wenn er offen ist, sollte er über einen 100 nF-Kondensator mit GND verbunden werden. Andernfalls können ADC-Messwerte ungenau werden.

Ich habe alle drei Fehler irgendwann mal gemacht, und es hat jeweils eine ganze Weile gedauert, bis ich das Problem lokalisiert hatte. Es gibt weitere Empfehlungen, wie z. B. keinen MCU-Pin offenzulassen (d. h. nicht angeschlossen und als Eingang konfiguriert). Da es möglich ist, offene Pins als Ausgänge zu konfigurieren, ohne dass dies Strom frisst, sollte man es eigentlich immer machen.

Prellen von Schalterkontakten

Eines der Missverständnisse, die Leute von der Softwareseite haben, ist, dass ein Schalter oder eine Taste von einem offenen Zustand in einen geschlossenen Zustand übergeht (oder umgekehrt), wenn man ihn betätigt. Leider stimmt das nur bis zu einem gewissen Grad, wie das folgende Bild zeigt.

Schalterprellen: Die obere Kurve ist die analoge Messung, die untere die digitale Interpretation

Wenn ein Schalter geschlossen ist, dauert es eine Weile, bis sich der Schalter im anderen Zustand stabilisiert, und dazwischen kann der Schalter seinen Zustand ein paar Mal ändern, er prellt. Das ist besonders ärgerlich, wenn man zählen will, wie oft ein Taster betätigt wird. Wie lange muss man warten, um einen anderen stabilen Zustand zu erreichen? Im obigen Beispiel sind es weniger als 10 μs. Jack Ganssle führte eine empirische Studie durch und kam zu dem Schluss, dass die meisten Schalter weniger als 10 ms prellen, aber es gibt Ausreißer. Man ist also vermutlich auf der sicheren Seite, wenn man annimmt, dass ein Schalter maximal 20 ms prellt.

Wie geht man jetzt mit diesem Problem um? Es gibt den harten Weg und es gibt den weichen Weg. Man kann Hardware nutzen, um dieses Problem zu lösen. Dabei ist der billigste Weg, ein RC-Glied (einen Tiefpassfilter) wie im nächsten Bild zu verwenden.

Tiefpassfilter

Wenn man 47 kΩ für R1 und R2 und 220 nF für C1 wählt, erhält man ein Verhalten wie im folgenden Bild. Mit anderen Worten, 12 ms nach dem Drücken der Taste wird die Taste als geschlossen erkannt. Diese Zeitspanne ist nicht wahrnehmbar, wenn der Knopf von einem Menschen bedient wird. Wenn es sich jedoch um einen Endschalter in einer Maschine handelt, kann diese Verzögerung zu groß sein. Ein weiteres Problem kann sein, dass es sich jetzt nicht mehr um ein sauberes digitales Signal handelt. Glücklicherweise haben die AVR-MCUs allerdings Schmitt-Trigger mit einer Hysterese von 50 mV an ihren Eingängen, sodass die sehr langsam fallende Spannung kein Problem darstellt.

Hardware-Entprellung mit der oben gezeigten Schaltung

Die meisten Leute (insbesondere Software-Leute) bevorzugen eine Softwarelösung, weil man damit ein paar Cent und etwas Platz auf der Leiterplatte spart. Und man hat ja sowieso diese leistungsstarke MCU, die kaum etwas zu tun hat. Wenn es nur um einen Schalter geht, reicht es aus, den Status des Schalters periodisch zu testen. Ändert sich der Status, startet man die gewünschte Aktion und ignoriert die folgenden 20 ms den Schalter. Dies funktioniert vermutlich gut, solange es keine EMI (elektromagnetische Interferenz) gibt. Wenn man sich vor EMI schützen will oder mehr als eine Taste überwacht werden muss, werden Lösungen schnell komplexer. Eine Lösung könnte darin bestehen, den Zustand der Tasteneingänge mithilfe eines Timer-Interrupts periodisch abzufragen. Weitere Lösungen zum Entprellen von Schaltern und Tastern finden sich überall im Web und vornehmlich im Blogbeitrag von Jack Ganssle.

Zusammenfassend lässt sich sagen, dass Schalterprellen ein Phänomen ist, um das man bei eingebetteten System nicht herumkommt. Man kann das Problem mithilfe von Hardware oder durch Software lösen, aber man kann es definitiv nicht ignorieren.

Pull-up-Widerstände und I2C-Bausteine

Wenn man etwas Sinnvolles mit einer MCU anstellen will, muss man meist einen Sensor an die MCU anschließen. Interessanterweise sprechen die meisten Sensoren, die man heutzutage kaufen kann, I2C (auch TWI genannt), ein von Philips entwickeltes 2-Draht-Busprotokoll.

Dieses Protokoll besteht aus der Hardwareschicht (auf der die elektrischen Eigenschaften festgelegt sind und angegeben wird, wie Bytes übertragen werden) und der Softwareschicht (auf der spezifiziert ist, welche verschiedenen Zustände es gibt und wie Informationen zwischen den Parteien ausgetauscht werden). Für das Arduino-Framework ist dies alles in der Wire-Bibliothek gekapselt. Darüber hinaus gibt es für eine Vielzahl von Sensoren Bibliotheken, die die Wire-Bibliothek verwenden und das jeweilige Sensorprotokollen implementieren. Die gute Nachricht ist also, dass man diese Sensoren verwenden kann, ohne etwas über I2C oder das jeweilige Sensorprotokoll zu wissen. Das bedeutet aber auch, dass etwas schiefgehen kann und man nicht weiß warum.

Auf der Hardwareseite gibt es zwei häufige Probleme. Erstens hat man möglicherweise die SCL – und SDA-Leitungen verwechselt. Wenn I2C nicht funktioniert, schaue ich als erstes, ob das Vertauschen der Verbindungen hilft. Das zweithäufigste Problem besteht darin, zu schwache Pull-up-Widerstände einzusetzen (mit einem zu hohen Wert) oder die Pull-up-Widerstände ganz wegzulassen.

Die beiden Leitungen, SDA und SCL, werden von zwei Pull-up-Widerständen auf Vcc hochgezogen. Diese Widerstände befinden sich entweder auf der Leiterplatte oder auf der Sensor-Breakout-Platine. Ergänzend setzt die Wire-Bibliothek die internen Pull-up-Widerstände der MCU (ca. 20-50 kΩ für AVR-MCUs) ein, was oft auch alleine ausreicht. Der empfohlene Wert für einen I2C-Bus-Pull-up-Widerstand beträgt 4,7 kΩ. Widerstände kleiner als das sind auch in Ordnung. Da man aber gerne ein paar Cent und Platz auf der Leiterplatte spart, verlässt man sich gerne alleine auf die internen Pull-up-Widerstände der MCU. Dies geht auch meistens gut, kann aber zu Problemen führen. Um das zu demonstrieren, schauen wir uns zwei extreme Beispiele im Bild unten an.

I2C-Bussignale bei 100 kHz mit 4,7 kΩ (links) und 220 kΩ Pull-ups (rechts)

Links sieht man die Signale auf dem I2C-Bus mit 100 kHz und Pull-ups von 4,7 kΩ. Die oberen beiden Reihen zeigen die analogen Spannungspegel, die unteren beiden Reihen die digitale Interpretation. Auf der rechten Seite sieht man dasselbe mit Pull-ups von 220 kΩ. Man sieht deutlich, dass die elektrischen Signale so stark deformiert sind, dass sie nicht mehr interpretierbar sind. Wenn niedrigere Widerstände nicht möglich sind, kann man die Kommunikationsgeschwindigkeit reduzieren (hier haben wir also ein weiteres Beispiel eines zeitabhängigen Fehlers, über die wir im ersten Blog gesprochen haben). Im folgenden Bild sieht man die I2C-Kommunikation mit 220 kΩ Pull-ups, wenn der Bus mit 20 kHz getaktet ist.

I2C-Bussignale bei 20 kHz mit 220 kΩ Pull-ups

Übersprechen

Nachdem man ein System auf einer Steckplatine entwickelt hat und alles funktioniert, kann man eine Leiterplatte entwerfen und das Design an eine Fab schicken. Jetzt muss man lediglich noch etwas warten … und wenn die Leiterplatte endlich ankommt, kann man das System aufbauen. Da es auf der Steckplatine funktioniert hat, wird es auch auf der Leiterplatte funktionieren, oder? Falsch! Es kann kleine, aber feine Unterschiede geben, die zu Problemen führen. Eines ist die Möglichkeit des sogenannten Übersprechens: Wenn zwei Drähte nebeneinander unterschiedliche Signale tragen, erzeugen die Ströme in ihnen Magnetfelder, die ein kleineres Signal im benachbarten Draht induzieren (Wikipedia). Dies Problem wird ausführlich in diesem Artikel diskutiert.

Ich hatte kürzlich den Verdacht, dass ich bei einer von mir entworfenen Platinen so ein Übersprechen-Problem hätte. Es stellte sich dann aber als ein parasitäres Stromversorgungsproblem aufgrund eines Programmierfehlers heraus.

Elektromagnetische Störungen

Wie bereits oben erwähnt, können EMI oder elektromagnetische Störungen das Leben schwierig machen. EMI kann zu falschen Messwerten der Systemeingänge (oder Datenpfade) führen. Das oben erwähnte Übersprechen ist z.B. eine Form von EMI. Ich bin allerdings bisher noch nie auf ein EMI-Problem gestoßen. Wenn jedoch ein System in einer Umgebung betrieben werden soll, in der es viel EMI gibt, sollten man Vorsichtsmaßnahmen treffen. Das Schlagwort hier ist immunitätsbewusste Programmierung.

Übrigens kann die eigene MCU auch eine Quelle für EMI sein. Ein markantes Beispiel dafür ist der UKW-Sender, der aus nur einer einzigen ATtiny45-MCU aufgebaut ist. Wie vom Autor bemerkt, haben die emittierten elektromagnetischen Wellen wahrscheinlich eine sehr geringe Energie und werden daher nicht weit reichen. Wenn man PB4 als Ausgang für den MCU-Takt auswählt und ein Kabel an diesen Pin anschließen, kann sich dies jedoch 😎 ändern.

Views: 8