我对物联网领域还很陌生。我正在设置一个带有Teensy的传感器,以读取其数据并通过串行通信传输到使用python的系统,我正在读取数据并将其存储到数据库中。
我面临的问题是,当我使用 arduino串行监视器检查程序时,我得到了疯狂的采样速度,例如在40毫秒内完成了10k读数,但是当我尝试使用 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个样本。
感谢您的任何帮助或建议,谢谢。
答案 0 :(得分:1)
首先,很好的问题。您面临的问题充满学习机会。
让我们一个一个地走
-现在您可以了解微控制器和计算机之间的区别。最基本形式的微控制器(如果您运行的是裸机代码,即使它不是非常高效的代码,例如在Arduino上),也只会做一件事,尤其是在与硬件相关的情况下(例如读取或写入UART) ),它将非常有效地完成此操作。另一方面,在台式计算机上,您具有逐层运行的任务(操作系统后台任务,更新屏幕等)。由于许多事情同时发生,并且如果您没有确定优先级,那么准确预测将要发生的情况和时间将非常困难。因此,不仅是您的Python代码正在运行,还会出现许多其他事情,这些事情会中断用户任务的流程。如果您希望以稳定(或至少可预测)的速度从UART缓冲区中读取数据,那么当前使用的体系结构将永远不会发生这种情况。
-即使您设法将操作系统精简到最低限度,杀死所有进程,在没有任何图形的终端上进行...您仍然必须应对自己在Python上所做的不确定性代码(这是您在Arduino串行监视器上看到的更好的性能,它除了从缓冲区中删除数据外没有做任何其他事情)。在Python代码上,您依次从端口读取数据,尝试查找特定字符(换行符),然后将读取的数据附加到列表中。如果您想提高性能,则只需读取数据并存储以供脱机处理,或者查看多线程(如果您的程序线程专用于仅从缓冲区读取数据,并且在单独的线程上进行进一步处理,可以显着提高吞吐量,特别是如果您正确设置优先级的话。
-最后,但实际上最重要的是,您应该问自己:我是否真的需要以2 Mbps的速度从传感器读取数据?如果答案是肯定的,并且您的传感器不是摄像机,那么恐怕您需要退后一步,看看以下概念:传感器带宽和动态响应。完成之后,下一个问题是:传感器更新输出的速度有多快?为什么?更新率有意义吗?我可以在这里给您一些参考。首先,假设您有一个温度传感器来读取和记录烤箱中的温度。如果烤箱中的温度以每分钟10摄氏度甚至每秒100摄氏度的速度变化,以1 MHz(每秒100万个读数)从传感器采样值是否有意义?您的传感器是否能够做出如此快速的反应(以至于其动态响应就起作用了)?我的猜测:可能不会。许多工业设备集成了数十个传感器来控制关键过程,并通过1.5 Mbps链路(例如,Profibus的相当标准)发送所有数据。