ventajas punto protocolo protocol multipunto funciones desventajas comunicacion caracteristicas embedded serial-port protocols

embedded - protocolo - punto a multipunto



Protocolo simple de comunicación punto a punto en serie (12)

Necesito un protocolo de comunicación simple entre dos dispositivos (una PC y un microcontrolador). La PC debe enviar algunos comandos y parámetros al micro. El micro debe transmitir una matriz de bytes (datos del sensor).

Los datos deben estar protegidos contra el ruido (además de la verificación de paridad, creo que necesito algún otro método de corrección de datos).

¿Hay alguna solución estándar para hacer esto? (Necesito solo una idea, no la solución completa).

PD. Cualquier consejo es apreciado. PPS Lo siento por cualquier error de gramática, espero que lo entiendas.

Edición 1. No he decidido si será el protocolo maestro / esclavo o ambos lados pueden iniciar la comunicación. La PC debe saber cuándo micro ha hecho un trabajo y puede enviar datos. Puede sondear continuamente el micro si los datos están listos, o el micro puede enviar datos, cuando se realiza un trabajo. No sé cuál es mejor y más simple.

Editar 2. Hardware y protocolo de capa física . Dado que el estándar serie RS-232 C se usa en la PC, usaré comunicación asíncrona . Usaré solo señales RxD, TxD y GND. No puedo usar cables adicionales porque el microcontrolador AFAIK no los admite. Por cierto, estoy usando el chip AVR ATmega128.

De modo que usaré velocidad de transmisión fija, 8 bits de datos, 2 bits de parada sin verificación de paridad (¿o con?).

Protocolo de enlace de datos De eso se trata principalmente mi pregunta. Gracias por sugerir HDLC , PPP y Modbus . Investigaré sobre eso.


Aquí hay algunas buenas respuestas, aquí hay algunos consejos útiles:

Incluso si sus paquetes no están separados por el tiempo, el byte de sincronización es una forma esencial de reducir la cantidad de lugares desde los que debe intentar construir un paquete. Sus dispositivos a menudo tendrán que lidiar con un montón de datos basura (es decir, el final de un paquete en vuelo cuando se activan o como resultado de una colisión de hardware). Sin un byte de sincronización, deberás tratar de crear un paquete con cada byte que recibas. El byte de sincronización significa que solo 1/255 bytes de ruido aleatorio podría ser el primer byte de su paquete. También es FANTÁSTICO cuando quieres husmear en tu protocolo.

Tener una dirección en sus paquetes o incluso un poco diciendo maestro / esclavo o PC / dispositivo es útil cuando mira los paquetes a través de una herramienta de búsqueda de algún tipo u otro. Puede hacer esto teniendo un byte de sincronización diferente para la PC que el DISPOSITIVO. Además, esto significará que un dispositivo no responderá a su propio eco.

Es posible que desee buscar en la corrección de errores (como Hamming ). Usted empaqueta 8 bits de datos en un byte protegido de 12 bits. Cualquiera de esos 12 bits puede voltearse en ruta y recuperarse los 8 bits originales. Útil para el almacenamiento de datos (utilizado en CD) o donde el dispositivo no puede volver a enviarse fácilmente (enlaces por satélite, rf unidireccional).

Los números de paquete hacen la vida más fácil. Un paquete enviado lleva un número, las respuestas llevan el mismo número y una bandera que dice "respuesta". Esto significa que los paquetes que nunca llegaron (por ejemplo, la sincronización corrupta) son detectados fácilmente por el remitente y en el modo dúplex completo con un enlace lento, se pueden enviar dos comandos antes de que se reciba la primera respuesta. Esto también facilita el análisis de protocolos (un tercero puede entender qué paquetes se recibieron sin conocimiento del protocolo subyacente).

Tener un solo maestro es una simplificación impresionante. Dicho esto, en un entorno dúplex completo no importa mucho en absoluto. Basta con decir que siempre debe hacerlo a menos que esté tratando de ahorrar energía o esté haciendo algo impulsado por eventos en el extremo del dispositivo (estado de entrada cambiado, listo para la muestra).


Aquí hay un protocolo alternativo:

u8 Sync // A constant value which always marks the start of a packet u16 Length // Number of bytes in payload u8 Data[Length] // The payload u16 Crc // CRC

Use RS232 / UART, ya que la PC (puerto serie) y el procesador (UART) ya pueden manejar eso con el mínimo esfuerzo (solo necesita un chip MAX232 o similar para hacer el cambio de nivel).

