使用 python 在 teensy bord 和系统之间进行串行通信

Serial communication between teensy bord and system using python

我对物联网领域还很陌生。我正在设置一个带有 teensy 的传感器,用于读取其数据并使用串行通信传输到使用 python 的系统,我正在读取数据并将其存储到数据库中。

我面临的问题是,当我使用 arduino 串行监视器 检查我的程序时,我得到了 疯狂的采样速度,例如 10k 读数在 40 毫秒内完成 但是当我尝试使用 python 读取同一个程序时,它甚至没有给我超过每秒 1000 个读数 而且如果没有数据库代码,它也只能 每秒读取 200 个样本 。有什么办法可以提高这个采样率,还是我必须设置任何额外的参数才能通过串行通信?

这是我的 teensy 代码:

int i;

elapsedMillis sinceTest1;

void setup()
{

  Serial.begin(2000000); // USB is always 12 Mbit/sec

  i = 0;

  delay(5000);

  Serial.println("Setup Called"); 

Serial.flush();

}

void loop()
{

  if (i == 0 || i == 500000)
  {

    Serial.println(sinceTest1);

  }

  Serial.println(i);

  //Serial.println(Serial.baud());

  i++;

}

对于python:

import serial
import pymysql
from datetime import datetime
import time
import signal
import sys


class ReadLine:
    def __init__(self, s):
        self.buf = bytearray()
        self.s = s

    def readline(self):
        i = self.buf.find(b"\n")
        if i >= 0:
            r = self.buf[:i+1]
            self.buf = self.buf[i+1:]
            return r
        while True:
            i = max(1, min(2048, self.s.in_waiting))
            data = self.s.read(i)
            i = data.find(b"\n")
            if i >= 0:
                r = self.buf + data[:i+1]
                self.buf[0:] = data[i+1:]
                return r
            else:
                self.buf.extend(data)


ser = serial.Serial(
    port='COM5',\
    baudrate=2000000,\
    #baudrate=9600,\
    #parity=serial.PARITY_NONE,\
    #stopbits=serial.STOPBITS_ONE,\
    #bytesize=serial.EIGHTBITS,\
        #timeout=0
        )

print("connected to: " + ser.portstr)
count=1
#this will store the line
line = []

#database connection
connection = pymysql.connect(host="localhost", user="root", passwd="", database="tempDatabase")
cursor = connection.cursor()


checker = 0

rl = ReadLine(ser)
while True:

   time = datetime.now().strftime('%Y-%m-%d %H:%M:%S')
   print(time)
   print(checker)
   print(rl.readline())


   insert1 = ("INSERT INTO tempinfo(value,test,counter) VALUES('{}','{}','{}');".format(33.5, time,checker)) #.format(data[0])
   insert2 = ("INSERT INTO urlsync(textvalue,sync) VALUES('http://www.myname.com/value.php?&value={}&time={}',0);".format(33.5,time)) #.format(data[0])

   cursor.execute(insert1)
   cursor.execute(insert2)

   connection.commit()
   checker += 1


connection.close()
time = datetime.now().strftime('%Y-%m-%d %H:%M:%S')
print(time )
ser.close()

P.S:每秒 1000 个样本是我在不使用数据库命令时获得的速率,包括它们我每秒仅获得大约 250 个样本。

感谢任何帮助或建议,谢谢。

首先,很好的问题。您面临的问题充满了学习机会。

让我们一一道来:

-您现在可以了解微控制器和计算机之间的区别了。最基本形式的微控制器(如果你是 运行 裸机代码,即使它不是非常有效的代码,比如在 Arduino 上)也只会做一件事,特别是当它与硬件相关时(比如阅读或写入 UART)它会非常有效地完成。另一方面,在台式计算机上,您同时有一层又一层的任务 运行(操作系统后台任务、更新屏幕等等)。这么多事情同时发生,如果你不确定优先顺序,就很难准确预测到底会发生什么以及什么时候发生。因此,不仅 Python 代码是 运行,还会有更多的事情出现并中断用户任务的流程。如果您希望以稳定(或至少可预测)的速度从 UART 缓冲区读取数据,那么您目前使用的架构永远不会发生这种情况。

-即使你设法将你的 OS 精简到最低限度,终止所有进程,在没有任何图形的终端上继续......你仍然必须处理你的不确定性正在执行您自己的 Python 代码(这就是为什么您会看到 Arduino 串行监视器具有更好的性能,它除了从缓冲区中删除数据外什么都不做)。在您的 Python 代码中,您正在依次从端口读取,试图找到一个特定的字符(换行符),然后将您读取的数据附加到列表中。如果你想提高性能,你需要要么只读取数据并将其存储以供离线处理,要么查看 multithreading(如果你的程序有一个线程专用于仅从缓冲区读取并且您在单独的线程上进行进一步处理,您可以显着提高吞吐量,特别是如果您设置了正确的优先级)。

-最后但实际上最重要的是,您应该问自己:我真的需要以 2 Mbps 的速度从传感器读取数据吗?如果答案是肯定的,而且你的传感器不是摄像机,恐怕你需要退后一步,看看以下概念:传感器带宽和动态响应。这样做之后,下一个问题是:您的传感器更新输出的速度有多快,为什么?这个更新率有意义吗?我可以在这里给你一些参考。首先,假设您有一个温度传感器来读取和记录烤箱中的温度。如果烤箱中的温度以每分钟 10 摄氏度甚至每秒 100 度的速度变化,以 1 MHz(每秒 100 万个读数)从传感器采样值是否有意义?您的传感器是否能够如此快速地做出反应(动态响应发挥作用的地方)?我的猜测:可能不会。许多工业设备集成了数十个传感器来控制关键过程并通过 1.5 Mbps link(例如,Profibus 的相当标准)发送所有数据。