Protocole simple de communication point à point en série

j'ai besoin d'un protocole de communication simple entre deux appareils (un PC et un microcontrôleur). Le PC doit envoyer quelques commandes et paramètres au micro. Le micro doit transmettre un tableau d'octets (données de capteur).

les données doivent être noise protected (outre la vérification de parité, je pense que j'ai besoin d'une autre méthode de correction des données).

y a-t-il une solution standard pour faire cela? (J'ai besoin seulement d'une idée, de ne pas le terminer solution.)

P. S. tout conseil est apprécié. P. P. S désolé pour les fautes de grammaire, j'espère que vous comprenez.

Edit 1. Je n'ai pas décidé s'il sera maître/esclave protocole ou les deux parties peuvent initier la communication. Le PC doit savoir quand micro ont fait un travail et peut envoyer des données. Il peut sonder en continu le micro si les données sont prêtes, ou le micro peut envoyer des données, quand un travail est terminé. Je ne sais pas ce qui est mieux et plus simple.

Edition 2. "151990920 Matériel" et couche physique protocole. Depuis RS-232 C série standard utilisé dans le PC, je vais utiliser communication asynchrone . Je n'utiliserai que les signaux RxD, TxD et GND. Je ne peux pas utiliser des fils supplémentaires parce que le le microcontrôleur AFAIK ne les supporte pas. J'utilise la puce AVR ATmega128.

donc je vais utiliser taux fixe de bauds, 8 bits de données, 2 bits d'arrêt sans vérification de parité (ou avec?).

protocole de liaison de données . C'est ce qui me préoccupe le plus dans ma question. Merci d'avoir suggéré HDLC , PPP et les protocoles Modbus . Je recherche sur.

51
demandé sur Vanuan 2009-05-03 02:20:38

12 réponses

j'utiliserais HDLC . J'ai eu de la chance avec elle dans le passé. Je voudrais pour un point à point série juste utiliser le encadrement asynchrone et oublier toutes les autres choses de contrôle car il serait probablement trop.

en plus d'utiliser HDLC pour l'encadrement du paquet. Je formate mon paquet comme suit. C'est ainsi que les options sont passées en utilisant 802.11

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

le total la taille de chaque paquet de commande est len +2

vous définissez alors des commandes comme

#define TRIGGER_SENSOR 0x01
#define SENSOR_RESPONSE 0x02

l'autre avantage est que vous pouvez ajouter de nouvelles commandes et si vous concevez votre analyseur correctement pour ignorer les commandes non définies, alors vous aurez une compatibilité ascendante.

Afin de mettre le paquet serait la suivante.

 // 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

le système va alors surveiller le flux série pour le drapeau 0x7e et quand il est là, vous vérifiez la longueur pour voir si c'est pklen >= 4 et pklen=len+4 et que le crc est valide. Remarque: ne pas compter sur crc pour les petits paquets, vous obtiendrez beaucoup de faux positifs également vérifier la longueur. Si la longueur ou le crc ne correspond pas, réinitialisez la longueur et le crc et commencez par décoder le nouveau cadre. Si c'est une correspondance, alors Copiez le paquet dans un nouveau tampon et passez-le à votre fonction de traitement de commandes. Toujours réinitialiser la longueur et le crc quand un drapeau est reçu.

pour votre fonction de traitement de commandes saisissez le cmd et len puis utilisez un commutateur pour manipuler chaque type de commande. J'exige également qu'un certain événement envoie une réponse de sorte que le système se comporte comme un appel de procédure à distance qui est event driven.

ainsi, par exemple, le capteur peut avoir une minuterie ou répondre à une commande de prendre une lecture. Il formaterait alors un paquet et l'enverrait au PC qui répondrait qu'il a reçu le paquet. Si ce n' alors, le capteur pourrait redémarrer dans un délai d'arrêt.

aussi quand vous faites un transfert de réseau, vous devriez le concevoir comme une pile de réseau comme le modle OSI comme Foredecker points don't forget about the layer stuff . Mon message avec le HDLC est le data link layer et le RPC et la manipulation de commande est la couche Application .

34
répondu Rex Logan 2017-05-23 11:47:05
Les protocoles

