2016-08-15 100 views
0

我在Windows 10上運行pyserial(3.1.1)與Python 2.7有Arduino的納米

更新打開COM端口時,使用睡眠與pyserial - 得到了同樣的問題上是Xubuntu 16運行,以及Windows 。

我通過串行接口通過串口寫入arduino nano。

我正在寫一個簡單的字符串(例如'2+')並讀取arduino中的輸出。如果我保持第一次睡眠。在打開com端口2秒鐘後它會工作。如果我將它更改爲1或刪除它,arduino似乎收到不同的字符/編碼,它不起作用。

理想情況下,我不想任何睡眠,以便它的工作更快。我做錯了什麼,或者有更好的方法來做到這一點,以便我可以刪除睡眠或至少減少它?

Python代碼:

import sys, getopt 
import time 
import serial 
ser = serial.Serial(
    port='COM3', 
    baudrate=9600, 
    parity=serial.PARITY_ODD, 
    stopbits=serial.STOPBITS_TWO, 
    bytesize=serial.SEVENBITS 
) 
time.sleep(1) #change this to 2 and it works 
ser.write('2+') 
out = '' 
time.sleep(1) 
while ser.inWaiting() > 0: 
    out += ser.read(1) 
if out != '': 
    print ">>" + out 
else: 
    print ">> nothing!" 
time.sleep(1) 
ser.close() 

Arduino的代碼(我在用的ASCII字符數了一些小問題,以及 - 我認爲這是個字節的簽署但那是至少我的問題在此刻)

String inString = ""; 
int pinNumber = 0; 

void setup() { 
    // initialize serial communication at 9600 bits per second: 
Serial.begin(9600); 
} 

void loop() { 
    // expected input: 1+ //to change the digital pin to on 
    // expected input: 2- //to change the digital pin to off 
    while (Serial.available() > 0) { 
     //char inChar = char(int(Serial.read())); 
     char inChar = Serial.read(); 
     Serial.println(inChar); 
     if (isDigit(inChar)) { 
      inString += inChar; 
      Serial.println(inString); 
     } 
     else { 
      pinNumber = inString.toInt(); 
      Serial.println(pinNumber); 
      pinMode(pinNumber, OUTPUT); 
     if (inChar == -85) { 
      Serial.println("set high"); 
      digitalWrite(pinNumber, HIGH); 
     } else if (inChar == -83) { 
      Serial.println("set low"); 
      digitalWrite(pinNumber, LOW); 
     } else { 
      Serial.println("NO MATCH!!!"); 
     } 
     inString = ""; 
    } 
} 

}

+0

您是否試過在'ser.write('2 +')'之後在您的python代碼中放置'ser.flush()'? – ChatterOne

+0

感謝您的幫助。我嘗試了ser.flush(),它不會改變任何東西 - 我仍然需要睡眠出於某種原因。 – onemorecupofcoffee

回答

1

你假設,如果有數據,這將是完整的數據。如果在傳輸部分處理串行端口的方式有緩衝,則只能獲得部分數據。

你可以嘗試在你的python代碼中添加一個ser.flush(),但你也應該檢查你收到的數據是否完整。您可以通過確保您的數據以已知字符終止並檢查它來做到這一點。

請記住,您還應該有某種類型的超時,以免在某些讀取循環中卡住。

另一個問題是,您正在閱讀char類型,但根據the documentationSerial.read()實際上會返回int。數據類型爲char,其大小爲1字節,而int的大小爲2字節,所以這可能是爲什麼你會得到奇怪的東西(有一個參考here)。

它也說read將只返回數據的第一個字節。所以,如果你想要第二個字節,你需要讀兩次。

+0

謝謝 - 串行沒有工作,但欣賞與arduino上的serial.read()的幫助和char/int – onemorecupofcoffee

0

我無法找到解決這個睡眠問題的方法。如果至少允許1.5秒,字節只能在arduino上正確接收 - 大概是爲了串行連接初始化。

作爲一種解決方法,我必須在啓動時打開一次串口,然後通過套接字服務器接受和寫入數據。這按預期工作。這似乎是串口打開的問題。

import os, os.path 
import time 
import serial 
import socket 
import re 

def sendData(msg): 
    if not ser.is_open: 
     ser.open() 
    ser.write(msg) 
    ser.flush() 
    out = '' 
    time.sleep(0.5) 
    while ser.inWaiting() > 0: 
     out += ser.read(1) 
    if out != '': 
     print ">>" + out 
    else: 
     print ">> nothing!" 
    time.sleep(0.5) 

port='/dev/ttyUSB1', 

serversocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 
serversocket.bind(('localhost', 9000)) 
serversocket.listen(1) # become a server socket, maximum 5 connections 

ser = serial.Serial(
    port=port, 
    baudrate=9600, 
    parity=serial.PARITY_ODD, 
    stopbits=serial.STOPBITS_TWO, 
    bytesize=serial.SEVENBITS 
) 

while True: 
    connection, address = serversocket.accept() 
    buf = connection.recv(64) 
    if len(buf) > 0: 
     print buf 
     sendData(buf) 
1

打開串行連接時,您的Arduino是否可以自動重置?

在Arduino Nano中,RESET引腳通過C4連接到FTDI USB到串行轉換器的DTR。見Arduino Nano Schematic

也許如果你刪除C4或禁用DTR,你的問題就會消失。

你可以通過在setup函數中加入一個短的LED脈衝來檢查這一點,看看它是否在你的Python程序打開串口後發生。