2017-05-02 2 views
0

J'utilise Pyserial pour écrire des octets dans une connexion. Une des choses que j'ai lutté avec est de savoir comment écrire exactement les bits que je veux. J'ai eu du succès à écrire sur les octets d'une forme de chaînes ascii, telles queÉcriture d'octets

variable = 'h'.encode() 
serial.write(variable) 

Et qui va écrire les morceaux de H avec succès. Cependant, si je fais quelque chose comme ça avec b '\ b001', je n'écrirai pas 001 comme je l'aurais espéré.

Existe-t-il un moyen de le faire afin que je puisse simplement définir des variables en utilisant 1 et 0, puis utiliser la fonction d'écriture.

J'ai aussi essayé de définir comme ceci:

y = 0x13 
out = s.write(y) 

qui, selon la documentation de la fonction d'écriture, la fonction renvoie la quantité d'octets écrits. Quand j'ai exécuté ce code spécifique, il est retourné 19

+0

On ne sait pas ce que vous essayez de faire. Pouvez-vous montrer ce que vous voulez entrer et ce que vous espérez en tirer? –

Répondre

1

Si je comprends bien, vous essayez de trouver un moyen d'envoyer des données binaires en tant qu'objets python bytes, et des données hexadécimales en tant qu'objets python bytes (dans la deuxième partie).

il peut être contre-intuitif, mais la syntaxe pythons b'' ne signifie pas binary, but bytes donc pourquoi b'0010101' ne fonctionne pas comme vous le souhaitez.

Octets accepte les données hexadécimales par octets par défaut. Pour ce faire, vous devez formater les données hexadécimales en b'\xFF\x04'. Par exemple

byte_obj = bytes(b'\xFF\x04') 

Ceci peut ensuite être envoyé sur pyserial. Pour faire un binaire, vous devrez utiliser les méthodes de construction de python int, c'est-à-dire la méthode int(number, base).

Des explications plus détaillées here

mais cela peut essentiellement être fait via

bin_to_int int('01010101', 2) 
byte_obj = bytes([bin_to_int]) #requires array of ints 

Malheureusement, cela ne fonctionne que pour les chaînes binaires de taille 8 bits (et il vous donnera une erreur vous le dire) . Pour contourner ce problème, vous pouvez effectuer les opérations suivantes:

bin_to_int int('0101010101010101', 2) 
# to_bytes takes size in bytes and endianess, which is the order the bytes are placed. 
byte_obj = bin_to_int.to_bytes(2, 'little') 

little endian est least significant byte in smallest address (c.-à-indice 0) grand est opposé

Soyez prudent de la méthode entier binaire plus, je ne suis pas sûr ce que fait python en interne pour convertir un binaire en un entier, mais pour des données binaires arbitrairement grandes, je suspecterais un ralentissement en raison de la façon dont j'aurais implémenter la conversion. Je vais vous donner un exemple de la raison pour laquelle dans la façon dont je le binaire à la conversion d'entier non signé:

bit_string = "101010101..." 
exponent = 0 
decimal_value = 0 
for bit in bit_string: 
    decimal_value += int(bit)**exponent 
    exponent += 1 

Il pourrait ne pas être tout à fait évident au premier abord, mais parce que ints python sont arbitraily dimensionnées éventuellement vous allez obtenir au point où vous ajoutez des entiers très gros, en dehors de la taille arithmétique normale (c.-à-d. supérieure à 64 bits).Cela signifie qu'au fil du temps avec de grandes valeurs binaires (que vous produirez probablement) vous obtiendrez une complexité de temps non linéaire car N augmente la taille en octets des additions et augmente en dehors de 64 bits (et plus de traitement il faut faire l'addition, qui sera O (n_bytes)) au lieu de O (1))

Pour résoudre ce problème, il suffit de faire une fonction qui sépare les valeurs binaires avant de convertir en octets avec eux (comme binary_to_bytes(binary_string))