Python(与Arduino通信)在'if'-loop的第一行之后中断

时间:2016-12-20 07:53:57

标签: python-2.7 if-statement serial-port arduino-uno

目前我正在将Arduino与Python结合使用。我现在正在编写Python代码,由于一个未知的原因,它在if-loop中途中断。我认为原因可能是串行通信......我会尝试用我的代码来解释它。

为了便于阅读:感兴趣的代码部分位于'====='的行之间。我把剩下的代码放在上下文中。

Arduino代码

const int mPin      = 2;  // Pin attached to the Mark button
const int cPin      = 3;  // Pin attached to the Capture button
const int qPin      = 4;  // Pin attached to the Quit button
const int solAPin   = 6;  // Solenoid logic pin A - RELEASE PIN
const int solBPin   = 7;  // Solenoid logic pin B - CLOSE PIN
const int ledPin    = 13; // Onboard LED

boolean lastmButton  = 0;
boolean currmButton  = 0; 
boolean lastcButton  = 0;  
boolean currcButton  = 0;  
boolean lastqButton  = 0; 
boolean currqButton  = 0; 

void setup() {
  // Initial code, run at startup
  pinMode(mPin, INPUT); // Reads button press
  pinMode(cPin, INPUT); // Reads button press
  pinMode(qPin, INPUT); // Reads button press
  pinMode(solAPin, OUTPUT);
  pinMode(solBPin, OUTPUT);
  pinMode(ledPin, OUTPUT);

  digitalWrite(solAPin, LOW);
  digitalWrite(solBPin, LOW);
  digitalWrite(ledPin, LOW);

  Serial.begin(9600); // Open Python communication line
}

boolean debounce(boolean last, int Pin) {
  boolean current = digitalRead(Pin);
  if (last != current)
  {
    delay(5);
    current = digitalRead(Pin);
  }
  return current;
}

void loop() {
  // Main code, continious loop
  currmButton = debounce(lastmButton, mPin);
  currcButton = debounce(lastcButton, cPin);
  currqButton = debounce(lastqButton, qPin);
  // ===========================================================
  if (currmButton == HIGH && lastmButton == LOW) {
    mark();
  }
  if (currcButton == HIGH && lastcButton == LOW) {
    Serial.print("C");
  }
  if (currqButton == HIGH && lastqButton == LOW) {
    Serial.print("Q");
  }
  lastmButton = currmButton;
  lastcButton = currcButton;
  lastqButton = currqButton;
}
//==============================================================

void mark() {
  digitalWrite(solBPin, HIGH); // Close Pin, pencil moves down
  delay(300);
  digitalWrite(solBPin, LOW);
  digitalWrite(solAPin, HIGH);  // Release Pin
  delay(100);
  digitalWrite(solAPin, LOW);   // Neutral
  Serial.print("M");
}

debounce-code不是最佳的,但它现在有效。如你看到的;当按下M / C / Q按钮时,Arduino将M / C / Q写入Python。一切正常。

现在出现问题:

Python代码

if (__name__ == '__main__' and fail == False):
# Create directory
    print("Startup")   
    index = 1   # Image counter
    if os.path.exists(image_path) == False:
        os.makedirs(image_path)

# Find the Arduino Port
    try:
        portname = ""
        ports = list(serial.tools.list_ports.comports())
        for p in ports:
            if "Arduino" in p[1]:
                portname = p[0]
                break
        print("Arduino found on " + portname)
    except:
        print("Setup failed:\n  Arduino not found")
        fail = True

# Open Arduino serial communication           
    try:    
        arduino = serial.Serial(portname, baudrate=9600, timeout=1)    
        arduino.close()
        arduino.open()
        print("Arduino Connected")
    except serial.SerialException:
        print("Setup failed:\n  Could not connect to Arduino")
        fail = True

# Find and open the camera stream
    try:
        for i in range (10):
            cap = cv2.VideoCapture(i)
            if (cap.read()):
                if cap.isOpened() == False:
                    cap.open()
                break
        print("Camera Connected\n")
    except:
        print("Setup failed:\n  Camera not found")
        fail = True


#%%# MAIN LOOP
#====================================================================

    while True:

        k = arduino.readline()
        if   k == 'M': # Mark & capture
            print('Arduino: Marked')
            print ("Python Captured\n")
        elif k == 'C':# Capture
            print "Arduino: Python, capture this dot please" # This line is executed when K == C (button pressed on Arduino)
            print "Python: Captured!\n" # This line is not executed directly afterwards, but appears together with the line above when the button is pressed for the SECOND time!

        elif k == 'Q': # Quit 
            print "Arduino: Quit the program"                
            break
#=====================================================================

运行Python代码时,会设置Arduino连接。当按下其中一个按钮时,Arduino会向Python发送正确的信号,到目前为止一切都很好。但是:只执行if循环的第一行。第二次按下按钮时会执行剩余的行,然后再次按下第一行(因为第二次按下该按钮)。

例如,运行代码并按两次“C”会导致以下控制台输出:

Startup
Arduino found on COM4
Arduino Connected
Camera Connected
[button C is pressed for first time]

Arduino: Python, capture this dot please
[buttong C is pressed for second time]
Python: Captured!

Arduino: Python, capture this dot please

到目前为止我尝试过:

  • 在Arduino代码中放置延迟
  • 在Arduino代码中放置'Serial.flush()'
  • 调整信息的打印方式,不同的引号/括号等。

所以这就是我被困住的地方,我真的不知道在哪里寻找这个bug。如果需要任何额外信息,我很乐意提供。我希望有人可以帮助我!

修改

正如我在评论中提到的,在while循环中放置一个print-command会神奇地解决问题:

k = arduino.readline()
print k
if   k == 'M': # Mark & capture

但为什么这个问题解决了我的问题仍然不清楚。

提前致谢, 斯泰恩

0 个答案:

没有答案