Hay muchas formas de escribir un protocolo en serie dependiendo de la funcionalidad que desee y de la cantidad de errores que necesite.
Algunas de las cosas comunes que ve en los protocolos punto a punto son:
Fin del mensaje
Los protocolos ASCII más simples solo tienen un final de secuencia de caracteres del mensaje, a menudo \r
o \n
ya que esto es lo que se imprime cuando se pulsa la tecla Intro. Los protocolos binarios pueden usar 0x03
o algún otro byte común.
Inicio del mensaje
El problema con solo tener el final del mensaje es que no sabe qué otros bytes ya se han recibido cuando envía su mensaje. Estos bytes se prefijarán al mensaje y harán que se interprete incorrectamente. Por ejemplo, si el Arduino acaba de despertarse del sueño, puede haber algo de basura en el búfer en serie. Para evitar esto, tiene una secuencia de inicio de mensaje. En su ejemplo ^
, en protocolos binarios a menudo0x02
Comprobación de errores
Si el mensaje puede corromperse, necesitamos alguna comprobación de errores. Esto podría ser una suma de verificación o un error de CRC u otra cosa.
Personajes de escape
Podría ser que la suma de verificación se agrega a un carácter de control, como el byte 'inicio del mensaje' o 'fin del mensaje', o el mensaje contiene un valor igual a un carácter de control. La solución es introducir un personaje de escape. El carácter de escape se coloca antes de un carácter de control modificado para que el carácter de control real no esté presente. Por ejemplo, si un carácter inicial es 0x02, utilizando el carácter de escape 0x10 podemos enviar el valor 0x02 en el mensaje como el par de bytes 0x10 0x12 (carácter de control XOR de bytes)
Número de paquete
Si un mensaje está dañado, podríamos solicitar un reenvío con un mensaje oculto o reintentar, pero si se han enviado varios mensajes, solo se puede reenviar el último mensaje. En cambio, el paquete puede recibir un número que se transfiere después de un cierto número de mensajes. Por ejemplo, si este número es 16, el dispositivo transmisor puede almacenar los últimos 16 mensajes enviados y, si alguno se dañó, el dispositivo receptor puede solicitar un reenvío utilizando el número de paquete.
Longitud
A menudo, en los protocolos binarios, se ve un byte de longitud que le dice al dispositivo receptor cuántos caracteres hay en el mensaje. Esto agrega otro nivel de comprobación de errores, ya que si no se recibió el número correcto de bytes, hubo un error.
Arduino específico
Al proponer un protocolo para Arduino, la primera consideración es qué tan confiable es el canal de comunicaciones. Si está enviando a través de la mayoría de los medios inalámbricos, XBee, WiFi, etc., ya hay una verificación de errores y reintentos incorporados y, por lo tanto, no tiene sentido incluirlos en su protocolo. Si envía RS422 durante un par de kilómetros, será necesario. Las cosas que incluiría son el comienzo del mensaje y el final de los caracteres del mensaje, como lo ha hecho. Mi implementación típica se parece a:
>messageType,data1,data2,…,dataN\n
La delimitación de las partes de datos con una coma permite un análisis fácil, y el mensaje se envía mediante ASCII. Los protocolos ASCII son excelentes porque puede escribir mensajes en el monitor en serie.
Si desea un protocolo binario, tal vez para acortar el tamaño de los mensajes, tendrá que implementar el escape si un byte de datos puede ser lo mismo que un byte de control. Los caracteres de control binario son mejores para sistemas donde se desea el espectro completo de verificación de errores y reintentos. La carga útil aún puede ser ASCII si se desea.
No tengo ninguna experiencia formal en protocolos seriales, pero los he usado varias veces, y más o menos me decidí por este esquema:
(Encabezado de paquete) (Byte de ID) (datos) (suma de verificación fletcher16) (Pie de página de paquete)
Normalmente hago el encabezado de 2 bytes y el pie de página de 1 byte. Mi analizador volcará todo cuando vea un nuevo encabezado de paquete e intentará analizar el mensaje si ve un pie de página. Si la suma de verificación falla, no eliminará el mensaje, sino que continuará agregando hasta que se encuentre el carácter de pie de página y una suma de verificación tenga éxito. De esa forma, el pie de página solo debe ser de un byte, ya que las colisiones no interrumpen el mensaje.
La ID es arbitraria, a veces con la longitud de la sección de datos siendo el mordisco inferior (4 bits). Se podría usar un segundo bit de longitud, pero normalmente no me molesto, ya que no es necesario conocer la longitud para analizar correctamente, por lo que ver la longitud correcta para una ID dada es solo más confirmación de que el mensaje era correcto.
La suma de verificación fletcher16 es una suma de verificación de 2 bytes con casi la misma calidad que CRC pero es mucho más fácil de implementar. Algunos detalles aquí . El código puede ser tan simple como esto:
También utilicé un sistema de llamada y respuesta para mensajes críticos, donde la PC enviará un mensaje cada 500 ms aproximadamente hasta que reciba un mensaje OK con una suma de verificación del mensaje original completo como datos (incluida la suma de verificación original).
Este esquema, por supuesto, no es adecuado para ser escrito en una terminal como lo sería su ejemplo. Su protocolo parece bastante bueno por estar limitado a ASCII y estoy seguro de que es más fácil para un proyecto rápido que desea poder leer y enviar mensajes directamente. Para proyectos más grandes, es bueno tener la densidad de un protocolo binario y la seguridad de una suma de verificación.
fuente
Si te gustan los estándares, entonces puedes echar un vistazo a la codificación ASN.1 / BER TLV. ASN.1 es un lenguaje utilizado para describir estructuras de datos, creado específicamente para la comunicación. BER es un método TLV para codificar los datos estructurados utilizando ASN.1. El problema es que la codificación ASN.1 puede ser difícil en el mejor de los casos. La creación de un compilador ASN.1 completo es un proyecto en sí mismo (y particularmente complicado, piense meses ).
Probablemente sea mejor mantener solo la estructura TLV. El TLV consiste básicamente en tres elementos: una etiqueta, una longitud y un campo de valor. La etiqueta define el tipo de datos (cadena de texto, cadena de octeto, entero, etc.) y la longitud, la longitud del valor .
En BER, la T también indica si el valor es un conjunto de estructuras TLV (un nodo construido) o directamente un valor (un nodo primitivo). De esa manera puede crear un árbol en binario, muy parecido a XML (pero sin la sobrecarga de XML).
Ejemplo:
es un entero (etiqueta
02
) con una longitud del valor de 1 (longitud01
) y el valor -1 (valorFF
). En ASN.1 / BER, los enteros son signos de grandes números endianos, pero, por supuesto, puede usar su propio formato.es una secuencia (una lista) con longitud 7 que contiene dos enteros, uno con valor -1 y otro con valor 255. Las dos codificaciones de enteros forman el valor de la secuencia.
También puede simplemente lanzar esto a un decodificador en línea, ¿no es agradable?
También puede usar una longitud indefinida en BER que le permitirá transmitir datos. Sin embargo, en ese caso debes analizar tu árbol correctamente. Consideraría que es un tema avanzado, necesita saber sobre la amplitud primero y el análisis profundo primero, por ejemplo.
El uso de un esquema TLV básicamente le permite pensar en cualquier tipo de estructura de datos y codificarlo. ASN.1 va mucho más allá que eso, al proporcionarle identificadores únicos (OID), opciones (muy parecidas a uniones en C), incluye otras estructuras ASN.1, etc., etc., pero eso puede ser excesivo para su proyecto. Probablemente, las estructuras definidas por ASN.1 más conocidas hoy en día son los certificados utilizados por su navegador.
fuente
Si no, tienes lo básico cubierto. Sus comandos pueden ser creados y leídos por humanos y máquinas, lo cual es una gran ventaja. Puede agregar una suma de verificación para detectar un comando mal formado o uno dañado en tránsito, especialmente si su canal incluye un cable largo o un enlace de radio.
Si necesita fuerza industrial (su dispositivo no debe causar o permitir que alguien salga lastimado o muera; necesita altas velocidades de datos, recuperación de fallas, detección de paquetes faltantes, etc.), busque algunos de los protocolos estándar y prácticas de diseño.
fuente