Y al usar RS232 / UART, no tiene que preocuparse por el maestro / esclavo si no es relevante. El control de flujo está disponible si es necesario.

Software de PC sugerido: escriba el suyo o Docklight para una supervisión y control sencillos (la versión de evaluación es gratuita).

Para una mayor verificación de errores, lo más simple es verificar la paridad, o si necesita algo más poderoso, tal vez la codificación convolucional .

En cualquier caso, haga lo que haga: ¡ manténgalo simple!

EDITAR: El uso de RS232 con una PC es aún más fácil de lo que solía ser, ya que ahora puede obtener conversores USB a RS232 / TTL. Un extremo se conecta a la toma USB de su PC y aparece como un puerto serial normal; la otra muestra señales de 5 V o 3.3 V que se pueden conectar directamente a su procesador, sin necesidad de cambiar de nivel.

Hemos utilizado TTL-232R-3V3 de FDTI Chip, que funciona perfectamente para este tipo de aplicaciones.


En cuanto a los controles de paridad (ya que ha aparecido varias veces aquí):

En su mayoría son inútiles. Si te preocupa que un solo bit se modifique por error, entonces es muy probable que un segundo bit también cambie y obtengas un falso positivo de la verificación de paridad.

Use algo ligero como CRC16 con una tabla de búsqueda; se puede calcular a medida que se recibe cada byte y básicamente es solo un XOR. La sugerencia de Steve Melnikoff es genial para micros pequeños.

También sugeriría la transmisión de datos legibles por humanos, en lugar de binarios en bruto (si el rendimiento no es su primera prioridad). Hará que los archivos de depuración y registro sean mucho más agradables.


Leí esta pregunta hace unos meses, teniendo exactamente el mismo problema, y ​​realmente no encontré nada lo suficientemente eficiente para un pequeño micro de 8 bits con pequeñas cantidades de RAM. Así que, inspirado por CAN y LIN, construí algo para hacer el trabajo. Lo llamé MIN (Microcontroller Interconnect Network) y lo he subido a GitHub aquí:

https://github.com/min-protocol/min

Hay dos implementaciones allí: una en C incrustado, una en Python para PC. Además de un pequeño programa de prueba "hello world" donde la PC envía comandos y el firmware enciende un LED. Escribí en mi blog sobre cómo poner esto en funcionamiento en una placa Arduino aquí:

https://kentindell.wordpress.com/2015/02/18/micrcontroller-interconnect-network-min-version-1-0/

MIN es bastante simple. Reparé la representación de la capa 0 (8 bits de datos, 1 bit de parada, sin paridad) pero dejé abierta la velocidad en baudios. Cada cuadro comienza con tres bytes 0xAA que en binario es 1010101010, un buen tren de pulsos para realizar la detección de velocidad de autobaud si un extremo desea adaptarse dinámicamente al otro. Las tramas son 0-15 bytes de carga útil, con una suma de comprobación de Fletcher de 16 bits, así como un byte de control y un identificador de 8 bits (para indicar a la aplicación qué contienen los datos de la carga).

El protocolo utiliza el relleno de caracteres para que 0xAA 0xAA 0xAA siempre indique el inicio de la trama. Esto significa que si un dispositivo sale de restablecimiento, siempre se sincroniza con el inicio del siguiente fotograma (un objetivo de diseño para MIN nunca debe pasar por alto un fotograma incompleto o incorrecto). Esto también significa que no es necesario tener restricciones específicas de tiempo entre bytes e intercuadros. Los detalles completos del protocolo se encuentran en la wiki del repositorio de GitHub.

Hay espacio para mejoras futuras con MIN. He dejado algunos ganchos para pasar mensajes en bloque (4 bits del byte de control están reservados) y para la negociación de capacidades de mayor nivel (el identificador 0xFF está reservado), por lo que hay mucho margen para agregar soporte para la funcionalidad comúnmente requerida.


