pyserial - Comment lire la dernière ligne envoyé à partir d'un périphérique série
J'ai un Arduino connecté à mon ordinateur qui exécute une boucle, l'envoi d'une valeur sur le port série à l'ordinateur tous les 100 mme.
Je veux faire un script en Python qui va lire le port série à seulement quelques secondes, donc je veux juste voir la dernière chose envoyés à partir de l'Arduino.
Comment faites-vous cela dans Pyserial?
Voici le code que j'ai essayé qui ne fonctionne pas. Il lit les lignes de manière séquentielle.
import serial
import time
ser = serial.Serial('com4',9600,timeout=1)
while 1:
time.sleep(10)
print ser.readline() #How do I get the most recent line sent from the device?
Vous devez vous connecter pour publier un commentaire.
Je suis peut-être un malentendu à votre question, mais comme c'est une ligne série, vous aurez à lire tout envoyé à partir de l'Arduino de façon séquentielle - il va être mis en mémoire tampon dans l'Arduino avant de l'avoir lu.
Si vous voulez avoir un affichage de l'état qui montre la dernière chose envoyés utiliser un thread qui intègre le code dans votre question (moins la veille), et de garder la dernière ligne complète de lire la dernière ligne de l'Arduino.
Mise à jour:
mtasic
à l'exemple de code est assez bonne, mais si l'Arduino a envoyé une commande partielle quandinWaiting()
est appelé, vous obtiendrez un tronc de ligne. Au lieu de cela, ce que vous voulez faire est de mettre la dernière complète ligne enlast_received
, et de garder la partielle de la ligne dansbuffer
de sorte qu'il peut être ajouté à la prochaine ronde de la boucle. Quelque chose comme ceci:Concernant l'utilisation de
readline()
: Voici ce que le Pyserial documentation a à dire (légèrement modifié pour plus de clarté et avec une mention à readlines()):qui semble tout à fait raisonnable pour moi!
mtasic
le code semble bon en dehors de ce que je pense que c'est un petit problème.Ces solutions de porc de la CPU lors de l'attente pour les personnages.
Vous devez faire au moins un appel de blocage à lire(1)
...et de faire la split chose qu'avant.
Vous pouvez utiliser
ser.flushInput()
à débusquer toutes les données série qui est actuellement dans la mémoire tampon.Après l'effacement de l'ancien données, vous pouvez l'utilisateur ser.readline() pour obtenir les données les plus récentes de la série de l'appareil.
Je pense que c'est un peu plus simple que les autres solutions proposées ici. A travaillé pour moi, j'espère que c'est approprié pour vous.
Cette méthode permet de contrôler séparément le délai d'attente pour la collecte de toutes les données de chaque ligne, et d'un autre délai d'attente sur les lignes supplémentaires.
Vous aurez besoin d'une boucle pour lire tout envoyé, avec le dernier appel à readline() de blocage jusqu'à ce que le délai d'attente. Donc:
Légère modification à mtasic & Vinay Sajip code:
Alors que j'ai trouvé ce code très utile pour moi pour une application similaire, j'avais besoin d' tous les lignes de la série de l'appareil qui permettrait d'envoyer des informations périodiquement.
J'ai opté pour de la pop, le premier élément à partir du haut, de l'enregistrer, puis de rejoindre le reste des éléments comme le nouveau tampon et continuer à partir de là.
Je me rends compte que c'est pas ce que Greg l'a cherché, mais je pensais que c'était le partage de la valeur comme une note de côté.
À l'aide de
.inWaiting()
à l'intérieur d'une boucle infinie peut être problématique. Il peut porc de l'ensemble de la CPU en fonction de la mise en œuvre. Au lieu de cela, je vous conseille d'utiliser une taille spécifique de la lecture des données. Dans ce cas, les éléments suivants doivent être fait par exemple:Trop de complications
Quelle est la raison pour diviser les octets de l'objet par un saut de ligne ou par d'autres de la matrice de manipulations?
J'écris la méthode la plus simple, qui permettra de résoudre votre problème:
Voici un exemple d'utilisation d'un wrapper qui permet de lire les plus récentes ligne sans CPU à 100%