web-dev-qa-db-fra.com

python à arduino série lire et écrire

J'essaie d'échanger des informations entre du code python et du code arduino . Je veux envoyer deux points de consigne au code arduino périodiquement (par exemple à la minute), lisez-les dans les variables arduino et update. puis envoyez périodiquement les informations d’état d’arduino à python (par exemple, 30 secondes). Finalement, python enverra et extraira des informations d’une base de données mySQL (plus tard dev).

À l'heure actuelle, je ne peux pas obtenir les informations de rebondir de manière fiable. Je n'ai rien trouvé de semblable à cela dans les recherches et tout ce que j'ai essayé de modifier ne fonctionne pas. Voici ce que j'ai de plus proche (et cela ne change pas réellement entre envoyer et recevoir):

Python

#!/usr/bin/python
import serial
import syslog
import time

#The following line is for serial over GPIO
port = '/dev/ttyS0'


ard = serial.Serial(port,9600,timeout=5)

i = 0

while (i < 4):
    # Serial write section

    setTempCar1 = 63
    setTempCar2 = 37
    ard.flush()
    setTemp1 = str(setTempCar1)
    setTemp2 = str(setTempCar2)
    print ("Python value sent: ")
    print (setTemp1)
    ard.write(setTemp1)
    time.sleep(4)

    # Serial read section
    msg = ard.readline()
    print ("Message from arduino: ")
    print (msg)
    i = i + 1
else:
    print "Exiting"
exit()

Arduino:

// Serial test script

int setPoint = 55;
String readString;

void setup()
{

  Serial.begin(9600);  // initialize serial communications at 9600 bps

}

void loop()
{
  while(!Serial.available()) {}
  // serial read section
  while (Serial.available())
  {
    if (Serial.available() >0)
    {
      char c = Serial.read();  //gets one byte from serial buffer
      readString += c; //makes the string readString
    }
  }

  if (readString.length() >0)
  {
    Serial.print("Arduino received: ");  
    Serial.println(readString); //see what was received
  }

  delay(500);

  // serial write section

  char ard_sends = '1';
  Serial.print("Arduino sends: ");
  Serial.println(ard_sends);
  Serial.print("\n");
  Serial.flush();
}

Tout ce que je finis par obtenir, ce sont les mêmes valeurs qui sont répétées (pas ce qui a été réellement envoyé, pas sûr que ce soit un problème de chaîne ou d'octet) et rien dans le script python. Toute aide ou idées sont grandement appréciées. Merci.

EDIT: code modifié à ce que je cours actuellement comme suggéré ci-dessous. Arduino reçoit une communication fine et en série vérifiée par minicom. Mais le script python affiche toujours une ligne vierge après "Message de arduino:".

9
Boombrewer

Vous ne devriez pas fermer le port série en Python entre l'écriture et la lecture. Il se peut que le port soit toujours fermé lorsque l'Arduino réponde, auquel cas les données seront perdues.

while running:  
    # Serial write section
    setTempCar1 = 63
    setTempCar2 = 37
    setTemp1 = str(setTempCar1)
    setTemp2 = str(setTempCar2)
    print ("Python value sent: ")
    print (setTemp1)
    ard.write(setTemp1)
    time.sleep(6) # with the port open, the response will be buffered 
                  # so wait a bit longer for response here

    # Serial read section
    msg = ard.read(ard.inWaiting()) # read everything in the input buffer
    print ("Message from arduino: ")
    print (msg)

La fonction Python Serial.read ne renvoie qu'un seul octet par défaut. Vous devez donc l'appeler en boucle ou attendre que les données soient transmises, puis lire l'intégralité de la mémoire tampon.

Du côté Arduino, vous devriez considérer ce qui se passe dans votre fonction loop quand aucune donnée n’est disponible. 

void loop()
{
  // serial read section
  while (Serial.available()) // this will be skipped if no data present, leading to
                             // the code sitting in the delay function below
  {
    delay(30);  //delay to allow buffer to fill 
    if (Serial.available() >0)
    {
      char c = Serial.read();  //gets one byte from serial buffer
      readString += c; //makes the string readString
    }
  }

Au lieu de cela, attendez au début de la fonction loop que les données arrivent:

void loop()
{
  while (!Serial.available()) {} // wait for data to arrive
  // serial read section
  while (Serial.available())
  {
    // continue as before

EDIT 2

Voici ce que je reçois lors de l'interface avec votre application Arduino à partir de Python:

>>> import serial
>>> s = serial.Serial('/dev/tty.usbmodem1411', 9600, timeout=5)
>>> s.write('2')
1
>>> s.readline()
'Arduino received: 2\r\n'

Cela semble donc fonctionner correctement.

Lors du test de votre script Python, il semble que le problème soit que l’Arduino se réinitialise lorsque vous ouvrez le port série (du moins mon Uno le fait). Vous devez donc attendre quelques secondes pour le démarrer. De plus, vous ne lisez qu'une seule ligne pour la réponse, je l'ai donc corrigée dans le code ci-dessous également:

#!/usr/bin/python
import serial
import syslog
import time

#The following line is for serial over GPIO
port = '/dev/tty.usbmodem1411' # note I'm using Mac OS-X


ard = serial.Serial(port,9600,timeout=5)
time.sleep(2) # wait for Arduino

i = 0

while (i < 4):
    # Serial write section

    setTempCar1 = 63
    setTempCar2 = 37
    ard.flush()
    setTemp1 = str(setTempCar1)
    setTemp2 = str(setTempCar2)
    print ("Python value sent: ")
    print (setTemp1)
    ard.write(setTemp1)
    time.sleep(1) # I shortened this to match the new value in your Arduino code

    # Serial read section
    msg = ard.read(ard.inWaiting()) # read all characters in buffer
    print ("Message from arduino: ")
    print (msg)
    i = i + 1
else:
    print "Exiting"
exit()

Voici la sortie de ce qui précède maintenant:

$ python ardser.py
Python value sent:
63
Message from arduino:
Arduino received: 63
Arduino sends: 1


Python value sent:
63
Message from arduino:
Arduino received: 63
Arduino sends: 1


Python value sent:
63
Message from arduino:
Arduino received: 63
Arduino sends: 1


Python value sent:
63
Message from arduino:
Arduino received: 63
Arduino sends: 1


Exiting
8
Peter Gibson

Vous devez d’abord installer un module appelé Serial. Pour ce faire, accédez au dossier appelez Scripts, situé dans le dossier installé de python. Si vous utilisez la version Python 3, il est normalement situé à l'emplacement ci-dessous,

C:\Python34\Scripts  

Une fois que vous avez ouvert ce dossier, cliquez avec le bouton droit de la souris sur ce dossier avec la touche Maj. Cliquez ensuite sur 'ouvrir la fenêtre de commande ici'. Après cela, cmd apparaîtra. Écrivez le code ci-dessous dans cette fenêtre cmd,

pip install PySerial

et appuyez sur enter.after PySerial le module sera installé. N'oubliez pas d'installer le module, vous devez disposer d'une connexion INTERNET.


après avoir installé avec succès le module, ouvrez python IDLE, notez le code ci-dessous et exécutez-le.

import serial
# "COM11" is the port that your Arduino board is connected.set it to port that your are using        
ser = serial.Serial("COM11", 9600)
while True:
    cc=str(ser.readline())
    print(cc[2:][:-5])   
0
Thushara Madushan