Wie implementiert man Zeilencode?

Ich suche nach einer einfachen Möglichkeit, einen Zeilencode zu implementieren (sowohl die Codierungs- als auch die Decodierungsteile). Dies könnte so etwas wie Biphase Mark Code, Differential Manchester oder irgendetwas anderes sein, das die folgenden Eigenschaften hat:

  • Erheblicher Jitter ist in Ordnung (Flanken-Timings können um ~20 % der Zeit eines Bits abweichen)
  • Keine separate Uhr oder Taktsynchronisierung erforderlich (dies kann kein SPI oder UART verwenden, es gibt nur eine Leitung, die nur zwei Pegel übertragen kann)
  • Annähernd ausgeglichene Einsen und Nullen (nicht schlechter als 2:1 Ungleichgewicht) und keine langen Folgen des gleichen Symbols (nicht mehr als 3-5 aufeinanderfolgende Einsen oder Nullen)
  • Schnell! Benötigen Sie 1 Mbit/s oder mehr. (Ich habe 80MIPS-Mikrocontroller auf beiden Seiten, aber Software-Decodierung ist wahrscheinlich immer noch unpraktisch)
  • Billig! Idealerweise etwas, das mit Mikrocontroller-Peripheriegeräten oder einem kostengünstigen Encoder / Decoder-IC durchgeführt werden kann.
Klingt nach USB, bis auf die Zeilenzahl.
@IgnacioVazquez-Abrams: Ein bisschen wie USB, ja. Vielleicht auch ein bisschen wie 10 Mbit Ethernet PHY und viel wie IRDA.
Über welche Distanz zwischen Encoder und Decoder muss das funktionieren? Gibt es eine gemeinsame Basis? Warum nur ein Signal? Ist das eine Einschränkung der MCU oder der "Verkabelung"?
Was ist die Leitungsbandbreite? Ist das Jitter von einem Bit zum nächsten oder wird es langsamer variieren oder ist es eine konstante Abweichung von der "idealen" Taktrate?
Woher kommt das Zittern überhaupt? Sie senden entlang einer Leitung und stellen Sender und Empfänger bereit?
@gbulmer: Es ist optisch - im Grunde eine LED und eine Fotodiode. Keine gemeinsame Masse, keine Verkabelung.
@HannoBinder: Der Jitter tritt hauptsächlich auf, weil die Anstiegszeit und die Abfallzeit asymmetrisch sind und die niedrigen / hohen Schwellenwerte auf der Empfangsseite nicht so eingestellt sind, dass dies kompensiert wird. In einer Folge ..00100.. erscheint die 1 länger als auf der Empfangsseite als beim Senden; in einer Folge ..11011.. erscheint die 0 kürzer. Dies ist ziemlich vorhersehbar, aber aufgrund der Funktionsweise der Empfangsseite ziemlich schwer zu beheben.
@HannoBinder: Die Bandbreite beträgt ca. 16-20MHz.
Warum kann kein UART- oder UART-Typ-Schema verwendet werden? Unidirektionaler Transport benötigt nur eine Datenleitung. Welche Art von Schnittstellen hat Ihr 80-MIPS-Prozessor zur Verfügung? Können die Daten nach dem Empfang über einen parallelen Bus eingetaktet werden? Oder muss es über eine serielle Leitung in den Prozessor gehen oder???
@mkeith: UART funktioniert nicht, wenn diese Menge an Jitter vorhanden ist. Ich habe es versucht. Die Prozessoren haben UART, SPI, I2C, I2S, (vielleicht) CAN, ... all das Standardzeug, aber nichts, was hier anwendbar zu sein scheint. Nach dem Empfang werden die Daten über USB gesendet, ich brauche nur etwas, das sie über UART an den USB-Bridge-Chip senden kann (wie FT232R, FT231X).
@mkeith: Ein bisschen mehr Details zu UART funktionieren nicht: Ich habe versucht, Bytes zu senden, die 0-1 über UART ausgeglichen sind (wie 0xAA, 0x55, 0xA5, ...) und ohne Pausen zwischen Bytes. Der Effekt ist, dass einige Muster gut empfangen werden, aber nicht alle, und selbst dann ist es nicht 100% zuverlässig.
Macht keinen Sinn. Wenn Sie die UART-Spezifikation eingehalten haben, sollte es funktionieren. Sie sagen keine Pause, aber ich gehe davon aus, dass Sie eine korrekte/gültige Start- und Stoppbitkonfiguration verwendet haben. Wenn ja, sehe ich keinen Grund, warum es nicht funktionieren würde. Wenn dies nicht der Fall ist, liegt ein mysteriöses Problem vor, und es gibt auch keine Garantie dafür, dass ein anderes Schema funktioniert. Wie auch immer, es gibt Hochgeschwindigkeits-UARTs, die als Peripheriegeräte funktionieren. Aber sie benötigen möglicherweise einen parallelen Bus. Viel Glück.
Wie viele Mikrosekunden beträgt Ihr Jitter? „~20 % der Zeit eines Bits“ – aber ist das ein Bit bei 1 Megabit/Sekunde oder 10 Megabit/Sekunde?
@davidcary: Ich glaube, ich habe das bei 2 Mbit / s gemessen, also sagen wir mal 100 ns Jitter. Ich muss nochmal nachsehen.