RS232 sont délicats. La suggestion d'utiliser HDLC est bonne, mais ce n'est pas la solution dans son ensemble. Il y a d'autres choses que vous devez décider:

  • comment le débit baud entre les deux appareils sera-t-il déterminé? Autobuad? Prédéfinie ou explicitée?
  • allez-vous faire le contrôle de flux dans le Logiciel ou le matériel ou les deux? Note: si vous utilisez le contrôle de flux matériel, alors vous doit s'assurer que le les câbles sont correctement construit.
  • en Parlant de câbles, c'est une énorme douleur avec RS233. En fonction de l'appareil, vous pouvez avoir besoin d'utiliser un câble direct, ou un câble croisé, ou une variante.
  • utilisant un mécanisme de contrôle de flux basé sur un logiciel peut être efficace car il permet le câble le plus simple à utiliser - seulement trois câblés (TX, RX, et commun).
  • choisissez-vous un mot de 7 ou 8 bits?
  • HW parité ou logiciel vérification des erreurs.

je vous suggère d'utiliser 8 bits de données, pas de parité matérielle, 1 bit d'arrêt, et d'utiliser un contrôle de flux basé sur un logiciel. Vous devez utiliser autobaud si votre matériel le supporte. Si ce n'est pas le cas, autobaud est très difficile à faire en logiciel.

10
répondu Foredecker 2009-05-03 19:08:46

Il y a quelques bonnes réponses ici, voici quelques indications utiles:

Même si vos paquets ne sont pas séparées, l'octet de synchronisation est un moyen essentiel de réduire le nombre d'endroits où vous devez vous essayez de construire un paquet. Vos appareils devront souvent faire face à un tas de données indésirables (I. e la fin d'un paquet en vol lorsqu'il est activé, ou le résultat d'une collision matérielle). Sans un octet de synchronisation, vous devez essayer de faire un paquet de chaque octet de vous recevoir. Le byte sync signifie que seulement 1/255 octets de bruit aléatoire pourrait être le premier byte de votre paquet. Aussi fantastique quand vous voulez fouiner sur votre protocole.

avoir une adresse sur vos paquets ou même juste un peu dire maître / esclave ou pc / périphérique est utile lorsque vous regardez les paquets via un outil snoop d'un type ou d'un autre. Vous pouvez faire cela en ayant un byte de synchronisation différent pour le PC que le périphérique. En outre, cela signifiera un l'appareil ne répondra pas à son propre écho.

vous pourriez vouloir regarder dans la correction d'erreur (comme Hamming ). Vous empaquetez 8 bits de données dans un octet protégé de 12 bits. N'importe lequel de ces 12 bits peut être retourné en route et les 8 bits originaux récupérés. Utile pour le stockage de données (utilisé sur CD) ou lorsque l'appareil ne peut pas être réexpédié facilement (liaisons par satellite, rf à Sens Unique).

Les numéros de paquets

facilitent la vie. Un paquet envoyé porte un Nombre, les réponses portent le même numéro et un drapeau indiquant "réponse". Cela signifie que les paquets qui ne sont jamais arrivés (sync corrompu say) sont facilement détectés par l'expéditeur et en mode full-duplex avec un lien lent, deux commandes peuvent être envoyées avant que la première réponse ne soit reçue. Cela rend également l'analyse du protocole plus facile (un tiers peut comprendre quels paquets ont été reçus sans aucune connaissance du protocole sous-jacent)

avoir un seul maître est une simplification impressionnante. Cela dit, dans un environnement full-duplex, cela n'a pas beaucoup d'importance. Il suffit de dire que vous devez toujours le faire à moins que vous ne vouliez économiser de l'énergie ou que vous ne fassiez quelque chose qui se déclenche à la fin de l'appareil (état d'entrée modifié, échantillon prêt).

8
répondu Tom Leys 2017-05-23 11:47:05

ma suggestion est modbus. Il s'agit d'un protocole standard simple et efficace pour la communication avec des appareils qui ont des capteurs et des paramètres (par exemple un PLC). Vous pouvez obtenir les spécifications à http://www.modbus.org . Elle existe depuis 1979 et gagne en popularité, vous n'aurez aucun problème à trouver des exemples et des bibliothèques.

5
répondu Martin Liesén 2009-05-04 21:51:06

j'ai lu cette question il y a quelques mois, ayant exactement le même problème, et je n'ai rien trouvé d'assez efficace pour un micro 8-bit minuscule avec de petites quantités de RAM. Tellement inspiré par CAN et LIN que j'ai construit quelque chose pour faire le travail. Je l'ai appelé MIN (microcontrôleur réseau D'interconnexion) et je l'ai téléchargé sur GitHub ici:

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

il y a là deux implémentations: C embarqué, l'un en Python pour un PC. Plus un petit programme de test" hello world " où le PC envoie des commandes et le firmware allume une LED. J'ai blogué au sujet d'obtenir CE et courant sur une carte Arduino ici:

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

MIN est assez simple. J'ai corrigé la représentation de la couche 0 (8 bits de données, 1 bit d'arrêt, pas de parité) mais j'ai quitté le baud taux d'ouvrir. Chaque cadre commence par trois octets 0xAA qui en binaire est 1010101010, un joli pulsetrain pour faire la détection de vitesse autobaud si une extrémité veut s'adapter dynamiquement à l'autre. Les trames sont de 0 à 15 octets de charge utile, avec un checksum de 16 bits de Fletcher ainsi qu'un byte de contrôle et un identifiant de 8 bits (pour indiquer à l'application ce que contiennent les données de charge utile).

