Vor ein paar Tagen habe ich mir für einen Arduino ein SDcard Modul von Catalex (v.1.0) gekauft. Praktischerweise bietet dieses Produkt gleich einen integrierten LevelShifter von 5V auf 3,3V, dadurch kann das Modul ganz einfach an einem 5V-Arduino (wie dem Uno, Mega, usw.) betrieben werden. So zumindest die Beschreibung.

Auf den ersten Blick ein echtes Schnäppchen, knappe 7€ kostet ein Pack von zweien auf Amazon.
Auch auf den zweiten Blick war ich von der doch recht anständigen Verarbeitung angetan. Alles was ich tun musste um eine SD-Karte am Arduino auszulesen war das Modul an den SPI-Pins des Arduino anzuschließen und einen entsprechenden Sketch auf den Arduino zu laden.

Alles wunderbar! Oder?

Ja, alles wunderbar, bis ich einen zweiten Slave (einen Beschleunigungssensor) an den selben SPI-Bus gehängt habe. Sollte ja eigentlich kein Problem sein, schließlich ist genau dafür die ChipSelect-Leitung (CS) da, jeder Busteilnehmer muss mit dieser zuerst "aktiviert" werden bevor er Daten an den SPI-Bus anlegt, solange er nicht aktiviert wurde dürfen seine Ausgänge weder HIGH noch LOW sein, sie müssen in einem dritten Zustand sein, dem sogenannten HiZ-Mode. HiZ steht für "high impedance" - also ein Zustand hoher Impedanz - das ist dann etwa so als wäre da einfach kein Busteilnehmer angeschlossen.

Eine normale SD-Karte respektiert das auch ganz wunderbar (bis auf ein zwei kleine zeitliche Verzögerungen durch eine synchrone Taktung), ebenso respektvoll ist mein Sensor. Nur eben nicht das SD-Karten-Board mit LevelShifter. Der kann seine Klappe nicht halten ;D

Sieht man sich - nach etlichen Stunden Fehlersuche - die Platine ein wenig genauer an, dann wird auch recht schnell klar warum das so ist.

Aufbau und Fehlerursache

ACHTUNG
Es sind mindestens drei unterschiedliche Versionen dieser Platine unterwegs. Bitte schaut euch euer Board vorher ganz genau an und messt nochmal nach ob es auch wirklich das selbe ist! Selbst optisch sehr ähnliche Platinen haben hier teilweise eine andere Pinbelegung an den Chips (LVC125A).
Meine Version ist die v.1.0 von Catalex.

Auf dem Board sitzen neben ein paar Widerständen und Kondensatoren zwei Chips. Der eine dient der Spannungsversorgung (AMS 1117 3.3), der andere ist ein LVC125A. Sieht man im Datenblatt nach, so stellt sich heraus dass letzterer Chip (in Kombination mit der 3,3V Spannungsversorgung) folgende Aufgaben übernimmt, bzw. übernehmen kann.

  1. Er übersetzt die 5V-Logik des Arduino auf 3,3V in Richtung der SD-Karte
  2. Er besitzt 4 Kanäle. Jeder dieser besitzt je einen Ein- und Ausgang sowie eine Steuerleitung. Der Eingang kann also zum Ausgang entweder durchgeschaltet (HIGH oder LOW) oder deaktiviert werden (HiZ) - je nachdem ob die Steuerleitung (OutputEnable OE LOW ist - dann ist der Ausgang aktiviert, oder HIGH - dann ist der Ausgang deaktiviert und verhält sich als wäre er nicht angeschlossen - HiZ).

Der MISO Ausgang der SD-Karte liegt an Pin 12 des Chips an (Input Kanal 4 des Chips). Der zugehörige Ausgang des 4. Kanals liegt an Pin 11 und geht über einen kleinen Widerstand direkt zum MISO-Anschluss der Platine. Es fehlt noch die Steuerleitung des 4. Kanals, dieser liegt an Pin 13, doch wo führt dieser hin?

Wie sich herausstellt ist dieser auf GND gelegt und der Chip schaltet Kanal 4 (MISO) daher einfach immer durch. Wenn also die SD-Karte ihren Ausgang (MISO) auf HIGH zieht, so ist auch der entsprechende Anschlusspin der Platine auf HIGH, analoges gilt für LOW. Doch was passiert eigentlich wenn die SD-Karte die MISO-Leitung auf HiZ setzt, so wie es eben jeder Busteilnehmer machen sollte wenn er nicht durch den ChipSelect aktiviert wird?

