2010-12-01 57 views
0

J'ai fait beaucoup de recherche et de lecture mais je n'ai pas trouvé de réponse claire et précise. Je fais une application python qui communiquera avec un autre via le port série. J'ai utilisé PySerial pour accomplir ceci. Les types de paquets que je veux envoyer sont des informations d'état et des lectures de données. Je propose de former de mes paquets comme suit:Python: Quelle est la meilleure façon d'envoyer des bits d'état et des horodatages avec PySerial

[ Start Byte ][ Length ][ Message ][ End Byte ][ Checksum ] 

Bien que je ne pense pas avoir besoin de l'octet final car une longueur là-dedans. Ai-je raison?

Je pense à façonner la partie « Message » du paquet pour plus d'informations d'état comme ceci:

[ MsgTypeID ][ PacketID ][ Status Bits ][ Timestamp ] 

L'ID de message est ici juste de faire la différence que c'est un paquet d'état plutôt qu'un paquet de données. L'information d'état elle-même est composée de 16 bits, représentant l'état d'un certain nombre de sous-systèmes dans l'application émettrice. Pour certains de ces sous-systèmes, un seul bit fournira suffisamment d'informations ('0' pour dire que le sous-système est off/low/false, '1' pour on/high/true). D'autres nécessiteront 2 ou 3 bits (représentant des états et autres). En prototypant le système, j'ai simplement construit une chaîne concaténant les bits pour former quelque chose comme '1001110101101100' et l'envoyer par le port série, la somme de contrôle étant un modulo 256 des bits d'état.

Je suis assez nouveau pour Python et la communication série, mais je sais que c'est probablement un gaspillage de bande passante. Je sais que PySerial doit envoyer des chaînes mais en représentant chaque bit comme un '0' ou '1' comme ceci utilise une représentation de chaîne complète pour chaque bit. Je me demandais quelle est la meilleure façon d'envoyer ces bits pour réduire la bande passante?

Par exemple, je prendrais chacun 8 bits, les convertir en hexadécimal et envoyer octets hexagonaux concaténés, comme dans:

'10011101' + '01101100' 

représenté comme

'\x9d' + '\x6c' 

ou devrais-je les envoyer en ASCII ? J'ai aussi vu des mentions du module Struct. Devrais-je descendre cette route à la place?

L'autre chose que je me demande est de savoir comment représenter les parties d'horodatage du message.

Toute aide, suggestions que vous pouvez me donner serait grandement appréciée.

Merci beaucoup :)

Répondre

0

Eh bien, évidemment, il a besoin d'un octet par caractère envoyé, donc si vous pouvez encoder vos données en tant que chaîne de caractères ASCII (str en Python 2, bytes en Python 3), qui est le plus efficace .

Le module struct est certainement une bonne idée: il emballe les données Python dans une chaîne (et le déballe à l'autre extrémité). Cela fonctionnera pour vos horodateurs; emballez-les comme n'importe quel type d'int ou long semble approprié (voir la documentation liée pour vos options).

struct ne fait pas de bits individuels, vous devrez donc le faire vous-même.Je l'ai construit un dictionnaire avant de traduire les caractères en groupes de huit valeurs True/False:

Pour Décodage:

pot = [2**x for x in range(8)] # Powers of 2 (bytes with one 1 and seven 0s) 
bitvalues = {} 
for x in range(256): 
    bitvalues[chr(x)] = [(x & y) != 0 for y in pot] 

Pour faire un dictionnaire pour le codage, remplacez la dernière ligne avec:

bitvalues[tuple((x & y) != 0 for y in pot)] = chr(x) 

Si vous souhaitez encoder/décoder de chaînes de 1 et de 0 au lieu, remplacer le bit génération de la liste/tuple avec:

"".join("1" if (x&y) else "0" for y in pot) 
+0

Merci pour votre réponse Thomas. – Jack

+0

@Jack: De rien. Pouvez-vous faire ce que vous essayez de faire? –

+0

Je vais jeter un oeil au module struct. Cependant, je ne suis pas sûr d'avoir compris ce que vous voulez dire. Si j'ai les bits représentés comme '11011001', comment puis-je obtenir la représentation de la chaîne de caractères codée de ce nombre binaire (déjà représenté par une chaîne)? – Jack

0

À quelle fréquence prévoyez-vous d'envoyer ces mises à jour? Si update_frequency * length_of_message est bien inférieur au débit de la connexion série, il y a peu de raisons de s'inquiéter de l'efficacité de l'encodage des données, et vous pourriez même envisager d'étendre les choses à un format plus lisible, en particulier lorsque vous Je commence.

+0

Salut Russell. Je n'ai décrit qu'un type de paquet ici. Cette information d'état ne sera envoyée qu'une fois par seconde. Cependant, il y a aussi des paquets de données que je voudrais envoyer 100 fois/seconde. J'ai besoin d'un débit de données maximum plutôt que de la lisibilité humaine. J'ai donc besoin de transférer autant d'annonces que possible. Merci – Jack