le protocole utilise le remplissage de caractères de sorte que 0xAA 0xAA 0xaa indique toujours le début de l'image. Cela signifie que si un l'appareil sort de reset il se synchronise toujours avec le début du prochain cadre (un objectif de design pour MIN N'a jamais été de laisser passer un cadre incomplet ou incorrect). Cela signifie également qu'il n'est pas nécessaire d'avoir des contraintes de temps spécifiques entre les octets et entre les images. Tous les détails du protocole sont dans le wiki de github repo.

Il y a de la place pour des améliorations futures avec MIN. J'ai laissé quelques crochets là-dedans pour le passage de message de bloc (4 bits du byte de contrôle sont réservés) et pour négociation de haut niveau des capacités (l'identifiant 0xFF est réservé) donc il y a beaucoup de place pour ajouter le support pour les fonctionnalités couramment requises.

5
répondu Ken Tindell 2015-02-18 16:51:00

voici un protocole alternatif:

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

utilisez RS232 / UART, car le PC (port série) et le processeur (UART) peuvent déjà gérer cela avec un minimum de bruit (juste besoin d'un MAX232 puce ou similaire pour faire le changement de niveau).

et en utilisant RS232/UART, vous n'avez pas à vous soucier de maître/esclave si ce n'est pas pertinent. Le contrôle du débit est disponible si nécessaire.

Logiciel proposé pour PC: écrivez la vôtre, ou Docklight pour un suivi et un contrôle simples (la version d'évaluation est gratuite).

pour une plus grande vérification d'erreur, le plus simple est la vérification de parité, ou si vous avez besoin de quelque chose de plus puissant, peut-être codage convolutionnel .

dans tous les cas, quoi que vous fassiez: faites simple!

EDIT: utiliser RS232 avec un PC est encore plus facile que ce qu'il était, comme vous pouvez maintenant obtenir USB À RS232 / TTL convertisseurs. Une extrémité va dans la prise USB de votre PC, et apparaît comme un port série normal; l'autre sort à 5 V ou 3,3 V signaux qui peuvent être connectés directement à votre processeur, sans changement de niveau requis.

nous avons utilisé TTL-232R-3V3 de la puce FDTI, qui fonctionne parfaitement pour ce type d'application.

3
répondu Steve Melnikoff 2009-05-14 17:03:40

ma seule suggestion est si vous avez besoin Insonorisant, vous pourriez vouloir utiliser full-duplex RS-422/485. Vous pouvez utiliser un convertisseur IC similaire à ce du côté AVR, puis un convertisseur RS-232->RS-422 du côté PC comme le 485PTBR ici . Si vous pouvez trouver ou faire un câble blindé (deux paires blindées tordues) alors vous aurez encore plus de protection. Et tout cela est invisible pour le micro et le PC - aucun changement de logiciel.

Quoi que vous fassiez, assurez-vous que vous utilisez un système full-duplex et assurez-vous que les lignes enable read/write sont indiquées sur L'IC.

2
répondu Stephen Friederichs 2009-05-06 02:35:12

vous pouvez jeter un oeil à Telemetry et son implémentation de bureau associée en python Pytelemetry

Caractéristiques principales

c'est un protocole basé sur PubSub , mais à la différence de MQTT c'est un protocole point-à-point, no broker .

comme n'importe quel protocole pubsub, vous pouvez publier d'un se terminer sur un topic et être notifié à l'autre bout sur ce sujet.

du côté intégré, publier sur un sujet est aussi simple que:

publish("someTopic","someMessage")

pour les numéros:

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

cette façon d'envoyer des variables peut sembler limitée, mais la prochaine étape vise à ajouter un sens supplémentaire à l'analyse du sujet en faisant des choses comme ceci:

// 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)

C'est bien si vous avez besoin d'envoyer des tableaux, structures de données complexes, etc.

aussi, le motif PubSub est grand en raison de sa flexibilité. Vous pouvez construire des applications maître/esclave, périphérique à périphérique,etc.

c bibliothèque GitHub version

la bibliothèque C est très simple à ajouter sur tout nouvel appareil tant que vous avez une bibliothèque UART décent sur elle.

il Vous suffit d'instancier une structure de données appelée TM_transport (défini par Telemetry ), et assignez les 4 pointeurs de fonction 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();

pour utiliser la télémétrie, vous avez juste à ajouter le code suivant

// 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",...

bibliothèque Python PyPI version

du côté du bureau, Il y a le module pytelemetry qui implémente le protocole.

si vous connaissez python, le code suivant se connecte à un port série, publie une fois sur le thème foo , imprime tous les sujets reçus pendant 3 secondes puis se termine.

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 vous ne connaissez pas python, vous pouvez utiliser l'interface en ligne de commande

Pytelemetry CLI PyPI version

la ligne de commande peut être lancée avec

pytlm

puis vous pouvez connect , ls (liste) sujets reçus, print données reçues sur un sujet, pub (publier) sur un sujet, ou ouvrir un plot sur un sujet pour afficher des données reçues en temps réel

enter image description here

enter image description here

2
répondu Overdrivr 2016-02-10 08:07:26

en ce qui concerne les contrôles de parité (comme il est venu quelques fois ici):

ils sont pour la plupart inutiles. Si vous craignez qu'un seul bit puisse être modifié par erreur, alors il est très probable qu'un second bit puisse aussi changer et vous obtiendrez un faux positif à partir de la vérification de parité.

utilisez quelque chose de léger comme CRC16 avec une table de recherche - il peut être calculé que chaque octet est reçu et est essentiellement juste un XOR. La suggestion de Steve Melnikoff est idéal pour petits micros.

je suggérerais aussi de transmettre des données lisibles par l'homme, plutôt que des données binaires brutes (si la performance n'est pas votre première priorité). Cela rendra le débogage et la journalisation des fichiers beaucoup plus agréable.

1
répondu Peter Gibson 2009-05-14 12:23:50

vous ne spécifiez pas exactement comment le microcontrôleur se comporte, mais tout ce qui est transmis depuis le micro sera-t-il une réponse directe à une commande du PC? Si c'est le cas, il semble que vous pouvez utiliser un protocole maître/esclave d'une certaine sorte (ce sera typiquement la solution la plus simple). Si les deux parties peuvent initier la communication, vous avez besoin d'un protocole de couche de liaison de données plus général. HDLC est un protocole classique pour cela. Bien que le protocole complet soit probablement exagéré pour vos besoins, vous pourriez par exemple au moins utiliser le même format de cadre. Vous pourriez également avoir un oeil à PPP pour voir s'il y a quelque chose de pièces utiles.

0
répondu hlovdal 2009-05-02 22:59:40

peut-être que cette question peut être complètement stupide, mais quelqu'un a-t-il envisagé l'utilisation de l'un des protocoles X/Y/Z MODEM ?

le principal avantage d'utiliser l'un des protocoles ci-dessus est la grande disponibilité d'implémentations prêtes à l'emploi dans divers environnements de programmation.

0
répondu Chris Ciesielski 2009-05-07 13:25:48

SLIP and UDP. Sérieusement.

tous les PC et appareils similaires le parlent.

il y a un bon livre et des exemples de TCP Lean

Jeremy Bentham a obtenu sournoisement un PIC faisant fonctionner TCP / IP. Un AVR est aussi bon qu'un PIC, Non ?

je recommande UDP à la place, c'est assez facile.

-1
répondu Tim Williscroft 2009-12-01 03:46:52