Aha, das uralte Problem. Man hat ein Oszilloskop, aber fünf Ingenieure wollen es benutzen; eine Telefonleitung, aber drei Leute wollen telefonieren; 20 LEDs, aber nur noch acht GPIOs an Ihrem Mikrocontroller frei. Was also tut man? Man teilt auf! Oder, in der Fachsprache, man multiplexiert. Werfen wir einen Blick auf das Multiplexen.


Eine der größten Herausforderungen bei der Auswahl eines Mikrocontrollers (MCU) besteht darin, einen Controller mit genügend Pins für die Aufgabe zu finden, das im Rahmen des Budgets liegt. In der Regel ist ein 64-Pin-Baustein teurer als ein 32-Pin-Baustein. Etwa 10 bis 15 % dieser Pins sind Stromversorgungspins. Der Rest ist eine Mischung aus digitalen und analogen Pins sowie Pins für spezielle Anwendungsfälle.

So gibt es beispielsweise einen Reset-Pin, Pins für den Quarzoszillator und vielleicht einen speziellen Pin zur Unterstützung eines Bootloaders. Und manchmal sind Pins speziell für die Verwendung mit bestimmten Peripheriegeräten wie USB oder I2C vorgesehen, weil die Schaltung um sie herum ein wenig anders ist.

Nehmen wir also an, wir haben festgestellt, dass unsere Anwendung 20 rein digitale Pins benötigt, vielleicht für Eingangsschalter und die Steuerung von LEDs für eine Mensch-Maschine-Schnittstelle. Auf einer 32-poligen MCU subtrahieren wir die Stromversorgungspins (z. B. 6), die reinen Analogpins (z. B. 8), USB und I2C (z. B. 4), und es bleiben nur 14 Pins übrig. Können man also, wenn man es von der kommerziellen Seite betrachtet, die Wahl einer teureren MCU mit einer höheren an Pins rechtfertigen, bei der nicht alle Pins verwendet werden? Oder kann man mit etwas technischer Raffinesse aus 14 Pins 20 Signale machen?

Abonnieren
Tag-Benachrichtigung zu Mikrocontroller jetzt abonnieren!

Das Multiplexing begann mit dem Telegraphen

Die Idee, mehr aus einer einzigen elektrischen Verbindung herauszuholen, begann mit dem Telegrafen. Nachdem Morse und seine Freunde herausgefunden hatten wie man Datenbits über weite Entfernungen per Draht verschicken konnte, war klar, dass das ständige Hinzufügen von Leitungen zur Erhöhung der Kapazität teuer sein würde. Und nicht nur das, es bedeutete auch mehr Arbeit für das Team, das das Netz unterhielt.


Natürlich begannen einige kluge Köpfe der damaligen Zeit darüber nachzudenken, ob diese einzelnen Leitungen von mehreren Telegrafisten gemeinsam genutzt werden könnten, so dass zwei oder mehr Nachrichten über jeden der vorhandenen Drähte gesendet werden könnten. Einer von ihnen war Émile Baudot.
 
Emile Baudot public domain image - Multiplexing intro
Émile Baudot erfand ein Verfahren zum
Multiplexen mehrerer Telegrafen-Betreiber
über eine einzige Leitung.
(Public Domain)
Baudot begann in den späten 1860er Jahren als Operator für die französische Post- und Telegrafenverwaltung zu arbeiten. Dabei kam er auch mit dem Hughes-Drucktelegrafen in Berührung. Im Gegensatz zu den traditionellen Telegrafie-Systemen, die die Morsezeichen verwendeten, welche wieder in lesbaren Text übersetzt werden mussten, verfügte der Drucktelegraf über eine alphanumerische Tastatur, die Klaviertasten ähnelte. Am anderen Ende wurden die gesendeten Buchstaben auf ein Papierband übertragen.

