Question

Je construis un petit appareil avec son propre processeur (AVR Mega8) censé se connecter à un PC. En supposant que la connexion physique et le passage d'octets ont été effectués, quel serait le meilleur protocole à utiliser au-dessus de ces octets? L’ordinateur doit pouvoir définir certaines tensions sur le périphérique et en relire certaines autres.

Pour le moment, je pense à un protocole synchrone entièrement basé sur l'hôte: les demandes d'envoi d'ordinateur, le processeur intégré répond. D'autres idées?

Était-ce utile?

La solution

Modbus pourrait être ce que vous recherchez. Il a été conçu pour le type de problème que vous rencontrez. Il existe de nombreux outils / codes et le respect d’une norme pourrait permettre une réutilisation facile par la suite. Il prend également en charge l’ASCII lisible par l’homme, de sorte qu’il est toujours facile à comprendre / à tester.

Voir FreeModBus pour les fenêtres et les sources incorporées.

Autres conseils

Il y a beaucoup à dire sur l'architecture client-serveur et les protocoles synchrones. Simplicité et robustesse, pour commencer. Si la vitesse ne pose pas de problème, vous pouvez envisager un protocole compact lisible par l'homme pour faciliter le débogage. Je pense aux commandes AT modernes du modem: un "réveil". séquence suivie d'une commande set / get, suivie d'un terminateur.

Host -->  [V02?]      // Request voltage #2
AVR  -->  [V02=2.34]  // Reply with voltage #2
Host -->  [V06=3.12]  // Set voltage #6
AVR  -->  [V06=3.15]  // Reply with voltage #6

Chaque côté peut expirer s'il ne voit pas le crochet de fermeture et se resynchroniser sur le prochain crochet ouvert, qui ne peut pas apparaître dans le message lui-même.

En fonction des exigences de vitesse et de fiabilité, vous pouvez coder les commandes sur un ou deux octets et ajouter une somme de contrôle.

C'est toujours une bonne idée de répondre avec la tension réelle , plutôt que de simplement renvoyer la commande, car elle enregistre une opération de lecture ultérieure.

Également utile pour définir les messages d'erreur, au cas où vous auriez besoin de déboguer.

Mon vote est pour le lisible.

Mais si vous passez au binaire, essayez de mettre un octet d’entête au début pour marquer le début d’un paquet. J'ai toujours eu de la malchance avec les protocoles série qui se désynchronisent. L'octet d'en-tête permet au système intégré de se resynchroniser avec le PC. Ajoutez également une somme de contrôle à la fin.

J'ai fait des trucs comme celui-ci avec un simple format binaire

struct PacketHdr
{
  char syncByte1;
  char syncByte2;
  char packetType;
  char bytesToFollow;  //-or- totalPacketSize
};

struct VoltageSet
{ 
   struct PacketHdr;
   int16 channelId;
   int16 voltageLevel; 
   uint16 crc;
};

struct VoltageResponse
{
   struct PacketHdr;
   int16 data[N];  //Num channels are fixed
   uint16 crc;
}

Les octets de synchronisation sont moins critiques dans un protocole synchrone que dans un protocole asynchrone, mais ils sont toujours utiles, en particulier lorsque le système intégré est mis sous tension pour la première fois, et vous ne savez pas si le premier octet obtenu est au milieu de la un message ou pas.

Le type doit être une énumération qui explique comment interpréter le paquet. La taille peut être déduite du type, mais si vous l'envoyez explicitement, le récepteur peut gérer des types inconnus sans s'étouffer. Vous pouvez utiliser la "taille totale du paquet" ou "les octets à suivre"; ce dernier peut rendre le code récepteur un peu plus propre.

Le CRC à la fin ajoute plus d'assurance que vous avez des données valides. Parfois, j'ai vu le CRC dans l'en-tête, ce qui facilite la déclaration de structures, mais sa mise à la fin vous permet d'éviter un dépassement supplémentaire des données lors de l'envoi du message.

L'expéditeur et le destinataire doivent tous deux avoir des délais d'expiration commençant après la réception du premier octet d'un paquet, au cas où un octet serait supprimé. Le côté PC a également besoin d’un délai d’attente pour traiter le cas lorsque le système intégré n’est pas connecté et qu’il n’ya aucune réponse.

Si vous êtes certain que les deux plates-formes utilisent les flottants IEEE-754 (les ordinateurs le font) et ont la même finalité, vous pouvez utiliser des flottants comme type de données. Sinon, il est préférable d’utiliser des entiers, soit des bits bruts A / D, soit une échelle prédéfinie (1 bit = .001V donne une plage de +/- 32,267 V)

Adam Liss fait beaucoup de bons points. L'accent doit être mis sur la simplicité et la robustesse. Les transferts ASCII lisibles par l'homme aident beaucoup lors du débogage. Excellentes suggestions.

Ils sont peut-être excessifs pour vos besoins, mais HDLC et / ou PPP ajoutent le concept de couche de liaison de données et tous les avantages (et coûts) associés à une couche de liaison de données. La gestion des liaisons, le cadrage, les sommes de contrôle, les numéros de séquence, les retransmissions, etc. contribuent tous à assurer des communications robustes, mais ajoutent à la complexité, au traitement et à la taille du code, et peuvent ne pas être nécessaires pour votre application particulière.

