¿Se puede usar el Arduino para "espiar" una conexión UART entre dos dispositivos?

11

Necesito instalar un Arduino (en realidad solo el IC) en el hardware existente para mejorar la funcionalidad.

Lo que me gustaría hacer es conectar el Arduino para que "espíe" en las líneas de E / S entre dos chips en una placa. Si el Arduino selecciona una palabra clave específica en esa conexión UART, realizará una acción específica en un conjunto separado de pines de salida.

De lo que no estoy seguro es de cómo conectar el Arduino de tal manera que pueda decodificar una conexión UART existente sin participar. Si no es posible, estoy interesado en teorías, ideas, etc.

Brad Hein
fuente

Respuestas:

17

Si entiendo correctamente, tiene 2 dispositivos conectados a través de UART. ¿Asumo solo las líneas TX, RX y GND conectadas entre los dispositivos? (es decir, no se utilizan líneas de control DTS / CTS / DTR / RTS; esto es típico).

En este escenario, el TX del dispositivo 1 (transmisión) está conectado al RX del dispositivo 2 (recepción) y viceversa. Sus terrenos están conectados entre sí. Por lo tanto, cada dispositivo puede transmitir y recibir al mismo tiempo (cada uno transmite en un cable separado, la comunicación es full-duplex).

La razón por la que menciono todo esto es porque queda claro que para "oler" o "escuchar", realmente necesitará 2 UART para escuchar a ambos lados de la conversación.

Básicamente, todo lo que haría es asegurarse de que los UART GND de los 3 dispositivos estén en cortocircuito, y conectar (realmente, "tee", como en una conexión en T, como plomería) las líneas TX del dispositivo 1 y del dispositivo 2 a las 2 líneas RX en 2 UARTs. Asegúrese de que las velocidades de transmisión estén configuradas de manera idéntica.

Hay muchas tablas / diseños de Arduino. El más común hoy en día, el Duemilanove, usa el ATMega328P, que creo que solo tiene 1 UART (bueno, USART). Por lo tanto, tendría que conectar un segundo UART IC o recurrir a "golpes" en el segundo receptor.

Las comunicaciones asíncronas UART están bien definidas, con bits de inicio y parada (y a veces bits de paridad), por lo que si su procesador es lo suficientemente rápido, simplemente puede conectar una de las líneas UART TX del dispositivo a un GPIO configurado como entrada y sondear la línea lo suficientemente rápido con sobremuestreo para detectar START & STOP y bits de muestra. El artículo "Bit Banging" de Jack Ganssle te dará mucho para morder .

Se puede encontrar una descripción decente de la forma de onda RS232 en BeyondLogic .

Tenga en cuenta que hay otros problemas como los niveles de voltaje (0 / + 5, -10V / + 10V, etc.) que deberá tener en cuenta (consulte la sección Más allá de la lógica en "Convertidores de nivel RS232"). No tengo suficiente información en su sistema para discutir la interfaz de hardware además del enfoque de "conectar las líneas" discutido anteriormente. Suponiendo que los niveles de voltaje coinciden, generalmente no es un problema "conectar" la línea TX a un segundo receptor (el sniffer), pero si el TX no tiene suficiente unidad, es posible que deba insertar un buffer / controlador para evitar señal de degradación.

Radián
fuente
¡Hermoso! ¡Solo necesitaré que los datos viajen en una dirección, por lo que el único UART en el chip ATMega es suficiente! Los dos chips se comunican con +/- 5V UART, que creo que es lo mismo que ATMega. Wow, eso debería ser! ¡Gracias!
Brad Hein el
@BradHein, lo que se llama "+/- 5V" generalmente se conoce como "nivel TTL"; consulte en.wikipedia.org/wiki/Logic_level .
Mels
3
@Mels +/- 5V NO es TTL, TTL NO va debajo del suelo. Este es RS-232.
nmz787
9

Hay un buen truco que puede hacer si la comunicación es en una dirección solo a la vez (es decir, comunicación semidúplex). No funcionará si ambas partes se comunican entre sí al mismo tiempo (dúplex completo), pero si es su típico "haga esto", "esta es la respuesta", "ahora haga esto", "esta es la nueva respuesta". Funciona bastante bien.