Antworten (1)

Die schlechte Nachricht ist: Einige Probleme lassen sich einfach nicht per Software beheben; Sie müssen entweder Ihre Einschränkungen lockern oder neue Hardware hinzufügen.

Viele optische Kopplungssysteme haben Einschaltverzögerungen, die nicht genau gleich Ausschaltverzögerungen sind, wie Sie bereits bemerkt haben: "..00100.. die 1 erscheint länger ... ..11011.. die 0 erscheint kürzer.". In diesem System ist die 1-zu-0-Verzögerung länger als die 0-zu-1-Verzögerung. Wenn Sie Glück haben, sind diese Verzögerungen konsistent genug, um kompensiert zu werden. Ein Impulsstrecker kann so einfach sein wie eine Diode, ein Kondensator und ein paar Widerstände.

Viele Leitungscodes scheinen Ihre Kriterien zu erfüllen, darunter 4B5B-Codierung , 8b/10b-Codierung (oder einer der typischerweise darin verwendeten 3b/4b- oder 5b/6b-Codes), 6b/8b-Codierung , Manchester-Codierung und ihre Varianten wie Differential Manchester-Codierung , Drei von Sechs, Glasfaser , Pulspositionsmodulation usw.

Softwarekompensation

Ich vermute, Sie haben bereits einige optische Freiraum-Kommunikationshardware eingerichtet, die ein wenig skurril ist, und Sie versuchen, Hardware-Macken vollständig in Software zu kompensieren.

Ein Quick-and-Dirty-Schema ist:

  • Senden Sie unmittelbar vor dem Senden jedes Datenpakets eine Präambel , typischerweise ein "ausgeglichenes" Muster, vielleicht "U"-Zeichen (binär 0101_0101), um dem Bit-Slicer in der Empfangshardware zu helfen, den geeigneten Sollwert zu finden, um zwischen 0 und 1 zu unterscheiden.
  • Senden Sie Bytes (möglicherweise mit dem UART oder dem SPI-Peripheriegerät im Sender) aus einer kurzen Liste, die beim Empfänger "leicht diskriminiert" werden. Ich habe einige Systeme gesehen, die nur zwei eindeutige Bytes aus einem als 8N1 konfigurierten UART senden – 0x00 (dh 9 Nullbits gefolgt von 1 Einsbit) und 0xFF (dh 1 Nullbit gefolgt von 9 Einsbits). (Sie haben nur 2 Bytes in dieser Liste). Wenn Sie Glück haben, können Sie eine größere Liste verwenden.
  • Der Empfänger verwendet für jedes empfangene Byte (möglicherweise unter Verwendung des UART-Peripheriegeräts) eine Nachschlagetabelle, um es in die entsprechenden Bits zu decodieren. Bei obigem Beispiel dekodiert der Empfänger "kurze" Nullimpulse als 1-Bit und "lange" Nullimpulse als 0-Bit.