Das System musste auf Empfangs- und Sendeseite synchronisiert werden. Auf der Empfangsseite drehte sich ein Typenrad, ähnlich einem Typenraddruckkopf, kontinuierlich. Auf der Senderseite wurden alle Buchstabentasten in der gleichen Reihenfolge abgetastet. Wurde eine Taste gedrückt, so wurde der entsprechende Buchstabe des Typenrads aktiviert und auf einen Papierstreifen gedruckt. Dadurch wurde die Übertragung von Nachrichten auf etwa 40 Wörter pro Minute begrenzt (ein Wort bestand im Durchschnitt aus fünf Buchstaben plus Leerzeichen).
 
Hughes telegraph public domain - Multiplexing started
Der Hughes-Drucktelegraf ersparte das Erlernen des Morsecodes. (Public Domain, Quelle: Olaf)
Baudot fragte sich, ob diese Synchronisierungsmethode nicht auch für die gemeinsame Nutzung einer einzigen Leitung durch mehrere Benutzer verwendet werden könnte. Die Digitalisierung der Informationen, der zu sendenden Buchstaben, schien ein Teil der Lösung zu sein. Aber der von Morse begründete Code bedeutete, dass die Zeit zum Senden eines Buchstabens unterschiedlich war, von einem einzigen kurzen Punkt bis hin zu fünf langen Strichen.

Diese Herausforderung wurde durch ein neues Kodierungsschema gelöst, das für jeden Buchstaben die gleiche Anzahl von symbolen gleicher Länge vorsah. Sein System besteht aus fünf Bits und verwendete positive und negative Impulse, um jeden Buchstaben zu übertragen. Durch die Synchronisierung von Empfangs- mit Sendeseite konnten bis zu sechs Benutzer gleichzeitig Nachrichten über eine einzige Leitung senden. Nun, so sah es zumindest aus. In Wirklichkeit handelte es sich um ein Zeitmultiplexsystem, das jedem Telegrafisten ein Sechstel eines Zeitschlitzes für die Übertragung des nächsten Briefes zur Verfügung stellte.
 
Clavier Baudot public domain
Beim Baudot-Drucktelegrafen musste der Benutzer 5-Bit-Codes eingeben, die den
zu übertragenden Buchstaben oder das gewünschte Symbol darstellten.
Sechs dieser Einheiten teilten sich eine einzige Telegrafenleitung. (Public Domain)

Multiplexing für LEDs

Siebensegment-LEDs und Matrixtastaturen sind seit Jahrzehnten ein fester Bestandteil elektronischer Systeme. Schon bevor MCUs alltäglich wurden, suchten Elektronikingenieure nach Möglichkeiten, die Anzahl der für die Implementierung dieser Komponenten erforderlichen Signale zu verringern.

Nehmen wir als erstes Beispiel LED-Anzeigen mit sieben Segmenten. Wenn man den Dezimalpunkt mitzählt, enthalten diese Bauteile acht LEDs. Will man eine Stromversorgung bauen, benötigt man wahrscheinlich insgesamt vier Ziffern (XX.YY), um die Spannung oder den Strom anzuzeigen. Das bedeutet, dass wir 8 x 4 = 32 Pins benötigen - das ist eine ganze Menge.
 
Bench PSU Seven Segment Displays
Vier Siebensegment-Anzeigen an einem Tischnetzteil.
Allen Segmentanzeigen gemeinsam sind die acht Anschlüsse und die gemeinsame Kathode. Wir wissen zudem, dass LEDs den visuellen Nachleuchteffekt des menschlichen Auges ausnutzen können. Das heißt, wenn wir schnell genug zwischen den Anzeigen umschalten (Zeitmultiplex), wird das Auge nicht bemerken, dass die LEDs nur für einen Bruchteil einer Sekunde eingeschaltet waren. Etwas mehr als 24 Mal pro Sekunde wäre angemessen.