Los protocolos RS232 son complicados. La sugerencia de usar HDLC es buena, pero no es la solución completa. Hay otras cosas que debe decidir:

  • ¿Cómo se determinará la velocidad en baudios entre los dos dispositivos? Autobuad? Predefinido, o establecer explicate?
  • ¿Harás control de flujo en software o hardware o ambos? Tenga en cuenta que si usa el control de flujo de hardware, entonces debe asegurarse de que los cables estén construidos correctamente.
  • Hablando de cables, esto es un gran dolor con RS233. Dependiendo del dispositivo, es posible que deba utilizar un cable directo, un cable cruzado o una variante.
  • Usar un mecanismo de control de flujo basado en software puede ser efectivo, ya que permite usar el cable más simple: solo tres cables (TX, RX y común).
  • ¿Escoges una palabra de 7 u 8 bits?
  • HW parity o comprobación de errores de software.

Sugiero que vaya con 8 bits de datos, sin paridad de hardware, 1 bit de parada, y use control de flujo basado en software. Debería usar autobaud si su hardware lo admite. Si no, entonces autobaud es endiabladamente difícil de hacer en el software.


Mi única sugerencia es que si necesita resistencia al ruido, es posible que desee utilizar RS-422/485 dúplex completo. Puede usar un IC similar a this en el lado del AVR, luego un convertidor RS-232-> RS-422 en el lado de la PC como el 485PTBR aquí . Si puede encontrar o hacer un cable blindado (dos pares blindados retorcidos), tendrá aún más protección. Y todo esto es invisible para el micro y la PC: no hay cambios de software.

Haga lo que haga, asegúrese de estar utilizando un sistema de dúplex completo y asegúrese de que las líneas de habilitación de lectura / escritura estén confirmadas en el IC.


Mi sugerencia es modbus. Es un protocolo estándar eficiente y fácil para la comunicación con dispositivos que tiene sensores y parámetros (por ejemplo, un PLC). Puede obtener las especificaciones en http://www.modbus.org . Ha existido desde 1979 y está ganando popularidad, no tendrá problemas para encontrar ejemplos y bibliotecas.


No se especifica exactamente cómo se comporta el microcontrolador, pero ¿todo lo transmitido desde el micro será una respuesta directa a un comando desde la PC? Si lo hace, entonces parece que puede usar un protocolo maestro / esclavo de algún tipo (esta será la solución más simple). Si ambas partes pueden iniciar la comunicación, necesita un protocolo de capa de enlace de datos más general. HDLC es un protocolo clásico para esto. Aunque el protocolo completo probablemente sea excesivo para sus necesidades, podría, por ejemplo, usar al menos el mismo formato de marco. También puede echarle un vistazo a PPP para ver si hay partes útiles.


Puede echar un vistazo a la Telemetry y su implementación de escritorio asociada en Pytelemetry Python

Principales características

Es un protocolo basado en PubSub , pero a diferencia de MQTT es un protocolo punto a punto, no es un intermediario .

Como cualquier protocolo pubsub, puede publicar desde un extremo sobre un topic y recibir notificaciones sobre ese tema en el otro extremo.

En el lado incrustado, la publicación de un tema es tan simple como:

publish("someTopic","someMessage")

Para números:

publish_f32("foo",1.23e-4) publish_u32("bar",56789)

Esta forma de enviar variables puede parecer limitada, pero el próximo hito pretende agregar un significado adicional al análisis del tema al hacer cosas como esta:

// Add an indexing meaning to the topic publish("foo:1",45) // foo with index = 1 publish("foo:2",56) // foo with index = 2 // Add a grouping meaning to the topic publish("bar/foo",67) // foo is under group ''bar'' // Combine publish("bar/foo:45",54)

Esto es bueno si necesita enviar matrices, estructuras de datos complejas, etc.

Además, el patrón PubSub es excelente debido a su flexibilidad. Puede construir aplicaciones maestro / esclavo, dispositivo a dispositivo, etc.

Biblioteca C

La biblioteca C es muy simple de agregar en cualquier dispositivo nuevo, siempre y cuando tenga una biblioteca UART decente.

Solo debe instanciar una estructura de datos llamada TM_transport (definida por Telemetry ) y asignarle a los 4 punteros de función read readable write writeable .

// your device''s uart library function signatures (usually you already have them) int32_t read(void * buf, uint32_t sizeToRead); int32_t readable(); int32_t write(void * buf, uint32_t sizeToWrite); int32_t writeable();

Para usar telemetría, solo tiene que agregar el siguiente código

// At the beginning of main function, this is the ONLY code you have to add to support a new device with telemetry TM_transport transport; transport.read = read; transport.write = write; transport.readable = readable; transport.writeable = writeable; // Init telemetry with the transport structure init_telemetry(&transport); // and you''re good to start publishing publish_i32("foobar",...

