python - 如何让Python(通过串行连接)发送的数据等待Arduino完成当前任务?

标签 python arduino serial-port

我尝试让我的 Arduino 微 Controller 和我的 Mac 一起通信,并创建了一个功能性串行连接。我的计算机正在向我的 Arduino 发送数据,当我的 Arduino 准备好接收新数据时,它会发送 '1'

我创建了一个 if-else 语句(下面的 Python 脚本),它要么向 Arduino 发送新的数据行,要么等待 Arduino 准备好接收新的数据行数据。

问题是Python脚本第一部分中的ser.read()总是返回'1',这意味着脚本正在发送单独的数据线路速度可能快于 Arduino 连接的步进电机的 react 速度。

在 Arduino 脚本中,您可以看到我在 serialEvent() 函数的第一行发送状态状态,在我的世界中,这应该让 Arduino 在新的“任务”来了。但是,由于某种原因,它不起作用。有人可以帮我吗?

Python 脚本

import os
import time
import serial

# Name of csv file with drawing coordinates
csvFile = "scaled_coordinates.csv"

# Create serial connection
ser = serial.Serial(port='/dev/tty.usbserial-A9005bDh', baudrate=9600)

wd = os.getcwd()
myFile = open(wd + "/coordinates/" + csvFile)

state = '1'

while True: # Exits when there is no more lines to read

    if state == '0': # Wait for Arduino to be ready
        state = ser.read()

    elif state == '1': # Send one more line to Arduino
        line = myFile.readline()
        if not line:
            break
        print line
        ser.write(line)
        #time.sleep(1)

        state = '0' # Wait for Arduino before reading next line

myFile.close

Arduino 循环函数

void loop() {

  serialEvent(); // Call the serial function

  if (coord_complete) {

    // Steps to move from currrent to new point
    target1 = steps(x_current, y_current, x_new, y_new, 1);
    target2 = steps(x_current, y_current, x_new, y_new, 2);

    // Start moving
    stepper1.move(target1);
    stepper2.move(target2);

    // Update current position
    x_current = x_new;
    y_current = y_new;

    // Reset variables
    x_complete = false;
    y_complete = false;
    coord_complete = false;
  }

  // Stay in while loop until steppermotors is done
  while ((stepper1.distanceToGo() != 0) && (stepper2.distanceToGo() != 0)) {
    stepper1.run();
    stepper2.run();
  }
}

Arduino serialEvent 函数

void serialEvent() {

  Serial.write('1'); // Tell Python that Arduino is ready for one more line

  while (Serial.available() && coord_complete == false) {
    char ch = Serial.read(); // Get new character
    Serial.print(ch);

    // If digit; add it to coord_string
    if (isDigit(ch)) {
      coord_string[index++] = ch;

    // Else if ch is ","; then rename to x_new
    } else if (ch == ',') {
      coord_string[index++] = NULL;                   // Finish coord_string
      x_new = atoi(coord_string);                     // Convert to integer
      x_complete = true;                              // Change x_complete to true
      index = 0;                                      // Reset index
      memset(coord_string, 0, sizeof(coord_string));  // Reset coord_string

    // Else if ch is a new line; then rename as y_new
    } else if (ch == ';') {
      //Serial.write('0');
      coord_string[index++] = NULL;
      y_new = atoi(coord_string);
      y_complete = true;
      index = 0;
      memset(coord_string, 0, sizeof(coord_string));
    }

    // Ends while-loop when true
    coord_complete = x_complete * y_complete;
  }
}

编辑

当前的Python代码如下所示:

import os
import time
import serial

# Name of csv file with drawing coordinates
csvGraphic = "Scaled_coordinates.csv"

# Create serial connection
ser = serial.Serial(port='/dev/tty.usbserial-A9005bDh', baudrate=9600)

wd = os.getcwd()
myFile = open(wd + "/graphics/" + csvGraphic)

state = '1'

while True: # Exits when there is no more lines to read

  print "state", state

  if state == '0': # Wait for Arduino to be ready
    state = str(ser.read())

  elif state == '1': # Send one more line to Arduino
    line = myFile.readline()
    if not line:
      ser.close()
      break
    print line
    ser.write(line)
    state = '0' # Wait for Arduino before reading next line

ser.close()
myFile.close

Python 输出如下所示。代码一次性执行,无需等待 Arduino。看起来 state = str(ser.read()) 行读取某种串行缓冲区中的数据。我想解决方案是清除缓冲区。我只是不知道怎么办。

state 1
239,275;

state 0
state 1
1100,275;

state 0
state 1
300,400;

state 0
state 1
200,400;

state 0
state 1
200,300;

state 0
state 1
[Finished in 0.1s]

最佳答案

我想我找到了。您的 SerialEvent() 在您的循环开始时被调用。它所做的第一件事是 write('1') ,这意味着每次执行 loop 时,它都会告诉您的 Python 代码它已准备好接受新指令(即使没有给出任何指令! )并用“1”上的批处理填充缓冲区,您逐一读取

试试这个:

void SerialEvent(){
    if((stepper1.distanceToGo() == 0) && (stepper2.distanceToGo() == 0)){
        Serial.write('1');
    }
    //Rest of the function

而且我认为在循环结束时你想要

while((stepper1.distanceToGo() != 0) || (stepper2.distanceToGo() != 0))

而不是 while((stepper1.distanceToGo() != 0) && (stepper2.distanceToGo() != 0))

关于python - 如何让Python(通过串行连接)发送的数据等待Arduino完成当前任务?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33805986/

相关文章:

ios - 在 iOS 中比较蓝牙发送的 ASCII 字符时出现问题

c++ - QSerialPort 的 readAll() 不包括最后发送的响应

embedded - 简单的串行点对点通信协议(protocol)

python - 如何在 Keras 中记录有关模型预期性能的数据?

python - 如何在matplotlib中制作具有不同y轴的堆叠折线图?

python - 在 Fabric 中切换用户

c - 检查所有 int 数组元素是否等于特定数字的最短代码?

python - 如何找到特定数字的最大索引和最小索引列明智的numpy

c++ - Arduino 串行监视器在传输数据时显示垃圾

java - 将 windows.h HANDLE 返回到 Java JNI