Wenn wir also die gleichen LED-Segmente jeder Ziffer an den gleichen MCU-Pin anschließen, können wir 24 Pins einsparen. Um zu bestimmen, welche unserer vier Siebensegment-Anzeigen angesteuert wird, benötigen wir vier Pins, um eine der gemeinsamen Kathoden mit Masse zu verbinden. Um 32 LEDs anzusteuern benötigen wir also 8 + 4 = 12 Pins - 20 weniger als ein Pin pro LED.
 
7 Segment Multiplexing with Arduino UNO
Zwei Siebensegment-Anzeigen teilen sich acht Signalleitungen (Segment plus Dezimalpunkt).
Die Pins D11 und D12 des UNO schalten die eine oder andere Anzeige ein
und verbinden die gemeinsame Kathode mit Masse.
Wenn man die Helligkeit des Displays steuern möchte, kann man eine Routine in einem Timer-Interrupt erstellen, die die Einschaltzeit der gemeinsamen Kathodenpins steuert.

Abonnieren
Tag-Benachrichtigung zu Arduino jetzt abonnieren!

Multiplexing für Matrix-Tastaturen

Der gleiche Ansatz kann für eine Matrix von Drucktastern als Eingabeeinheit für ein Embedded System verwendet werden. Wenn man nur zwei oder drei Schalter hat, kann man diese wahrscheinlich mit einem Pull-Up/Down-Widerstand kombinieren und ihren Status mit der gleichen Anzahl von GPIOs erkennen, die als Eingänge konfigurierten sind.


Ab etwa sechs Schaltern kann es jedoch sinnvoll sein, eine Matrix zum Auslesen der Schalter zu implementieren. Anstatt die Schalter über Pull-up-Widerstände mit der Stromversorgung zu verbinden werden die Schalter an einen GPIO-Ausgang angeschlossen. Wenn der Ausgang High ist und der Schalter gedrückt wird, erkennt der Eingang dies als 1. Man muss die Widerstände allerdings beibehalten um zu vermeiden, dass Vcc über die GPIOs gegen Masse kurzgeschlossen wird.

Um eine Matrix zu erstellen, müssen die Schalterketten durch einige GPIO-Pins zyklisch als Ausgänge geschaltet werden.
Wir beginnen mit sechs Schaltern und gruppieren sie in zwei Dreiergruppen. Bei jeder Dreiergruppe ist eine Seite mit einem GPIO-Ausgang verbunden. Dann gruppieren wir sie in Zweiergruppen, wobei die andere Seite jedes Schalters mit einem GPIO-Eingang verbunden ist.
 
Push Button Multiplexing
Drucktasten-Multiplexing: sechs Tasten mit fünf GPIOs.
Button Multiplexing Schematic
Schaltplan für das Multiplex-Tastenfeld mit sechs Tasten.
In der Software schalten wir den GPIO-Ausgang einer Zeile von Drucktasten ein, scannen die drei Eingänge und schalten den Ausgang dann wieder aus. Der Vorgang wird mit der zweiten Zeile wiederholt. Für sechs Schalter haben wir also zwei Ausgänge und drei Eingänge verwendet - das sind fünf statt sechs Pins.
 
// PSEUDO CODE

// INITIALIZE PINS
SET D0 as OUTPUT
SET D1 as OUTPUT
SET D0 LOW
SET D1 LOW

// SCAN BUTTONS
SET D0 HIGH
READ D2, D3, D4 and STORE STATE as BUTTON 1, BUTTON 2, BUTTON 3
SET D0 LOW

SET D1 HIGH
READ D2, D3, D4 and STORE STATE as BUTTON 4, BUTTON 5, BUTTON 6
SET D1 LOW
 
Es ist wichtig, die Abfrage der Spalten schnell genug zu durchlaufen, damit die Eingabemethode schnell genug reagiert. Der Mensch wertet eine Reaktionszeit von unter 200 ms als "sofort", daher sollte man die gesamte Drucktastenmatrix mindestens fünfmal pro Sekunde abfragen. Diese Methode eignet sich auch zur Erkennung von Tastenkombinationen, mit deren Hilfe mehr Benutzerschnittstellenfunktionen als Tasten zur Verfügung stehen können.

