¿Cómo decodificaría por software esta transmisión en serie de 260 KHz?

Probé este flujo en serie que sale de un controlador de marcador y parece un protocolo propietario. ¿Cómo haría para tratar de decodificar esto por software?

flujo en serie

El bit de inicio tiene una longitud de 7,8 us. Todos los bits de datos son de aproximadamente 3,85 us, lo que da una velocidad de bus de alrededor de 260 KHz. Un bit lógico ALTO comienza con un período ALTO de 3.1us y luego con un BAJO de ~800ns. Un bit lógico BAJO es lo mismo, pero los períodos se intercambian. Cada paquete está compuesto por 255 bits, por lo que se envía aproximadamente un paquete cada milisegundo.

Pensé en disparar en el flanco ascendente y luego leer el nivel del pin después de un breve retraso, pero no creo que un esquema controlado por interrupciones funcione tan bien debido a la sobrecarga.

¿Algunas ideas?

¿Qué micro piensas usar?
No creo que un AVR sea lo suficientemente rápido para esto, así que estoy usando un Teensy 3.0.
¿No estás seguro de cómo esto es un duplicado? Las señales no son las mismas (una es similar a RS232 y la otra es un protocolo propietario). También haciendo diferentes preguntas... Esto pregunta cómo decodificar eficientemente una línea serial de alta velocidad, no una identificación.
Puede buscar un dispositivo lógico programable, aunque hacer una solución de ciclo contado en un microcontrolador dedicado a esta tarea en realidad puede ser más fácil de desarrollar. Estaría tentado de capturar primero un montón de datos en el disco con un analizador lógico de transmisión económico y decodificarlo sin conexión para asegurarme de que entendí el formato.
Tienes que perdonar a los críticos. A veces solo buscan similitudes superficiales antes de cerrar una pregunta como un duplicado. Esta es claramente una pregunta diferente y merece una respuesta, especialmente dado que la otra pregunta no tenía respuesta de todos modos.
@DaveTweed Lo siento, yo fui uno de los culpables. Ambas preguntas eran de la misma persona, involucraban protocolos en serie con marcadores y tenían diagramas de tiempo de aspecto similar (aunque al mirar más de cerca puedo ver que son diferentes). Así que llegué a la conclusión de que había duplicados.

Respuestas (3)

Usted dice que la sobrecarga del manejo de interrupciones sería demasiado alta, pero no creo que eso sea necesariamente cierto. Es posible que un microcontrolador barato no pueda realizar un procesamiento muy útil del flujo de datos, pero debería ser lo suficientemente potente como para servir como un convertidor ad-hoc.

Tomemos un chip AVR como ejemplo: el ATmega328P que sirve como núcleo de la placa de desarrollo Arduino. A la velocidad de reloj máxima de 20 MHz, obtiene 77 ciclos de reloj por bit. De acuerdo con la hoja de datos (página 15), se necesitan aproximadamente 7 ciclos de reloj para ingresar a un ISR y 4 ciclos para salir.

Suponiendo que gasta la mitad de cada bit de datos en un bucle giratorio esperando el momento adecuado para probar la entrada, le quedan alrededor de 27 ciclos por bit fuera del controlador de interrupciones. La mayoría de las instrucciones AVR son de un solo ciclo, por lo que debería ser suficiente tiempo para enmarcar los bits en bytes y enviarlos a un enlace SPI a su procesador host.

(He pasado por alto el problema de detectar bits de inicio. Una opción es restablecer uno de los temporizadores incorporados al comienzo de cada bit y usar la comparación de salida para determinar si el intervalo entre dos flancos ascendentes excede un umbral. )

+1. Sí, un bucle de giro de reloj de 25 a 20 MHz es bastante razonable. ¿Tal vez la detección de bits de inicio podría encajar en esos 25 relojes? El tiempo restante es aproximadamente equivalente a un ATmega328 a 10 MHz. Mucha gente usa el ATmega328 a 10 MHz o menos y hace cosas útiles.

He decodificado señales como esta con AVR. Lo hice con una interrupción de cambio de pin y un temporizador de ejecución libre. También podría hacerlo con una entrada de captura en el temporizador, pero también estaba activando los datos, por lo que necesitaba la capacidad de detección asíncrona.

Básicamente, lo que hice fue cada vez que recibí una interrupción de cambio de pin, miré la hora y el estado del pin. Luego podría decir "el pin tenía 3 us de alto" o "el pin tenía 3 us de bajo" y cambiar el 1 o el 0 a una palabra de datos de entrada. Usé un @#define@ para determinar el tiempo de umbral de un valor alto o bajo y determiné empíricamente un buen valor para usar. Mis palabras de datos recibidas tenían 33 bits de largo, así que después de contar 33 bits marqué la recepción como completa y marqué la rutina principal para verificar y decodificar la palabra de datos.

Para mayor robustez, también reinicié un temporizador que tenía un período de aproximadamente 10 ms. Si se disparó esa interrupción, significaba que debía restablecer mi subsistema de recepción, ya que no entraba ningún dato y mi contador de bits no había contado suficientes datos para considerar que el mensaje estaba completo.

Una forma de decodificar esto sería invertirlo y luego alimentarlo a un UART configurado para 2.6 Mbps (un poco extremo, pero algunos UART pueden configurarse tan alto).

El flanco ascendente de cada pulso se convertiría en un flanco descendente (un bit de inicio) para el UART, y cada tipo de pulso produciría un patrón de datos único en el receptor UART: un "1" se convertiría en 0x80, un "0" se convertiría en 0xFE, y un "bit de inicio" se convertiría en 0x00 (y posiblemente causaría un error de "desbordamiento"). El firmware convertiría estos valores de byte en bits y luego decodificaría el protocolo según corresponda.

Es posible que pueda configurar el UART a 1,3 Mbps y recibir dos de los pulsos de señal por byte: la decodificación se vuelve un poco más complicada, pero solo tendría que lidiar con la mitad de la tasa de interrupción.

  • 0x00 → pulso de inicio
  • 0x7F → 0 seguido de 0
  • 0x0F → 0 seguido de 1
  • 0x74 → 1 seguido de 0
  • 0x04 → 1 seguido de 1

Un enfoque completamente diferente sería utilizar un par de multivibradores monoestables reactivables . Uno se establecería en un período de alrededor de 1,9 µs; crearía un borde de reloj en el centro de cada bit. El otro se establecería en un período de unos 5 µs; detectaría el pulso de "inicio".

Luego, conectaría estas señales a un puerto esclavo SPI en su micro: la señal de datos original a MOSI, la señal de reloj a SCLK y la señal de inicio a SSEL. La interfaz SPI recopilaría 8 bits a la vez y los entregaría al firmware a una velocidad de aproximadamente 32 kB/seg.