【问题标题】:How to get Arduino to read serial from Python?如何让 Arduino 从 Python 读取串行?
【发布时间】:2017-12-07 20:50:01
【问题描述】:

具体问题

我正在尝试使用带有 USB 电缆的串口在 Python 脚本和我的 Arduino Pro Mini 之间进行通信。在 Python 中,我可以读取 Arduino 写入的内容,但 Arduino 无法读取 Python 写入的内容,或者它正在以我无法处理的形式读取它。最明显的表现方式是当我尝试将 Arduino 刚刚从 Python 读取的内容写入 Python 时。 Python 中不会显示任何内容。

当我在串行监视器中使用它时,我的 Arduino 草图似乎工作得很好,即它可以读写,所以我怀疑它是 Python 端的东西。这是什么原因造成的?

详情

我希望能够测试将 64 字节长的信息发送到我的 Arduino 的速度。为此,我编写了一个 Python 脚本,它应该能够定期向我的 Arduino 发送各种信息。我可以改变周期,从而测试我能达到什么样的速度。

然而,尽管我的 Arduino 草图与串行监视器配合得很好,即我可以向它发送信息并从中读取信息,但我无法让它与 Python 配合使用。

使用我的 Python 脚本,我可以打开连接并读取 Arduino 写入的内容,但由于某种原因,从 Python 写入存在问题。我尝试了以下方法,但都没有奏效:

  • 使用 Uno 而不是 Pro Mini。
  • Serial.println() 语句放入我的get_data() 函数中。什么都没有打印出来。
  • 发送格式为“T(number);”的字符串并使用sscanf() 提取号码。使用 if 语句检查数字并打开板载 LED。没用。
  • 发送以“T”开头的字符串并使用 if 语句查看它是否存储在 raw_data[] 中。不是。
  • 在不同时间从 Python 写入数据(即使用更长的延迟)。
  • 使用device.write(b"mystring")device.write("mystring".encode()) 从Python 编写

我不知道下一步该尝试什么……

Python (2.7) 代码

import serial, time, random, string

device = serial.Serial('/dev/tty.usbserial-A105YOZX', baudrate = 38400)

initial_time = time.time()
current_time = time.time()

counter = 0
control = 0

while counter < 1000:
    current_time = time.time()
    if current_time - initial_time > 0.1:
        initial_time = current_time
        counter += 1
        device.read()
    if current_time - initial_time > 1 and control == 0:
        device.write(b"Message being sent")
        control = 1

Arduino 代码

#define RAW_LEN 64 //max length of incoming string (buffer size is only 64 bytes)

//variables for incoming data
char raw_data[RAW_LEN];
int raw_data_i = 0; //index

unsigned long my_time;
int control = 0;
int for_print;

int get_data(int i) {
  //fills up raw_data[] with serial data. Clears raw_data if it gets too long
  if (Serial.available()>0) {
    raw_data[i] = Serial.read();
    Serial.println(raw_data[i]);
    //Serial.println(raw_data[i]);
    if (i<RAW_LEN-1){
      i++;
    }
  }
  return i;
}

void clear_data() {
  //clears raw_data and resets raw_data_i
  raw_data_i = 0;
  memset(raw_data,'\0',RAW_LEN-1);
}

//print functions
void raw_print(char data[]) {
  Serial.println("Received data: ");
  //if (raw_data[0] == 'T') {digitalWrite(LED_BUILTIN, HIGH);}
  for (int i=0; i< RAW_LEN;i++) {
    Serial.println(data[i]);
  }
}

void setup() {
  Serial.begin(38400);
  Serial.println("Restart");
  pinMode(LED_BUILTIN, OUTPUT);
  digitalWrite(LED_BUILTIN, LOW);
}

void loop() {
  my_time = millis();
  raw_data_i = get_data(raw_data_i);
  //clear raw_data if it gets full
  if (raw_data_i == RAW_LEN-1) {
    clear_data();
  }

  if (my_time > 5000 && control == 0) {
    Serial.println("Here");
    raw_print(raw_data);
    control = 1;
  }
}

【问题讨论】:

  • raw_data 是一个字符向量,所以从串行读取时将其转换为字符:raw_data[i] = (char)Serial.read()
  • 感谢您的建议。我试过了,它仍然适用于串行监视器,但不适用于 Python……
  • device.read() 应该做什么?
  • 我正在将 Arduino 收到的数据打印回串行端口,因此device.read() 应该读取并打印它。我在复制的代码中犯了一个错误——应该是print device.read()
  • 标记为迁移到 arduino 特定社区。 tks, tg

标签: python-2.7 arduino arduino-uno pyserial


【解决方案1】:

问题出在 Python 代码中。在while 循环中,第一个if 语句在0.1s 后为True,然后在第二个if 语句为True 之前再执行9 次。

这个问题是device.read() 如果没有收到字符就会挂起。因为我没有从 Arduino 发送足够的字符,所以 Python 代码在 device.read() 处暂停,并且从未到达第二个 if 语句。

一个恼人的错误,花了一段时间才弄明白,希望这个问题和答案可以为其他人节省大量的调试时间。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-06-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-10-27
    相关资源
    最近更新 更多