Charlieplexing mit LEDs

Multiplexing reduziert bereits die Anzahl der zur Steuerung von LEDs benötigten GPIOs, Charlieplexing benötigt noch weniger Pins! Dabei wird die Tatsache genutzt, dass MCU-GPIO Pins drei Zustände haben: High und Low als Ausgang und hohe Impedanz als Eingang. Im einfachsten Fall können wir zwei LEDs mit entgegengesetzter Polarität zwischen zwei MCU-Pins anschließen. Wenn die Pins als Ausgänge konfiguriert sind leuchtet eine der LEDs auf, wenn ein Pin auf High und der andere auf Low ist. Bei umgekehrten Ausgangspegeln leuchtet die andere LED. Um sie auszuschalten, setzt man einfach beide GPIOs als Eingänge.


 
Simple Charlieplexing Breadboard
Prinzip des Charlieplexing mit zwei GPIOs und zwei LEDs.
Sobald eine LED eingeschaltet wird, fließt der Strom durch zwei strombegrenzende Widerstände. Wenn man also einen 200-Ω-Widerstand für die LEDs berechnet hat, benötigt man zwei 100 Ω Widerstände zur Strombegrenzung.
Simple Charlieplexing Schematic
Schaltplan für das Charlieplexing von zwei LEDs.
// PSEUDO CODE - CHARLIEPLEXING

// INITIALIZE PINS
SET D0 LOW
SET D1 LOW
SET D0 as INPUT
SET D1 as INPUT

// TURN ON LED 2
SET D0 as OUTPUT
SET D1 as OUTPUT
SET D1 HIGH
SET D0 LOW

// TURN ON LED 1
SET D1 LOW
SET D0 HIGH

// TURN LEDS OFF
SET D0 as INPUT
SET D1 as INPUT
SET D0 LOW
SET D1 LOW

So weit, so unspektakulär. Wir haben zwei GPIOs verwendet, um zwei LEDs zu steuern. Der Spaß beginnt erst, wenn wir einen zusätzlichen GPIO hinzufügen ... und vier weitere LEDs. Wir fügen zwei weitere LEDs mit entgegengesetzter Polarität zwischen GPIO eins und drei und zwei zwischen GPIO zwei und drei hinzu. Um eine einzelne LED zu steuern, muss ein GPIO als High-Ausgang, einer als Low-Ausgang und der dritte als Eingang konfiguriert werden.
 
Charlieplexing 6 LEDs Breadboard
Steuerung von sechs LEDs mit drei GPIO-Pins durch Charlieplexing.
// PSEUDO CODE FOR CHARLIEPLEXING SIX LEDS

// INITIALIZE GPIOs
SET D0 LOW
SET D1 LOW
SET D2 LOW
SET D0 as INPUT
SET D1 as INPUT
SET D2 as INPUT

// TURN ON LED1
SET D0 HIGH
SET D1 LOW
SET D0 as OUTPUT
SET D1 as OUTPUT

// TURN ON LED4
SET D0 LOW
SET D1 LOW
SET D0 as INPUT
SET D2 HIGH
SET D1 LOW
SET D2 as OUTPUT
 
Tabelle zur Steuerung von sechs Charlieplex-LEDs
Output Pins LED1 LED2 LED3 LED4 LED5 LED6
D0 OUT HIGH OUT LOW INPUT INPUT OUT HIGH OUT LOW
D1 OUT LOW OUT HIGH OUT HIGH OUT LOW INPUT INPUT
D2 INPUT INPUT OUT LOW OUT HIGH OUT LOW OUT HIGH

