web-dev-qa-db-ger.com

python zu Arduino serielles Lesen und Schreiben

Ich versuche, Informationen zwischen Python-Code und Arduino-Code hin und her zu pingen. Ich möchte regelmäßig zwei Sollwerte an den Arduino-Code senden (z. B. auf der Minute), sie auf Arduino- und Update-Variablen lesen Senden Sie dann in regelmäßigen Abständen Statusinformationen von Arduino an Python zurück (z. B. auf der: 30 Sekunden). Eventuell sendet und holt Python Informationen aus einer mySQL-Datenbank (später dev).

Im Moment kann ich nicht die Informationen erhalten, um zuverlässig hin und her zu springen. Ich habe bei den Suchvorgängen nichts in der Nähe gefunden und alles, was ich ändern wollte, funktioniert nicht. Das nächste, was ich habe, ist Folgendes (und es wechselt nicht wirklich zwischen Senden und Empfangen):

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();
}

Am Ende bekomme ich immer die gleichen Werte (nicht das, was tatsächlich gesendet wurde, nicht sicher, ob es sich um ein Zeichenfolgen- oder Byte-Problem handelt) und nichts zurück zum Python-Skript. Jede Hilfe oder Idee wird sehr geschätzt. Vielen Dank.

BEARBEITEN: Modifizierter Code für das, was ich derzeit wie unten beschrieben ausführte. Arduino erhält eine feine und serielle Kommunikation, die von minicom bestätigt wurde. Das Python-Skript druckt jedoch immer noch eine leere Zeile nach "Message from arduino:".

9
Boombrewer

Sie sollten die serielle Schnittstelle in Python nicht zwischen Schreiben und Lesen schließen. Es besteht die Möglichkeit, dass der Port immer noch geschlossen ist, wenn der Arduino antwortet. In diesem Fall gehen die Daten verloren.

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)

Die Python-Funktion Serial.read gibt standardmäßig nur ein einzelnes Byte zurück. Sie müssen es also entweder in einer Schleife aufrufen oder auf die Übertragung der Daten warten und dann den gesamten Puffer lesen.

Auf der Arduino-Seite sollten Sie berücksichtigen, was in Ihrer loop-Funktion passiert, wenn keine Daten verfügbar sind. 

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
    }
  }

Warten Sie stattdessen am Anfang der loop-Funktion, bis die Daten ankommen:

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

EDIT 2

Folgendes bekomme ich, wenn ich mit Ihrer Arduino-App von Python aus arbeite:

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

Das scheint also gut zu funktionieren.

Beim Testen Ihres Python-Skripts scheint das Problem darin zu liegen, dass das Arduino zurückgesetzt wird, wenn Sie die serielle Schnittstelle öffnen (zumindest bei meinem Uno). Sie müssen also einige Sekunden warten, bis es startet. Sie lesen auch nur eine einzige Zeile für die Antwort, daher habe ich das auch im folgenden Code behoben:

#!/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()

Hier ist jetzt die Ausgabe des obigen:

$ 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

Zuerst muss ein Modul Call Serial installiert werden. Gehen Sie dazu in den Ordner callscripts, der sich im installierten Python-Ordner befindet. Wenn Sie die Python 3-Version verwenden, befindet sich diese normalerweise am folgenden Ort.

C:\Python34\Scripts  

Wenn Sie diesen Ordner öffnen, klicken Sie mit der Umschalttaste mit der rechten Maustaste auf den Ordner. Klicken Sie dann auf 'Befehlsfenster hier öffnen'. Danach wird cmd angezeigt. Schreiben Sie den folgenden Code in dieses cmd-Fenster.

pip install PySerial

und drücken Sie die Eingabetaste PySerial Modul wird installiert. Denken Sie daran, das Modul zu installieren. Sie müssen über eine INTERNET-Verbindung verfügen.


nachdem Sie das Modul erfolgreich installiert haben, öffnen Sie Python IDLE und notieren Sie den untenstehenden Code, und führen Sie ihn aus.

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