Viele Leitungscodes können angemessen angenähert werden, indem Bytes in eine Folge von Hexadezimalziffern (Nybbles), Quartärziffern oder einzelnen Binärziffern (Bits) aufgeteilt und dann eine Nachschlagetabelle entworfen werden, die diese Ziffer in 8 oder 10 oder 16 oder so umwandelt Bits (Chips), die, wenn sie vom UART oder dem SPI-Peripheriegerät gesendet werden, diesen Leitungscode angemessen annähern.

Vielleicht kann Ihr System zuverlässig zwischen 16 verschiedenen übertragenen Bytes unterscheiden, sodass jedes übertragene übertragene Byte in 4 Datenbits dekodiert werden kann – Ihr Sender verwendet eines von 16 Bytes in seiner kurzen Liste. Wenn Sie ein Byte mit einem isolierten 1-Bit senden und die Hardware es so weit dehnt, dass der Empfänger manchmal ein Muster mit einem einzelnen 1-Bit und manchmal ein Muster mit zwei 1-Bits sieht, müssen beide Muster in dasselbe dekodiert werden 4 Datenbits. (Außerdem muss der Empfänger irgendein Rauschen zwischen den Paketen irgendwie wegwerfen, die 'U'-Präambelbits wegwerfen usw.).

Vorbetonung

Manchmal können Sie irgendwo in der Senderhardware einen Impulsdehner einfügen und die Widerstände im Sender so einstellen, dass am kritischen Punkt im Empfänger die 1-zu-0-Verzögerung praktisch gleich der 0-zu-1-Verzögerung ist .

Nachbetonung

Manchmal können Sie irgendwo in der Empfängerhardware einen Impulsdehner einfügen und die Widerstände im Empfänger so einstellen, dass am kritischen Punkt im Empfänger die 1-zu-0-Verzögerung praktisch gleich der 0-zu-1-Verzögerung ist .

Bestehende Implementierungen

Es gibt mehrere existierende Implementierungen von optischer Freiraumkommunikation, die mit 1 Megabit/Sekunde oder schneller laufen.

  • Infrared Data Association (IrDA) ; wenn Sie Glück haben, hat Ihr Mikrocontroller bereits Hardware-Unterstützung für IrDA)
    • MIR bei 1 Mbit/s (?)
    • FIR bei 4 Megabit/Sekunde (Die Suche auf http://Digikey.com/ nach „irda fir“, ohne Anführungszeichen, ergibt eine Reihe von Transceiver-Modulen. Vielleicht „Kann das IrDA FIR-Modul (A) direkt mit dem SPI oder UART verbunden werden Pins des Mikrocontrollers (B)?" wäre eine gute unabhängige Frage?) (Würde einer der Schaltpläne im LT1328-Datenblatt für Sie funktionieren?).
    • VFIR bei 16 Mbit/s
  • RONJA (10 Megabit/s Vollduplex)
  • Li-Fi ("1,6 Gbit/s" ?)

Würde einer von denen für Sie funktionieren?

Danke, eine geniale Antwort! Sie haben Recht, ich habe optische Hardware, die funktioniert, aber ein wenig eigenartig ist. Ich glaube nicht, dass ein Pulsdehner funktionieren würde, weil der Jitter nicht so konstant ist (aber ich werde das auf jeden Fall versuchen). Ein IrDA-Encoder-Decoder (Endec) würde wahrscheinlich gut funktionieren, aber ich konnte keine FIR / VFIR-Endec-ICs finden.