Da zwischen den Pins 1 und 3 zwei LEDs in Reihe geschaltet sind (Arduino D0 und D2 im untenstehenden Schaltplan), kann man sich zu Recht fragen, warum diese LEDs nicht beide aufleuchten, wenn man versucht, eine einzelne LED zwischen diesen Pins einzuschalten. Dies ist ein Risiko, hängt aber von der niedrigen MCU-Versorgungsspannung und der Durchlassspannung der LEDs ab. Bei einer Versorgungsspannung von 3,3 V beträgt die Spannung an den beiden LEDs 3,3 ÷ 2 = 1,65 V, damit nicht genug, um eine LED zum Leuchten zu bringen. Der Betrieb mit 5,0 V ist daher problematisch.
 
Charlieplexing 6 LEDs Schematic
Schaltplan für das Charlieplexing von sechs LEDs mit einem Arduino.
Dies führt zu einer weiteren Überlegung. Die LEDs müssen alle die gleiche Eigenschaft haben. LEDs verschiedener Farben haben oft unterschiedliche Spannungsabfälle, so dass bei gemischten LEDs die Gefahr besteht, dass eine zusätzliche LED unter bestimmten Ausgangsbedingungen unerwünscht eingeschaltet wird.

Wie beim Multiplexing kann auch beim Charlieplexing die Einschaltzeit des High Ausgangspins gesteuert werden, um die Helligkeit der LED zu verändern. Dies erfordert einen Timer und dessen Interrupt sowie einige Schaltanweisungen. Da Charlieplexing so viele Möglichkeiten eröffnet, erläutert eine kleine Formel, wie viele LEDs von wie vielen Pins gesteuert werden können.


 
LEDs = GPIOs × (GPIOs - 1)
 
Für unsere vier Siebensegment-Anzeigen (32 LEDs) von vorhin bräuchten wir also sieben GPIOs und könnten immer noch bis zu 10 weitere LEDs für andere Zwecke anschließen.

Warum also Charlieplexing?

Der Begriff Charlieplexing stammt von einem Ingenieur bei Analog Devices, Charlie Allen, der sich für die Anwendung dieser Technik innerhalb des Unternehmens einsetzte. Infolgedessen wurde sein Name zu einer Art Kurzform für die Bezeichnung dieses Steuerungsansatzes. Analog Devices stellt tatsächlich einige spezielle Siebensegmenten LED-Treiber her, wie z. B. den MAX6950.

Dieser 16-Pin-Chip kann bis zu fünf Siebensegment-Anzeigen oder 40 diskrete LEDs ansteuern. Nur acht der Pins werden für die Steuerung der LEDs verwendet. Die verwendete Steuermethode ist etwas anders als die oben beschriebene, wobei eine Stromquelle die LEDs versorgt und MOSFETs den Pfad zur Masse für die gemeinsame Kathode bereitstellen. Die Stromquelle ist von 2,5 mA bis 37,5 mA einstellbar und ermöglicht die Steuerung der LED Helligkeit. Eine MCU steuert den LED-Treiber über SPI. Bei Bedarf können mehrere Treiber hintereinander geschaltet werden, um weitere segmentierte Anzeigen zu steuern.
 
MAX6950 Block Diagram
Der MAX6950/1 verwendet einen Charlieplexing-Ansatz zur Steuerung von bis zu 40
LEDs mit nur acht Pins. (Quelle: Analog Devices)

Weniger ist mehr

Der Spaß an der Technik ist das Lösen von Problemen. Herausforderungen, wie zum Beispiel unzureichende Pins, treten bei der Entwicklung von Embedded Systemen regelmäßig auf. Die kreative Nutzung der verfügbaren Ressourcen, beispielsweise die Verwendung eines einzigen Pins für mehrere Funktionen, ist nicht neu. Aus diesem Grund ist es hilfreich, aufgeschlossen und neugierig zu bleiben und die Geschichte des Fachgebiets zu kennen. Nur weil etwas vor über einem Jahrhundert erfunden wurde, heißt das nicht, dass es heute nicht mehr von Bedeutung ist!