Le

bus USB répondra à tous vos besoins. Ce peut être un périphérique USB très simple avec uniquement un canal de commande pour envoyer une demande à votre périphérique ou vous pouvez ajouter un canal d’interruption qui vous permettra d’avertir l’hôte des modifications apportées à votre périphérique. Un certain nombre de contrôleurs usb simples peuvent être utilisés, par exemple Cypress ou Microchip .

Le protocole en haut du transfert concerne vraiment vos besoins. D'après votre description, il semble qu'un simple protocole synchrone suffit amplement. Qu'est-ce qui vous fait errer et chercher une approche supplémentaire? Partagez vos doutes et nous essaierons de vous aider :).

Si je ne m'attendais pas à devoir effectuer des transferts binaires efficaces, je choisirais l'interface de type terminal déjà suggérée.

Si je veux créer un format de paquet binaire, j’ai tendance à utiliser quelque chose de vaguement basé sur le format PPP HDP byte-asnc PPP, qui est extrêmement simple et facile à envoyer,

Les paquets commencent et finissent avec 0x7e Vous échappez à un caractère en le préfixant avec 0x7d et en basculant le bit 5 (c'est-à-dire xor avec 0x20) Donc 0x7e devient 0x7d 0x5e et 0x7d devient 0x7d 0x5d

Chaque fois que vous voyez un 0x7e, si vous avez des données stockées, vous pouvez les traiter.

Je fais habituellement des choses synchrones gérées par l’hôte à moins que j’ai une très bonne raison de faire autrement. C’est une technique qui va du simple point à point RS232 au multiplex RS422 / 485 sans tracas - souvent un bonus.

Comme vous avez peut-être déjà déterminé, à partir de toutes les réponses qui ne vous dirigent pas directement vers un protocole, qu’une approche personnalisée est votre meilleur choix.

Donc, cela m'a fait réfléchir et bien, voici quelques unes de mes pensées -

Etant donné que cette puce a 6 canaux ADC, vous utilisez probablement une communication série Rs-232 (comme dans votre question), et bien sûr l'espace de code limité, définir une structure de commande simple vous aidera, comme le souligne Adam - Vous voudrez peut-être limiter au maximum le traitement des entrées sur la puce; les sons binaires semblent attrayants, mais le compromis est en termes de facilité de développement ET de maintenance (vous devrez peut-être vous ennuyer avec une entrée morte dans 6 mois) - hyperterminal est un puissant outil de débogage - donc, cela m’a amené à réfléchir à la façon de mettre en œuvre une structure de commande simple avec une bonne fiabilité.

Quelques considérations générales -

conserve les commandes de la même taille - facilite le décodage.

Comme le fait remarquer Adam, vous pouvez encadrer les commandes et la somme de contrôle facultative, comme il se doit. (avec de petites commandes, une somme de contrôle XOR / ADD simple est rapide et sans douleur)

Je recommanderais une annonce de démarrage à l'hôte avec la version du microprogramme réinitialisée - par exemple, "BONJOUR; Version du firmware 1.00z " - indiquerait à l'hôte que la cible vient de démarrer et ce qui fonctionne.

Si vous surveillez principalement, vous pouvez envisager un "essai gratuit". mode où la cible parcourrait simplement les lectures analogiques et numériques - bien entendu, cela ne doit pas nécessairement être continu, il peut être espacé de 1, 5, 10 secondes ou simplement sur commande. Votre micro est toujours à l'écoute, l'envoi d'une valeur mise à jour est donc une tâche indépendante.

Terminer chaque ligne de sortie avec un CR (ou un autre caractère) facilite la synchronisation sur l'hôte.

Par exemple, votre micro pourrait simplement sortir les chaînes;

  V0=3.20
  V1=3.21
  V2= ...
  D1=0
  D2=1
  D3=...
  and then start over -- 

De plus, les commandes pourraient être très simples -

? - Lisez toutes les valeurs - il n'y en a pas beaucoup, obtenez-les toutes.

X = 12.34 - Pour définir une valeur, le premier octet est le port, puis la tension et je vous recommande de conserver le signe "&"; et le ". " comme encadrement pour assurer un paquet valide si vous oubliez la somme de contrôle.

Autre possibilité, si vos sorties se situent dans une plage définie, vous pouvez les pré-échelonner. Par exemple, si la sortie ne doit pas être exacte, vous pouvez envoyer quelque chose comme

5=0 
6=9
2=5  

qui désactiverait le port 5, le port 6 au maximum, et le port 2 à la moitié de sa valeur - Avec cette approche, les données ascii et binaires sont à peu près du même pied en ce qui concerne le calcul / décodage des ressources au niveau micro. Pour plus de précision, indiquez 2 octets en sortie, par exemple 2 = 54 - OU, ajoutez une table xref et les valeurs ne doivent même pas être linéaires, l'octet de données constituant un index dans une table de recherche. .

Comme je me plais à dire; simple est généralement préférable, à moins que ce ne soit pas le cas.

J'espère que cela aide un peu.

Avait une autre pensée en relisant; ajout d'un " * " La commande peut demander les données encapsulées avec des balises html. Désormais, votre application hôte peut simplement rediriger la sortie de votre micro vers un navigateur. Wala, prêt pour le navigateur -

:

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top