2015-10-01 87 views
1

我實現了一個簡單的CmdMessenger示例,允許Arduino通過串口與PC通信。通過CmdMessenger與Arduino和Python通信,無法正常工作

該程序旨在偵聽串行等待命令'0;'。當輸入此命令時,Arduino將讀取一個溫度傳感器並將溫度結果寫入串行。

它從串口監視器工作很好,但我不能用PYthon使用pySerial。我認爲我在python實現中做了一些錯誤,下面是代碼片段: EDiTED:如果我以調試模式運行(在PyCharm上),下面的代碼按預期運行。我在這條線上開始了一個斷點:

if (not self.serialConnection.isOpen()): ... 

並從那裏運行'恢復程序',它的工作原理。我不知道爲什麼它不能在「正常模式」下運行。

import serial 
import time 

class Temperature: 
    def __init__(self, comPath='/dev/ttyACM0', bauds=115200): 
     self.serialConnection = serial.Serial(comPath, bauds, parity=serial.PARITY_ODD, stopbits=serial.STOPBITS_TWO, 
               bytesize=serial.SEVENBITS) 

    def queryTemperature(self): 
     if (not self.serialConnection.isOpen()): 
      self.serialConnection.open() 

     # prints True: 
     print self.serialConnection.isOpen() 
     self.serialConnection.write("0;\n") 
     time.sleep(2) 
     while self.serialConnection.inWaiting() == 0: 
      pass 
     # don't reach this point. It stops on loop above 
     time.sleep(2) 
     iw = self.serialConnection.inWaiting() 
     temp = (self.serialConnection.read(iw)) 
     self.serialConnection.close() 
     return temp 

和方法queryTemperature的呼喚:

from temp_read import * 
dObject = Temperature('COM3') 
print dObject.queryTemperature(); 

程序沒有完成。它似乎停止環路:

 while self.serialConnection.inWaiting() == 0: 
      pass 

波紋管是Arduino的草圖:

#include <CmdMessenger.h> 
#include <OneWire.h> 
#include <DallasTemperature.h> 

int pinTemp = 13; 

CmdMessenger cmdMessenger = CmdMessenger (Serial); 
OneWire oneWire (pinTemp); 
DallasTemperature sensors (&oneWire); 


enum { 
    kReadTemperature, 
    kStatus, 
}; 

void attachCommandCallbacks(){ 
    cmdMessenger.attach (onUnknownCommand); 
    cmdMessenger.attach (kReadTemperature, onReadTemperature); 
} 

void onStatus(){ 
    Serial.println ("status"); 

} 

void onUnknownCommand(){ 
    Serial.println ("unknow"); 
} 

void onReadTemperature(){ 
    Serial.println ("readTemp"); 
    sensors.requestTemperatures(); 
    delay (1500); 
    float temp = sensors.getTempCByIndex(0);   
    cmdMessenger.sendCmd(kStatus, (float) temp); 

} 

void setup() { 
Serial.begin(115200); 
sensors.begin(); 
cmdMessenger.printLfCr(); 
    attachCommandCallbacks(); 


} 

void loop() { 
    cmdMessenger.feedinSerialData(); 


} 
+0

我發現在等待中會有些不可靠......也許會增加一個睡眠而不是通過....或者讀取,直到您得到一些指示消息結束的字符...還發現了與arduino一樣的字符它有助於睡眠幾秒鐘後打開串行連接.... –

+0

此代碼不打印任何東西:time.sleep(3) r = self.serialConnection.readline() print r – alexpfx

+0

您不應該需要在py2中的字節作爲字符串足夠了......嘗試用「\ n」代替你的換行符「\ r」......嘗試讀取單個字節而不是行......如果所有其他的都不行,你可以在發送之前儘量打印你的cmd, /或設置免費串口監視器來觀察串口通信 –

回答

3

它不使用你的代碼,但要實現相同的功能,我寫了一個強大的Python接口CmdMessenger(https://github.com/harmsm/PyCmdMessenger)。你可以使用它通過做這個任務:

import PyCmdMessenger 

# set up serial connection at proper baud rate 
a = PyCmdMessenger.ArduinoBoard('/dev/ttyACM0',baud_rate=115200) 

# list of commands at top of sketch, with argument formats 
commands = [["kReadTemperature","f"], 
      ["kSendTemperature","f"], 
      ["kStatus","s"]] 

cmd = PyCmdMessenger.CmdMessenger(a,commands) 
cmd.send("kReadTemperature") 
print(cmd.receive()) 

到您的Arduino草圖的變化是增加kSendTemperature你的初始命令枚舉:

enum { 
     kReadTemperature, 
     kSendTemperature, 
     kStatus, 
}; 

免去您發送命令,以便它發出的持股量一個二進制字符串:

//cmdMessenger.sendCmd(kStatus, (float) temp); 
cmdMessenger.sendBinCmd(kSendTemperature, (float) temp); 

並刪除多餘的Serial.Println(XXX)命令。