Kann der Arduino verwendet werden, um eine UART-Verbindung zwischen zwei Geräten "auszuspionieren"?

Ich muss einen Arduino (eigentlich nur den IC) in vorhandene Hardware einbauen, um die Funktionalität zu verbessern.

Ich möchte den Arduino so anschließen, dass er die E / A-Leitungen zwischen zwei Chips auf einer Platine "ausspioniert". Wenn der Arduino ein bestimmtes Schlüsselwort auf dieser UART-Verbindung aufnimmt, führt er eine bestimmte Aktion an einem separaten Satz von Ausgangspins aus.

Worüber ich mir nicht sicher bin, ist, wie ich das Arduino so anschließen kann, dass es eine vorhandene UART-Verbindung decodieren kann, ohne daran teilzunehmen? Falls nicht möglich, interessiere ich mich für Theorien, Ideen etc.

Antworten (3)

Wenn ich das richtig verstehe, hast du 2 Geräte über UART verbunden. Ich nehme an, dass nur TX-, RX- und GND-Leitungen zwischen den Geräten verbunden sind? (dh es werden keine DTS/CTS/DTR/RTS-Steuerleitungen verwendet – dies ist typisch).

In diesem Szenario ist der TX (Senden) von Gerät 1 mit dem RX (Empfangen) von Gerät 2 verbunden und umgekehrt. Ihre Böden sind miteinander verbunden. Somit kann jedes Gerät gleichzeitig senden und empfangen (jedes sendet auf einer separaten Leitung, die Kommunikation ist Vollduplex).

Der Grund, warum ich das alles erwähne, ist, dass klar wird, dass Sie zum "Schnüffeln" oder "Zuhören" tatsächlich 2 UARTs benötigen, um beide Seiten des Gesprächs zu hören.

Im Grunde müssen Sie nur sicherstellen, dass die UART-GNDs aller 3 Geräte kurzgeschlossen sind, und die TX-Leitungen von Gerät 1 und Gerät 2 mit den 2 RX-Leitungen verbinden (wirklich "T-Stück", wie bei einem T-Anschluss, wie z. B. Rohrleitungen). auf 2 UARTs. Achten Sie darauf, dass die Baudraten alle identisch konfiguriert sind.

Es gibt viele Arduino Boards / Designs. Der heutzutage gebräuchlichste, der Duemilanove, verwendet den ATMega328P, der meiner Meinung nach nur 1 UART (na ja, USART) hat. Sie müssten also entweder einen zweiten UART-IC verkabeln oder auf "Bit Banging" am zweiten Empfänger zurückgreifen.

Die asynchrone UART-Kommunikation ist gut definiert, mit Start- und Stoppbits (und manchmal Paritätsbits). Wenn Ihr Prozessor also schnell genug ist, können Sie einfach eine der UART-TX-Leitungen des Geräts mit einem als Eingang konfigurierten GPIO verbinden und die Leitung abfragen schnell genug mit Oversampling, um START & STOP und Sample-Bits zu erkennen. Der Artikel „Bit Banging“ von Jack Ganssle gibt Ihnen reichlich zu kauen.

Eine anständige Beschreibung der RS232-Wellenform finden Sie bei BeyondLogic .

Beachten Sie, dass es andere Probleme wie Spannungspegel (0/+5, -10 V/+10 V usw.) gibt, die Sie berücksichtigen müssen (siehe Abschnitt „Beyond Logic“ zu „RS232-Pegelwandler“). Ich habe nicht genügend Informationen über Ihr System, um neben dem oben beschriebenen Ansatz "Verbindung der Leitungen" über Hardwareschnittstellen zu sprechen. Unter der Annahme, dass die Spannungspegel übereinstimmen, ist es normalerweise kein Problem, die TX-Leitung in einen zweiten Empfänger (den Sniffer) zu "verzweigen", aber wenn der TX nicht über genügend Laufwerk verfügt, müssen Sie möglicherweise einen Puffer / Treiber einfügen, um dies zu verhindern Signal von Abbau.

Schön! Ich brauche die Daten nur in eine Richtung, also reicht der einzelne UART auf dem ATMega-Chip gerade aus! Die beiden Chips kommunizieren mit +/-5V UART, was meiner Meinung nach mit dem ATMega identisch ist. Wow, das sollte es sein! Vielen Dank!
@BradHein, was Sie "+/-5V" nennen, wird normalerweise als "TTL-Pegel" bezeichnet - siehe en.wikipedia.org/wiki/Logic_level .
@Mels +/-5V ist NICHT TTL, TTL geht NICHT unter Masse. Dies ist RS-232.

Es gibt einen netten Trick, den Sie anwenden können, wenn die Kommunikation jeweils nur in eine Richtung erfolgt (dh Halbduplex-Kommunikation). Es wird nicht funktionieren, wenn beide Seiten gleichzeitig miteinander sprechen (Vollduplex), aber wenn es Ihre typische Art der Kommunikation ist: "Mach das", "OK, hier ist die Antwort", "Jetzt mach das", "Ok, hier ist die neue Antwort". es funktioniert ganz gut.

Da die UART-Verbindung einen Leerlaufzustand des Senders auf einem logisch hohen (1) Pegel verwendet, würden Sie ein UND-Gatter mit 2 Eingängen verwenden und den TX von jeder Seite mit einem UND-Eingang verbinden. Der Ausgang des UND-Gatters ist Ihr Eingang zum UART Ihres Sniffers (es ist RX-Pin). Nehmen Sie nun die TX-Leitung von Gerät B und bringen Sie sie ebenfalls zu einem I/O-Port am Sniffer. Sie konfigurieren den Sniffer so, dass er einen Interrupt generiert, wenn dieser Pin von High auf Low wechselt.

