Abrir el puerto serie para leer, cuando los datos ya están fluyendo

2

Tengo un drummachine (Roland TR505, pero todo esto sería cierto con cualquier otro dispositivo) enviando un byte 11111000 ( Timing Clock MIDI message ), 48 veces por segundo, a un puerto MIDI OUT. Funciona bien.

Estoy leyendo la señal MIDI en mi dispositivo electrónico a través del software con las técnicas de lectura clásicas puerto serie (a 31500 baudios, etc., respeté totalmente el estándar MIDI en mi esquema electrónico).

[ROLAND TR505]  =====MIDI cable=====> [MY ELECTRONIC DEVICE]

Tengo una situación complicada:

  1. Si enciendo mi dispositivo electrónico y dejo que se inicie el software de lectura del puerto serie, y luego enciendo el TR505, funciona : el flujo de los bits que llegan al puerto serie se interpreta correctamente. Funciona perfectamente.

  2. Si enciendo el TR505 (es decir, los bits ya fluyen al puerto serie), y entonces enciendo mi dispositivo electrónico, hay un problema : probablemente mi dispositivo comience a leer datos en serie en medio de un byte , es decir, los datos se interpretan incorrectamente.

Pregunta : cuando conecta un dispositivo que ya está encendido, ya envía datos a otro dispositivo que escucha el puerto serie, ¿cómo garantizar que el dispositivo de escucha no se inicie en medio de un byte?

es decir, si el flujo de bits es:

...0111100001111000011110000...

¿Cómo sabrá mi dispositivo que es byte1=11110000 y no byte1=01111000 ?

Aquí está el código del software en Python:

import serial

ser = serial.Serial('/dev/ttyAMA0', baudrate=38400) # Note: there's a well known hack in /boot/config.txt to make this work at 31500 baud, which is normally not supported on Raspberry; in short baudrate is not the problem

while True:
    data = ord(ser.read(1)) # read a byte
    
pregunta Basj

3 respuestas

2
  

si el flujo de bits es:

     

... 0111100001111000011110000 ...

     

¿cómo sabrá mi dispositivo que es byte1 = 11110000 y no byte1 = 01111000?

Esa no es la imagen completa. Cada byte se 'enmarca' con un bit de inicio (0) y un bit de parada (1). El UART se sincroniza buscando la transición de 1 a 0 cuando se va de Stop a Start.

La mayoría de los dispositivos no envían datos continuamente, y cualquier espacio de más de 9 bits debería ser suficiente para sincronizarse. La velocidad en baudios de MIDI es de 31250 bps, por lo que si el reloj temporizador es un solo byte repetido 48 veces por segundo, debería haber un gran espacio entre los bytes. El flujo de bits real debería tener este aspecto: -

...011110000111111111111111111111111...1111111111111111110111100001....
    ^Byte-1^                                              ^Byte-2^
    
respondido por el Bruce Abbott
3

Consideremos un flujo en serie continuo que sale de un TxUART a un RxUART. Sin intervalos entre bytes y solo 1 bit de parada. TxUART ya se está ejecutando y de medio byte cuando RxUART está listo para recibir.

Existe la tentación de pensar que RxUART nunca se sincronizará con los bytes transmitidos desde TxUART. Que tomará el siguiente 0 como bit de inicio y luego terminará de recibir en el medio del siguiente byte y así sucesivamente.

En realidad, se sincroniza con bastante rapidez, en el peor de los casos dentro de un par de cientos de bytes.

RxUART está buscando un bit de inicio ... en realidad un bit de parada seguido de un bit de inicio, por lo tanto un flanco descendente. 9 bits después necesita un bit de parada. Así que está buscando:

10dddddddd1

Si no encuentra un 1, y con frecuencia no lo hace, es un error de encuadre y ese byte se descartará de todos modos. Luego buscará el siguiente patrón de 10 bits de parada-inicio. Así que se está "deslizando" a lo largo de la transmisión en serie de TxUART, acercándose cada vez más al bit de inicio real. Una vez en un bit de inicio, los bits de parada están en el lugar correcto y permanece sincronizado.

Para el registro, hice el análisis una vez en un sistema con un RxUART que se iniciaba aleatoriamente cuando un TxUART ya estaba enviando bytes de incremento continuo. Mi conjetura fue que nunca se sincronizaría '. Mi estudio mostró rápidamente que el número de bytes incrementales entrantes antes de que se sincronice RxUART es de 2 como mínimo y 128 como máximo. Aquí, sus datos son más aleatorios, pero los principios siguen vigentes.

    
respondido por el TonyM
1

Los UART utilizan el flanco descendente al comienzo del bit de inicio para sincronizar entre el remitente y el receptor. Por lo tanto, es posible capturar un borde equivocado.

Hay (comparativamente) largas pausas entre los mensajes del reloj, por lo que es poco probable que comience en medio de un byte.

Pero incluso si empezaste en el momento equivocado, aún necesitabas un bit de datos 0 que se interpreta como el bit de inicio, por lo que los posibles valores "incorrectos" son:

  • 00111111: 3F = datos
  • 01111111: 7F = datos
  • 11111111: FF = Reinicio del sistema

(Si el receptor no espera a que la línea se vuelva baja, pero en realidad comprueba si hay un flanco descendente, solo 3F es posible).

Los bytes de datos 3F / 7F se ignorarían porque no hay un byte de estado anterior. El comando de reinicio del sistema es teóricamente válido, pero la mayoría de los dispositivos lo ignoran, y sería inofensivo como el primer comando recibido.

    
respondido por el CL.

Lea otras preguntas en las etiquetas