2010-02-24 4 views
4

Je veux envoyer des données à un Arduino via pyserial en Python. Tout ce que je veux faire à l'Arduino est de lire les données de chaîne de longueur variable du port série, et de le réécrire pour que Python puisse le lire. Comme j'ai été incapable de le faire, le code ci-dessous n'a que Python qui envoie un caractère. Voici le code Python:Programme Echo entre Arduino et Python

import serial 
import sys 
import pywapi 
import time 

def main(): 
    ser = serial.Serial(3, 9600, timeout=1) 
    print "Conn established" 
    print "Sending: %s" % "z".__repr__() 
    print ser.write('z'.encode("ascii")) 
    time.sleep(2) 
    print "Received: %s" % ser.read(10).__repr__()   
    ser.close() 

Voici le code Arduino:

void setup(){ 
    analogReference(DEFAULT); 
    Serial.begin(9600); 
} 

void loop(){ 
    if(Serial.available() > 0) 
    Serial.println("x"); 
    while(Serial.available() > 0){ 
    Serial.print(Serial.read(), BYTE); 
    } 
} 

La sortie:

Conn established 
Sending: 'z' 
1 
Received: '' 

Je sais que le code de l'Arduino fonctionne parce qu'il fonctionne lorsque les données sont envoyées depuis le terminal Arduino. Cependant, le moment où j'essaye d'envoyer quelque chose de Python échoue. J'ai lutté avec ça toute la journée. Toute aide serait grandement appréciée.

+0

que signifie "résultats étranges"? C'est peut-être un problème de poignée de main. –

+0

Désolé, des résultats étranges signifient exactement ce que j'ai posté ici, c'est-à-dire rien. – JohnS

+0

Quel est votre système d'exploitation? Windows ou * nix? – Earlz

Répondre

3

Essayez d'augmenter ou de supprimer le délai d'attente et définissez la taille de lecture sur 1. Vous pouvez également augmenter le délai de veille ou même implémenter une simple boucle de lecture.

Quelque chose comme:

try: 
    while True: 
     data = ser.read(1).__repr__() 
     if data: 
      print "Received: %s." % data 
     else: 
      print "Looping." 
except KeyboardInterrupt: 
    print "Done." 
except: 
    raise 
finally: 
    ser.close() 
    print "Closed port." 

Ensuite, il suffit d'utiliser ctrl-c pour l'arrêter.

+0

Pour une raison quelconque, la première lecture revenait toujours ''. Après avoir effectué une seconde lecture à des fins de test, il a commencé à fonctionner (bien que je doive toujours faire une lecture fictive à chaque démarrage du programme python). – JohnS

+0

Peut-être que cela a quelque chose à voir avec "Serial.println (" x ");" dans le code Arduino. L'application Python imprime-t-elle le 'x' que vous envoyez lors de la connexion? Sinon, peut-être que l'application Python récupère le caractère newline qui est envoyé après le 'x'. Ou, si vous définissez toujours un délai d'expiration sur la connexion série Python, la lecture peut expirer. –

3

Je vous recommande de vérifier les deux parties indépendamment, en utilisant un port série séparé et un logiciel de communication série sur le PC.

E.g. Si votre PC possède deux ports série, utilisez un câble null-modem (loopback) pour les connecter. Ou utilisez com0com pour créer une paire de ports série virtuels liés. Exécutez votre logiciel Python sur un port série et un programme terminal (Hyperterminal ou RealTerm) sur l'autre port série. Vérifiez manuellement l'opération du programme Python de cette façon.

Ensuite, connectez votre PC directement à l'Arduino comme d'habitude, et utilisez le logiciel du terminal pour vérifier manuellement le fonctionnement du logiciel Arduino.

Ce processus vous permettra d'affiner le problème. Une fois que vous les avez vérifiés tous les deux, ils devraient bien fonctionner ensemble.

Serial Port Monitor

Une autre méthode que vous pouvez utiliser est un logiciel qui se connecte en série pilote de port du PC, et vous permet de surveiller le trafic sur le port série. J'ai utilisé le logiciel Free Serial Port Monitor de HHD Software dans le passé, et cela a bien fonctionné pour nos objectifs. Il vous permet de surveiller l'un des ports série du PC, et vous montre un journal (hex et texte) des données série passant par le port dans les deux directions.

0

Avez-vous besoin de vider le caractère envoyé de tout tampon série en attente?

Il se peut que votre personnage ne quitte pas réellement le port COM et arrive à l'Arduino. Lorsque vous testez cela avec le terminal Arduino (je suppose que vous voulez dire le terminal d'interface utilisateur dans l'environnement de développement), vous envoyez votre chaîne + un retour chariot, je pense, pas seulement le caractère. (c.-à-d. touchez-vous après avoir tapé 'z' dans votre test?)

Essayez ser.flush() ou envoyez un caractère. De vos tests, l'Arduino fonctionne très bien, c'est le programme python qui ne semble pas envoyer quoi que ce soit.

0

La raison pour laquelle vous devrez peut-être envoyer deux fois est que si vous vous connectez via USB, la première connexion série réinitialisera l'Arduino.