如何提高 PySerial 读取速度

2024-04-26

我目前正在构建一台使用 Arduino Mega2560 作为主控制器的机器。 Arduino 通过串口连接,获取命令,执行它并每 1ms 吐出一堆测量数据。我有一个运行 Python 的 Raspberry Pi,为用户提供一个漂亮的 GUI 来发送命令,并以可读的形式呈现数据。

我面临的问题:Arduino 能够每毫秒吐出 15 个字节的数据(因此只有 15kbyte/s),但我运行的代码只能每 10 毫秒处理大约 15 个字节,因此为 1.5kB/s 。

当我跑步时cat /dev/ttyACM0 > somefile,我很好地看到了所有数据点。

我有以下精简的Python代码

# Reset Arduino by starting serial
microprocBusy = True
serialPort = serial.Serial("/dev/ttyACM0", baudrate=460800, timeout=0)
time.sleep(0.22);
serialPort.setDTR(False);
time.sleep(0.22);
serialPort.setDTR(True);
time.sleep(0.10);

logfile = open(logfilenamePrefix + "_" + datetime.datetime.now().isoformat() + '.txt', 'a')

# Bootloader has some timeout, we need to wait for that
serialPort.flushInput()
while(serialPort.inWaiting() == 0):
    time.sleep(0.05)

# Wait for welcome message
time.sleep(0.1)
logfile.write(serialPort.readline().decode('ascii'))
logfile.flush()

# Send command
serialPort.write((command + '\n').encode('ascii'))

# Now, receive data
while(True):
    incomingData = serialPort.readline().decode('ascii')
    logfile.write(incomingData)
    logfile.flush() 

    if(incomingData[:5] == "FATAL" or incomingData[:6] == "HALTED" or incomingData[:5] == "RESET"):
        break;
    elif(incomingData[:6] == "RESULT"):
            resultData = incomingData;

logfile.flush() 

当我运行这个程序时,前约 350 个数据点出现,然后我看到一些损坏的数据并错过了大约 2000 个数据点,之后我看到了另外 350 个左右的数据点。进程中CPU使用率为100%

出了什么问题? PySerial 是否优化不佳,或者我的代码中是否存在一些错误?我可以跑cat /dev/ttyACM0 > somefile从Python,然后读取该文件,但这并不是一个很好的解决方案,不是吗?

多谢 :)


我意识到这是一个旧线程,但在撰写本文时它已被查看 3000 次,我讨厌有人在这次遭遇中关闭 pySerial。

我认为作者问题最有可能的罪魁祸首是在读取之间进行的隐式解析:

incomingData = serialPort.readline().decode('ascii')

The readline()方法告诉 pyserial 解析到下一行。你也在做一个decode()在您的接收周期的中间。所有这一切都发生在您的直播中。

更好的方法可能如下所示:

waiting = port.in_waiting  # find num of bytes currently waiting in hardware
buffer += [chr(c) for c in port.read(waiting)] # read them, convert to ascii

# ...keep accumulating the buffer for as long as is reasonable...

processSerialData(buffer)  # whatever processing needs to happen, split your
                           # lines, log, or whatever else *after* you get
                           # your data
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何提高 PySerial 读取速度 的相关文章