Zur Erinnerung: Gerät A UART TX -> AND-Gate-Eingang. Gerät B UART TX -> anderer AND-Gate-Eingang UND Sniffer-GPIO-Pin. Ausgang des UND-Gatters -> Sniffer-UART-RX-Leitung.

UART-Kommunikationen bestehen aus einem Startbit, einer Anzahl von Datenbits, einem optionalen Paritätsbit und einem oder mehreren Stoppbits. Da der Ruhezustand ein logisches Hoch (1) ist, ist der Anfang jedes Bytes ein logisches Niedrig (0) und der Interrupt auf dem Sniffer wird ausgelöst. Während Ihr Sniffer den E/A-Interrupt ausführt, sammelt die UART-Hardware Bits vom UND-Gatter. Bis der UART das Stoppbit empfangen hat, ist der E/A-Interrupt lange beendet und der UART-RX-Interrupt wird ausgelöst.

Die Interrupt-on-IO-Change-Routine wird eine "Richtungs"-Variable setzen, um anzuzeigen, dass die Kommunikation in der "B->A"-Richtung erfolgt. Der UART-Empfangsinterrupt des Schnüfflers würde sich diese "Richtungs"-Variable ansehen und das gerade empfangene Byte in den entsprechenden Puffer schreiben. Der UART RX-Interrupt würde dann die Variable "Richtung" wieder auf den Standardzustand "A-> B" setzen:

volatile int direction = 0;           /* 0 = A -> B */

void io_interrupt(void)
{
    direction = 1;                    /* switch direction, now B -> A */
}

void uart_interrupt(void)
{
    unsigned char b;

    b = UART_RX_REG;
    if(direction) {
        store_byte_to_device_b_sniff_buffer(b);
    } else {
        store_byte_to_device_a_sniff_buffer(b);
    }

    direction = 0;                   /* reset direction to default A -> B */
}

Dieser Code wurde zur Verdeutlichung geschrieben und nicht unbedingt das, was Sie in einer realen Situation schreiben würden. Persönlich würde ich "Richtung" zu einem Zeiger auf die entsprechende FIFO-Struktur machen, aber das ist eine ganz andere Übung. :-)

Wenn Gerät A spricht, bewegt sich die E/A-Leitung nicht (sie bleibt auf einer logischen „1“, da der UART-Sender von Gerät B im Leerlauf ist), und der UART RX-Interrupt empfängt ein Byte, achten Sie darauf, dass die Richtung A-> B ist , und speichern Sie die Daten in diesem Puffer. Wenn Gerät B spricht, geht die E/A-Leitung auf Low, sobald Gerät B mit dem Verschieben von Daten beginnt, und die E/A-Unterbrechungsroutine stellt die Richtung ein, um anzuzeigen, dass Gerät B spricht. Der UART-RX-Interrupt wird schließlich ausgelöst, nachdem alle Bits gesammelt wurden, und da der E/A-Interrupt für die richtige Einstellung des Richtungsregisters gesorgt hat, wird das empfangene Byte im richtigen Puffer gespeichert.

Presto: Halbduplex-Kommunikation zwischen zwei Geräten, die mit einer einzigen UART- und E/A-Leitung auf dem Sniffer erfasst wurden, ohne Bit-Bang-UART-Kommunikation.

Faszinierend. Das geht an die Grenzen meines Verständnisses, aber es ist großartig! Ein Teil, den ich nicht verstehe, ist, wie der UART des Sniffers mit dem Ziel verbunden ist, damit er beide Kommunikationsrichtungen abfangen kann? Ich habe mehrere I/O-Pins zur Verfügung, könnte ich also einfach zwei I/O-Pins mit dieser Methode verwenden und effektiv beide Richtungen des Datenverkehrs erfassen?
Die Sniffer-UART-RX-Leitung ist mit dem Ausgang des UND-Gatters verbunden. Der UART TX von Gerät A ist mit einem Eingang des UND-Gatters verbunden, und der UART TX von Gerät B ist mit dem anderen Eingang des UND-Gatters verbunden. Da der Ruhezustand (kein Verkehr) eines UART eine logische „1“ ist, kombiniert das UND-Gatter effektiv beide Sendesignale zu einem. Die I/O-Leitung auf dem Sniffer wird verwendet, um das Startbit von Gerät B zu erkennen, damit es das Byte, das es auf seinem UART empfängt, nehmen und es in den entsprechenden Puffer (Verkehr von Gerät A oder Gerät B) legen kann.
Das Codefragment und die Beschaltung des UND-Gatters ermöglichen es dem Sniffer, mit einem einzigen UART beide Richtungen des Verkehrsflusses aufzuzeichnen. Dies funktioniert NUR, wenn der Datenverkehr halbduplex ist. Das heißt, wenn ein Gerät spricht, hört das andere zu. Wenn beide gleichzeitig sprechen (Vollduplex) dann würde das gar nicht funktionieren.

Sie müssen den Sendedaten-Pin des AVR nicht in Ihren Stromkreis einbinden. Schließen Sie einfach die Empfangsleitung an die Hälfte der bestehenden Verbindung an, die Sie abhören möchten. Wenn Ihr spezieller AVR zwei serielle Ports hat, sollten Sie in der Lage sein, beide Hälften der bestehenden Verbindung gleichzeitig auszuspionieren. Sie müssen nur die Porteinstellungen an die vorhandene Baudrate, Stoppbits usw. anpassen.