Im Datenblatt steht folgendes:

When using multiple bit logic devices, inputs should not float. In many cases, functions or parts of functions of digital logic devices are unused. Some examples are when only two inputs of a triple-input AND gate are used, or when only 3 of the 4-buffer gates are used. Such input pins should not be left unconnected because the undefined voltages at the outside connections result in undefined operational states. Specified in Figure 7 are rules that must be observed under all circumstances. All unused inputs of digital logic devices must be connected to a high or low bias to prevent them from floating. The logic level that should be applied to any particular unused input depends on the function of the device. Generally they will be tied to GND or VCC, whichever makes more sense or is more convenient.

In dem Moment wo die SD-Karte in den HiZ-Modus geht verhält sich der Input des 4. Kanals so, als wäre er "unused". Geringste Kapazitäten können jetzt den Zustand des Pins von HIGH auf LOW bringen, der Pin verhält sich wie eine Antenne. Auch in der Wahrheitstabelle im Datenblatt steht nicht über diesen Zustand.

Ein HiZ am Eingang wird also nicht einfach so zu einem HiZ am Ausgang übersetzt. Um am Ausgang HiZ zu erhalten müsste man eben die Steuerleitung (OutputEnable) erstmal auf HIGH setzen.

Lösung

Die Lösung des Problems ist denkbar einfach. Statt Pin 13 (Output Enable - OE) auf GND zu legen schließen wir diesen an den ChipSelect an. Damit wird der 4. Kanal (MISO) automatisch in den HiZ-Modus gesetzt wenn der Master den Slave deaktiviert. ChipSelect ist bei dem Modell hier auf Pin 9 gelegt.

Nochmal: Wir beenden also mit dem Arduino die Kommunikation zur SD-Karte, das passiert durch ein HIGH am CS-Signal. Eben dieses HIGH liegt nun auch an der Steuerleitung (OE) des 4. Kanals an. Wie man aus obiger Wahrheitstabelle entnehmen kann wird dadurch nun auch der Ausgang des 4. Kanals (also MISO) auf HiZ gesetzt.

Wir brauchen also eine kleine Brücke von Pin 13 (OE4) zu Pin 9 (CS, bzw. Input des 3. Kanals, da CS ebenfalls übersetzt wird bevor es die SD-Karte erreicht). Außerdem müssen wir natürlich die Verbindung von Pin 13 zu GND trennen.

Ansatz 1: Fliegende Brücke

Die einfachste Variante ist wohl den Pin 13 von seinem Pad zu lösen und mit einem kleinen Draht mit Pin 9 zu verbinden.

Ansatz 2: Etwas schöner

Ein schönerer Ansatz ist es den Chip (LVC125A) komplett zu entlöten, die Verbindung zu GND mit einem scharfen Gegenstand (z.B. Skalpell) zu durchtrennen, und eine kleine Brücke zu Pin 9 (CS) unter dem Chip zu setzen. Anschließend wird der Chip wieder eingelötet.

Weitere Probleme

Leider ist das nicht der einzige Konstuktionsfehler dieses Boards.

1) Es werden zwar die 5V vom Mikrocontroller zu 3,3V für die SD-Karte übersetzt, aber nicht andersrum! In der Regel kann der Arduino einen HIGH-Zustand trotzdem problemlos erkennen, aber darauf darf man sich nicht verlassen.

2) Das Board kann nur mit 5V Spannungversorgung betrieben werden, nicht aber mit den für SD-Karten nativen 3,3V.

Der einzig richtige Weg wäre das Board mit 5V zu versorgen aber auf 3,3V zu kommunizieren. Man bräuchte also bei den meisten Arduinos nochmal einen LevelShifter.... Macht das Sinn? Eher nicht.

Meine Empfehlung

Wenn ihr einen zuverlässigen SD-Kartenslot mit integrierten Level-Shifter in beide Richtungen möchtet, dann empfehle ich euch den von SparkFun. Den gibt es bereits für knappe 5€ bei eBay: http://www.ebay.de/itm/like/282153230355

Besucher-Aktionen

Besucher-Aktionen

Ich freue mich über einen Kommentar! Das geht auch als Gast: mit Disqus einloggen » als Gast.