随机推荐

  • WCF 反序列化的对象属性的空值

    我有一个 WCF Web 服务used工作顺利 它在某处停了下来 我不知道为什么 代码和界面从未改变 web config 也没有改变 至少与 Web 服务部分无关 我有一堂课 DataContract public class QuizS
  • 更改 Qt 中的标签

    我正在尝试制作一个由按钮和标签组成的简单程序 当按下按钮时 它应该将标签文本更改为程序内 QString 变量中的任何内容 到目前为止 这是我的代码 这是我的 widget h 文件 class Widget public QWidget
  • 使用取消嵌套函数插入 - 跳过序列列中的数字

    我正在尝试在插入中使用 unnest 功能 这样做时 序列号会为每个插入跳过一个数字 请帮我解决这个问题 mydb d tab1 Table public tab1 Column Type Modifiers id integer not
  • 我们可以在一个 Android Studio 项目中拥有多个应用程序吗?

    我正在使用 Android Studio 来开发 Android 应用程序 但我听说在 Android Studio 中 最好在一个应用程序中只包含一个应用程序 每个应用程序一个项目 如果这是正确的 那么为许多项目打开许多框架将非常浪费 但
  • 为什么 are.filter(String) 也返回数字? [复制]

    这个问题在这里已经有答案了 我正在做一些小练习来保持我对 js 怪癖的了解 我尝试编写一些简单的过滤器 它返回一个新数组 其中包含某些元素 例如字符串 数字 ecc 当给定数组中也有数字时 我对 arr filter String 产生的结
  • 为什么 SQL 标准允许重复行?

    中的一个核心规则 http en wikipedia org wiki Codd 27s 12 rules对于关系模型来说 元组 行 所需的唯一性是 数据库中的每个单独的标量值must通过指定包含表的名称 包含列的名称和首要的关键包含行的值
  • 实现导航侧栏加载

    我正在尝试在左侧实现一个带有链接列表的导航侧边栏 a 这样 单击每个链接时 对应的 div 将被加载到右侧 当我有一个函数onclick财产在 a 它在浏览器控制台上给我错误 未捕获的引用错误 callFunction 未定义 这是我的实现
  • Git 工作流程和 Gerrit

    我正在尝试使用 Gerrit 实现 git flow 类型的工作流程 但我似乎无法弄清楚最后一块拼图 我的问题有两个先决条件 Gerrit 只会对一个分支执行合并 我不允许将合并提交推送到 Gerrit 更改获得批准后 合并必须由 Gerr
  • 将字符串“true”/“false”转换为布尔值[重复]

    这个问题在这里已经有答案了 我有一个 JavaScript 字符串 其中包含 true or false 我怎样才能将它转换为布尔值而不使用eval功能 var val string true 不区分大小写 const val string
  • 如何升级appium的chromedriver版本?

    尝试在 Chrome 版本 65 上运行 Appium 脚本时出现以下错误 selenium common exceptions WebDriverException 消息 未知错误 调用函数结果缺少 值 会话信息 chrome 65 0
  • 为什么viewDidLoad在swift中完成后没有显示数据? [关闭]

    Closed 这个问题需要调试细节 help minimal reproducible example 目前不接受答案 当我的应用程序启动完成后 UITableViewCell 上应该显示数据 但是 那里什么也没有 所以重新启动应用程序后
  • Eclemma 说 4 个分支中有 1 个未被覆盖,但它是哪个分支?

    有没有一种简单的方法可以告诉我缺少哪个分支 IE 我有一些这样的代码 if x y do stuff 在突出显示的覆盖范围中 Eclipse 中有一个黄点 上面写着 4 个分支中的 1 个缺失 但我想知道哪个分支丢失了 有一个非常简单的解决
  • 每当我尝试使用 Next.js 运行“npm run dev”时,都找不到错误模块

    每当我跑步时npm run dev我收到这个错误 我尝试过删除node modules并使用重新安装它npm install但这没有用 然后我尝试删除两者node modules and package lock json并重新安装它们 这
  • nix 构建守护进程是否保留构建日志?

    有时候跑步的时候nix build and nixos rebuild我发现了易于修复的问题 例如已弃用的警告或冗余导入 并且我认为 有趣 我也许能够在空闲时间解决这个问题 我知道我可以将构建日志重定向到一个文件 但我总是忘记这样做 直到再
  • 如何熟悉代码签名问题?

    每次当我处理代码签名和配置文件时 都会发生奇怪的事情 大多数时候我会收到错误 找不到代码签名身份 如果没有 则会出现 找不到匹配的配置文件 和 没有具有有效签名身份的配置文件 之类的错误 尽管我非常熟悉代码签名和配置背后的理论和事物 但我每
  • 结构体的指针运算

    给定一个包含 1 个 double 和 3 个 int 变量 总共 4 个变量 的结构体定义 如果 p 是指向该结构体的指针 其值为 0x1000 那么 p 的值为多少 这不是作业问题 所以不用担心 我只是想准备考试 但我无法解决这个练习题
  • 使用蓝牙调用应用程序

    我们可以使用蓝牙从一个 Android 设备中调用另一台 Android 设备中的应用程序吗 如果可以的话流程是什么 不 您不能从一个 Android 设备调用另一个应用程序 除非两个应用程序都使用蓝牙权限并进行配置
  • 检测文本中哪个单词被点击

    我正在构建一个 JS 脚本 该脚本在某个时刻能够在给定页面上允许用户单击任何单词并将该单词存储在变量中 我有一个非常丑陋的解决方案 并且涉及使用 jQuery 进行类解析 我首先解析整个 html 将所有内容拆分到每个空间上 并重新附加包含
  • 在 Reshape Cast() 中使用来自 Shiny Widget 的输入

    我试图在我闪亮的网络应用程序中创建一种数据透视表 用户可以在其中选择他们想要相互转换的变量 我发现的问题是 当我尝试将强制转换与 输入 列 一起使用时 我得到以下信息 错误 强制转换公式包含在熔融数据中找不到的变量 输入 列 input c
  • 如何提高 PySerial 读取速度

    我目前正在构建一台使用 Arduino Mega2560 作为主控制器的机器 Arduino 通过串口连接 获取命令 执行它并每 1ms 吐出一堆测量数据 我有一个运行 Python 的 Raspberry Pi 为用户提供一个漂亮的 GU