Caracteres de control en el puerto serie en Arduino Deja un comentario

Continuamos profundizando en el uso del puerto serie avanzado en procesadores como Arduino. En esta entrada vamos a ver como añadir delimitadores de trama y caracteres de control a nuestros sistemas de transmisión para dotarlo de mayor robustez.

Anteriormente hemos visto cómo enviar bytes por puerto serie como una forma conveniente y “profesional” de realizar la comunicación. En la entrada anterior vimos que, frecuentemente, emplearemos una o varias estructuras definiendo un mensaje que queremos enviar o recibir.

Ahora queremos ampliar la trama (los bytes que enviamos en la comunicación) rodeando los bytes de datos con una serie de elementos que aumenten la “calidad” de la comunicación. Un ejemplo es añadir una función de checksum para comprobar la integridad de los datos, algo que veremos en la próxima entrada.

Otro ejemplo, que es el que vamos a ver en esta entrada, es añadir delimitadores de trama. Es decir, una determinada “señal” o marca que identifica el inicio y final de la comunicación. Ya que estamos, también nos gustaría poder añadir ciertos caracteres de control, que tengan un significado especial.

Como de costumbre todo esto ya está inventado y se denominan, precisamente, caracteres de control. De hecho, los estamos usando con frecuencia desde la primera entrada de comunicación cada vez que usamos ‘n’ (salto de línea) o ‘r’ (retorno de carro).

Aquí tenemos una lista de algunos de los caracteres de control disponibles con su valor hexadecimal y con su significado.

 

Código Hex Alt. Significado
NUL 0 Null
SOH 1 Start of Heading
STX 2 Start of Text
ETX 3 End of Text
EOT 4 End of Transmission
ENQ 5 Enquiry
ACK 6 Acknowledge
BEL 7 a Bell
BS 8 b Backspace
HT 9 t Horizontal Tabulation
LF 0A n Line Feed
VT 0B v Vertical Tabulation
FF 0C f Form Feed
CR 0D r Carriage Return
SO 0E Shift Out
SI 0F Shift In
DLE 10 Data Link Escape
DC1 11 Device Control One (XON)
DC2 12 Device Control Two
DC3 13 Device Control Three (XOFF)
DC4 14 Device Control Four
NAK 15 Negative Acknowledge
SYN 16 Synchronous Idle
ETB 17 End of Transmission Block
CAN 18 Cancel
EM 19 End of medium
SUB 1A Substitute
ESC 1B Escape
FS 1C File Separator
GS 1D Group Separator
RS 1E Record Separator
US 1F Unit Separator
SP 20 Space
DEL 7F Delete

 

En particular, vemos que los caracteres de control aceptados para inicio y final de trama son, respectivamente, 0x02 (STX) y 0x03 (ETX). Por supuesto no estamos obligados a emplear estos caracteres. De hecho, en ocasiones veréis en códigos de Internet usar ‘H’ (Header) como principio de un encabezado. No hay ninguna regla que impida usarlo, pero, siendo que existen los caracteres de control, es lógico (y más higiénico) emplear el estándar.

El funcionamiento es sencillo. Al empezar el envío de una trama empezaremos mandando el carácter STX, y al final ETX. Estamos aumentando el tamaño de la trama en dos bytes, a costa de una mejor calidad de la comunicación. El incremento relativo del tamaño de la trama es menor cuanto mayor sea la cantidad de datos que estamos enviando.

Aquí tenemos un ejemplo de envío de un array de datos con delimitadores de trama.

Mientras que un ejemplo de receptor sería el siguiente,

Sin embargo, los caracteres de control no son más que bytes. ¿Cómo de seguro son estos delimitadores? Es decir, ¿es posible que lo confundamos con un byte de datos que contenga 0x02 o 0x3? ¿Es posible que, aun perdiendo bytes, interpretemos equivocadamente uno byte de datos como un delimitador?

Pues efectivamente, así es, ningún sistema es totalmente robusto. Añadir delimitadores de trama mejora el sistema, pero no hace que sea infalible. De hecho, ni siquiera estamos comprobando que la integridad de los datos, solo intentamos comprobar si mantenemos un cierto grado de “sincronización”.

Para que los delimitadores fallen tiene coincidir que, tras perder varios o unos bytes, el byte recibido en la posición en la que debería estar el limitador tenga el mismo valor. Si estamos trabajando en un ambiente con muchos fallos, no va ser suficiente para filtrar todos los defectos.

Puede parecer poco probable pero, en realidad, la posibilidad de interpretar incorrectamente un código de control es de 1/256. Sin embargo, la probabilidad combinada de interpretar mal simultáneamente el inicio y final del mensaje es de 1/65.536.

Sin embargo, la ventaja real es que aporta una cierta capacidad de “resincronización”. En un entorno “normal”, ante una puntual pérdida de paquetes, el sistema puede detectar el fallo y, eventualmente, recuperar la sincronización.

Por supuesto, podemos mejorar mucho el proceso de transmisión, añadiendo un timeout, o un checksum. Veremos todo esto en las próximas entradas.

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

Este sitio usa Akismet para reducir el spam. Aprende cómo se procesan los datos de tus comentarios.

Enviar Whatsapp
Hola 👋
¿En qué podemos ayudarte?