Como el enlace UART usa una condición inactiva del transmisor en un nivel lógico alto (1), usaría una puerta AND de 2 entradas y conectaría el TX de cada lado a una entrada AND. La salida de la compuerta AND es su entrada al UART de su sniffer (es el pin RX). Ahora tome la línea TX del dispositivo B y también llévela a un puerto de E / S en el sniffer. Configurará el sniffer para generar una interrupción cuando este pin pase de mayor a menor.

Para recapitular: dispositivo A UART TX -> Y entrada de puerta. Dispositivo B UART TX -> otra entrada de compuerta AND Y pin GPIO sniffer. Salida de la compuerta AND -> sniffer línea UART RX.

Las comunicaciones UART consisten en un bit de inicio, cierto número de bits de datos, un bit de paridad opcional y uno o más bits de parada. Como el estado inactivo es un nivel lógico alto (1), el inicio de CADA byte será un nivel lógico bajo (0) y se disparará la interrupción en el sniffer. Mientras su sniffer está ejecutando la interrupción de E / S, el hardware de UART recogerá bits de la puerta AND. Para cuando el UART haya recibido el bit de parada, la interrupción de E / S habrá finalizado por mucho tiempo y se disparará la interrupción UART RX.

La rutina de interrupción por cambio de E / S establecerá una variable de "dirección" para indicar que las comunicaciones están en la dirección "B-> A". La interrupción de recepción UART del sniffer miraría esta variable de "dirección" y escribiría el byte recién recibido en el búfer apropiado. La interrupción de UART RX volvería a establecer la variable "dirección" en el estado predeterminado "A-> B":

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 */
}

Este código está escrito para mayor claridad y no necesariamente lo que escribiría en una situación del mundo real. Personalmente, haría de "dirección" un puntero a la estructura FIFO apropiada, pero ese es otro ejercicio completamente diferente. :-)

Cuando el dispositivo A está hablando, la línea de E / S no se mueve (permanece en un '1' lógico ya que el transmisor UART del dispositivo B está inactivo), y la interrupción UART RX recibirá un byte, verifique que la dirección sea A-> B y almacenar los datos en ese búfer. Cuando el dispositivo B está hablando, la línea de E / S se reducirá tan pronto como el dispositivo B comience a cambiar los datos, y la rutina de interrupción de E / S establecerá la dirección para indicar que el dispositivo B está hablando. La interrupción UART RX eventualmente se disparará después de que se hayan recopilado todos los bits y dado que la interrupción de E / S se ha encargado de establecer el registro de dirección de manera adecuada, el byte recibido se almacenará en el búfer correcto.

Presto: comunicaciones semidúplex entre dos dispositivos capturados con una sola línea UART y línea de E / S en el sniffer, sin comunicaciones UART con bit bitged.

akohlsmith
fuente
Intrigante. Esto está empujando los límites de mi comprensión, ¡pero es genial! Una parte que no entiendo es cómo se conecta el UART del rastreador al objetivo para que pueda interceptar ambas direcciones de comunicación. Tengo varios pines de E / S disponibles, entonces, ¿podría usar dos pines de E / S usando este método y recolectar efectivamente ambas direcciones de tráfico?
Brad Hein el
La línea sniffer UART RX está conectada a la salida de la compuerta AND. El UART TX del dispositivo A está conectado a una entrada de la puerta AND, y el UART TX del dispositivo B está conectado a la otra entrada de la puerta AND. Dado que la condición de inactividad (sin tráfico) de un UART es un '1' lógico, la compuerta AND combina efectivamente ambas señales de transmisión en una. La línea de E / S en el sniffer se usa para detectar el bit de inicio del dispositivo B para que pueda tomar el byte que está recibiendo en su UART y colocarlo en el búfer apropiado (tráfico del dispositivo A o tráfico del dispositivo B).
akohlsmith
El fragmento de código y el cableado de la compuerta AND permiten al rastreador registrar ambas direcciones del flujo de tráfico con un solo UART. Esto SOLO funciona si el tráfico es half-duplex. Eso significa que cuando un dispositivo está hablando, el otro está escuchando. Si ambos hablan al mismo tiempo (dúplex completo), esto no funcionaría en absoluto.
akohlsmith
5

No tiene que conectar el pin de transmisión de datos del AVR a su circuito. Simplemente conecte la línea de recepción a la mitad del enlace existente que desea espiar. Si su AVR en particular tiene dos puertos seriales, debería poder espiar ambas mitades del enlace existente simultáneamente. Solo tiene que hacer que la configuración del puerto coincida con la velocidad de transmisión, los bits de parada, etc.

JustJeff
fuente