Datos en serie recibidos en bits incorrectos

Tengo una interfaz RS422 configurada entre un Arduino y un dispositivo personalizado. El dispositivo está configurado para transmitir un encabezado de 16 bits, seguido de 66 bytes de datos, a una velocidad de transmisión de 460.800 y 200 Hz. Esto no se puede cambiar.

He leído en línea que la serie Arduino puede manejar 460.800 bps sin ningún problema. De hecho, me he comunicado con éxito entre MatLab y Arduino a esa velocidad en baudios sin problemas. También he confirmado que el dispositivo funciona, ya que cuando se conecta directamente a la computadora, se lee bien.

Cuando trato de leer los datos usando el Arduino, no obtengo lo que se espera. El encabezado que se supone que debo recibir es 0x55AA. Sin embargo, obtengo 0xD56A la mayor parte del tiempo, pero a veces obtengo valores como 0xB5CA. Parece que la segunda mitad de cada byte es correcta, pero no la primera, y tengo algunos bits subiendo y otros bajando cuando no deberían. Debido a esto, cuestiono la validez de los datos que se transmiten.

¿Puede alguien explicarme por qué sucede esto y qué soluciones puedo intentar para remediar esto, por favor?

Gracias

ACTUALIZACIÓN: he mirado con un osciloscopio y puedo ver que la forma de onda sale como 0x55AA, como debería ser. Aumenté el búfer serial de Arduino y cambié las placas, pero el problema persiste.

Me las arreglé para hacerlo funcionar a una tasa de baudios más baja (115,200), pero necesito tenerlo configurado en 460,800. A esta tasa de baudios más baja, obtendría 0x55AA, pero tan pronto como lo subo a 460,800, pierdo estos datos y se vuelve como se mencionó anteriormente.

¿Qué le hace pensar que solo hay una razón por la que los síntomas descritos pueden ocurrir?
Si tiene acceso a un alcance, ahora es un buen momento para usarlo.
¿Alguna vez obtienes el encabezado correcto?
@PlasmaHH No digo que solo haya una causa, solo pido una explicación de por qué sucede esto y cómo resolverlo.
@BrianDrummond El alcance muestra 0x55AA, como debería.
@Tom: eso parece contradictorio. Usted mismo dice que no hay una sola razón por la que esto sucede, pero quiere que le digamos por qué sucede. Lo mejor que podemos darle es una especulación sobre los cientos de posibles cosas que podrían haber salido mal, pero no tenemos ninguna información sobre el hardware involucrado o cómo se ven las señales. Entonces, en ese nivel, la razón por la que esto sucede es porque los datos no pasan correctamente de A a B.
@Andyaka No a esta velocidad en baudios. Sin embargo, lo hago a una velocidad de transmisión más baja. A esta velocidad de transmisión (460 800), obtengo 0x952A, 0xD56A, etc.

Respuestas (2)

Primero, veamos los datos que mencionas:

0x55AA  0101010110101010
0xD56A  1101010101101010
0xB5CA  1011010111001010

Como podemos ver, los datos son cercanos, pero ligeramente desviados. Las razones por las que los datos en serie están "ligeramente apagados" son muchas, pero una obvia en su caso particular es la tasa de datos en serie. Para que los datos seriales asincrónicos se reciban correctamente, el reloj original debe recrearse en el extremo receptor. Una regla general para los enlaces en serie es que si las frecuencias de reloj están desfasadas en más del 3 %, obtendrá errores muy parecidos a los que describe.

Así que a una velocidad de 460.800 bits/segundo, eso es un poco más de 2,27 m s por bit. Estos son algunos consejos para solucionar problemas:

  1. verifique los relojes de tasa de bits en ambos extremos y asegúrese de que las frecuencias estén dentro del 3% entre sí.
  2. mantenga su cableado lo más corto posible.
  3. verifique la terminación de la línea en ambos extremos para asegurarse de que tenga la misma impedancia que la línea.
  4. compruebe la forma de onda recibida con un osciloscopio. Busque transiciones resonantes o lentas.

También puede considerar si hay un CRC en el paquete que al menos lo ayude a detectar un error.

Cómo comprobar los relojes

Primero, permítanme exponer mis suposiciones:

  1. cada lado puede enviar datos arbitrarios
  2. los datos se envían en formato 8-N-1 (8 bits de datos, sin paridad, 1 bit de parada)
  3. puede configurar cualquiera de los extremos para enviar continuamente

Dicho esto, veamos cómo se envían normalmente los datos en serie. Veamos los bytes 0x55, 0x55tal como podrían enviarse en un enlace de datos de un solo extremo (RS-232).

+   +---+   +---+   +---+   +---+   +---+   +---+   +---+   +---+   +---+   +---
|   |   |   |   |   |   |   |   |   |   |   |   |   |   |   |   |   |   |   |   
+---+   +---+   +---+   +---+   +---+   +---+   +---+   +---+   +---+   +---+   
  S   1   0   1   0   1   0   1   0   P   S   1   0   1   0   1   0   1   0   P 

En este diagrama, Shay un bit de inicio y Pun bit de parada y los 8 bits de datos se envían primero, como es habitual, el bit menos significativo. Debería quedar claro al observar esto que si mide la frecuencia de esta forma de onda, debería ser exactamente la mitad de la tasa de bits.

Hay una suma de verificación al final del mensaje, pero debido a que no puedo obtener el encabezado correcto, no confío particularmente en el resto de los datos, incluido el valor de la suma de verificación. Tengo la sensación de que es mucho más probable que sea la frecuencia del reloj. Solía ​​funcionar a una velocidad de 115.200 baudios, pero tuve que cambiar eso. 2.27us es de hecho bastante corto. ¿Cómo haría para verificar esto?

¿Qué frecuencia de reloj usas?

Con un reloj de 8 MHz no encuentro un valor de prescaler aceptable para 460800 baudios. 14.7456 MHz podría hacer el trabajo ("Calculadora de tasa de baudios AVR de WormFood").