python - teensy bord 与系统之间使用 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++;
}
对于蟒蛇:
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()
PS:每秒 1000 个样本是我在不使用数据库命令时获得的速率,包括它们,我每秒只能获得大约 250 个样本。
任何帮助或建议表示赞赏,谢谢。
解决方案
首先,很好的问题。您面临的问题充满了学习机会。
让我们一一来:
-您现在可以了解微控制器和计算机之间的区别。最基本形式的微控制器(如果您正在运行裸机代码,即使它不是非常有效的代码,例如在 Arduino 上)只会做一件事,特别是当它与硬件相关时(例如读取或写入 UART ) 它会非常有效地做到这一点。另一方面,在台式计算机上,您有一层又一层的任务同时运行(操作系统后台任务、更新屏幕等等)。有这么多事情同时发生,如果你没有确定优先级,就很难准确预测什么时候会发生什么。所以运行的不仅是你的 Python 代码,将会有更多的事情出现并打断您的用户任务流程。如果您希望以稳定(或至少可预测)的速度从 UART 缓冲区读取数据,那么您目前使用的架构永远不会发生这种情况。
- 即使您设法将您的操作系统精简到最低限度,杀死所有进程,在没有任何图形的终端上运行......您仍然必须处理您在自己的 Python 代码上所做的不确定性(那就是为什么您看到 Arduino 串行监视器的性能更好,除了从缓冲区中删除数据之外,它没有做任何事情)。在您的 Python 代码中,您按顺序从端口读取数据,尝试查找特定字符(换行符),然后将读取的数据附加到列表中。如果你想提高性能,你要么只读取数据并将其存储以供离线处理,要么查看多线程(如果您的程序有一个线程专门用于仅从缓冲区读取,并且您在单独的线程上进行进一步处理,您可以显着提高吞吐量,特别是如果您设置了正确的优先级)。
-最后,但实际上,最重要的是,您应该问自己:我真的需要以 2 Mbps 的速度从传感器读取数据吗?如果答案是肯定的,而且你的传感器不是摄像机,恐怕你需要退后一步,看看以下概念:传感器带宽和动态响应. 在你这样做之后,下一个问题是:你的传感器更新其输出的速度有多快,为什么?这个更新率有意义吗?我可以在这里给你几个参考。首先,假设您有一个温度传感器来读取和记录烤箱中的温度。如果烤箱中的温度以每分钟 10 摄氏度甚至每秒 100 度的速度变化,那么以 1 MHz(每秒 100 万次读数)从传感器采样值是否有意义?您的传感器甚至能够做出如此快速的反应(以至于它的动态响应发挥作用)?我的猜测:可能不会。许多工业设备集成了数十个传感器来控制关键过程并通过 1.5 Mbps 链路发送所有数据(例如,Profibus 的相当标准)。
推荐阅读
- ios - iOS HERE SDK NMAKit 私有 API 使用
- maven - 无论如何要在 github 操作工作流中签署 maven 包吗?
- excel - 使用 VBA 和 IBM Lotus Notes 发送电子邮件
- regex - 正则表达式 (0*1*)* 和 (0 + 1)* 是否相同?
- splunk - 从请求正文 splunk 中提取所有出现的相同字段
- apache-spark - 在 RDD 的过滤器转换中没有得到预期的结果
- vba - MS 访问错误 91 对象变量或未在第 0 行设置块变量
- flutter - Flutter 和 Firestore:调试使用
- java - 在 Android 5.1.1 上膨胀类 androidx.appcompat.widget.SearchView 时出错
- sql - 在 SQL 表中搜索字符串 (Visual Studio C#)