Biblioteca de Python

En el lado del escritorio, está el módulo de pytelemetry que implementa el protocolo.

Si conoce Python, el siguiente código se conecta a un puerto en serie, publica una vez sobre el tema foo , imprime todos los temas recibidos durante 3 segundos y luego finaliza.

import runner import pytelemetry.pytelemetry as tm import pytelemetry.transports.serialtransport as transports import time transport = transports.SerialTransport() telemetry = tm.pytelemetry(transport) app = runner.Runner(transport,telemetry) def printer(topic, data): print(topic," : ", data) options = dict() options[''port''] = "COM20" options[''baudrate''] = 9600 app.connect(options) telemetry.subscribe(None, printer) telemetry.publish(''bar'',1354,''int32'') time.sleep(3) app.terminate()

Si no conoce Python, puede usar la interfaz de línea de comando

Pytelemetry CLI

La línea de comando se puede iniciar con

pytlm

A continuación, puede connect , ls (enumerar) los temas recibidos, print datos recibidos sobre un tema, pub (publicar) sobre un tema o abrir un plot sobre un tema para mostrar los datos recibidos en tiempo real.


SLIP y UDP. Seriamente.

Todas las PC y dispositivos similares lo hablan.

Hay un buen libro y ejemplos de TCP Lean

Jeremy Bentham ha obtenido a escondidas un PIC haciendo TCP / IP en funcionamiento. Un AVR es tan bueno como un PIC ¿verdad?

En su lugar, recomendaría UDP, es bastante fácil.


Yo usaría HDLC . He tenido buena suerte con eso en el pasado. Quiero un serial de punto a punto solo uso el encuadre asincrónico y me olvido de todos los demás elementos de control, ya que probablemente sea excesivo.

Además de usar HDLC para enmarcar el paquete. Yo formato mi paquete como el siguiente. Así es como se pasan las opciones usando 802.11

U8 cmd; U8 len; u8 payload[len];

El tamaño total de cada paquete de comando es len +2

Luego defines comandos como

#define TRIGGER_SENSOR 0x01 #define SENSOR_RESPONSE 0x02

La otra ventaja es que puede agregar nuevos comandos y si diseña su analizador correctamente para ignorar los comandos no definidos, entonces tendrá cierta compatibilidad con versiones anteriores.

Así que poner todo junto el paquete se vería como el siguiente.

// total packet length minus flags len+4 U8 sflag; //0x7e start of packet end of packet flag from HDLC U8 cmd; //tells the other side what to do. U8 len; // payload length U8 payload[len]; // could be zero len U16 crc; U8 eflag; //end of frame flag

El sistema entonces monitoreará la secuencia en serie para el indicador 0x7e y cuando esté allí, verificará la longitud para ver si es pklen> = 4 y pklen = len + 4 y que el crc es válido. Tenga en cuenta que no confíe solamente en CRC para paquetes pequeños, obtendrá muchos falsos positivos y también comprobará la longitud. Si la longitud o el crc no coinciden, restablece la longitud y el crc y comienza con la decodificación del nuevo marco. Si es una coincidencia, copie el paquete en un nuevo búfer y páselo a su función de procesamiento de comandos. Siempre restablece la longitud y el crc cuando se recibe una bandera.

Para su función de procesamiento de comandos, tome el cmd y len y luego use un interruptor para manejar cada tipo de comando. También requiero que ciertos eventos envíen una respuesta para que el sistema se comporte como una llamada a procedimiento remoto que es impulsada por eventos.

Entonces, por ejemplo, el dispositivo sensor puede tener un temporizador o responder a un comando para tomar una lectura. Luego formatearía un paquete y lo enviaría a la PC y la PC respondería que recibió el paquete. De lo contrario, el dispositivo sensor podría reenviarse en un tiempo de espera excedido.

Además, cuando está haciendo una transferencia de red, debe diseñarla como una pila de red como el modulo OSI ya que los puntos de Foredecker no se olvidan de la capa física . Mi publicación con HDLC es la capa de enlace de datos y el RPC y el manejo de comandos es la capa de aplicación .


tal vez esta pregunta puede ser completamente estúpida, pero ¿alguien ha considerado el uso de uno de los protocolos MODEM X / Y / Z ?

El principal beneficio de utilizar uno de los protocolos anteriores es la gran disponibilidad de implementaciones listas para usar en diversos entornos de programación.