有没有办法使我的Mcp3008取样均匀?

2024-06-03 00:15:47 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在做一项工作,使用ADC mcp3008采样传感器数据并收集到10k。然后将其发送到XDB

所有这些工作都应该在1秒内完成。这就是重点

现在的问题是,每个数据的时间戳都非常不均匀

如你所见:

data in influxdb

我希望时间戳统一为0.1ms。我的意思是SDB中的时间精度应该是0.1ms

但不幸的是,写入参数time_精度只有“s”、“ms”、“u”或“n”

所以我所能做的就是使取样过程更加均匀,对吗

我使用多处理模块来完成这项工作。这是我的原始代码:

import Adafruit_GPIO.SPI as SPI # Import Adafruit GPIO_SPI Module
import Adafruit_MCP3008         # Import Adafruit_MCP3008
import serial
import time
import datetime
from influxdb import InfluxDBClient
from multiprocessing import Process, Queue
def producer(name):
    i=0
    while True:
        begin=time.time()
        body = []
        while i<10000:
            val = round(mcp.read_adc(0),4) #here read the data from SPI port
            current_time = datetime.datetime.utcnow()
            js = {
                "measurement": "Double",
                "time": current_time,
                "tags": {
                },
                "fields": {
                    "sensor2": val
                }
            }
            body.append(js)
            i+=1
        i=0
        res = client.write_points(body) #Send influxdb 10k data at once
        body.clear()
        end=time.time()-begin
        print(end,name)
           
if __name__ == "__main__":
    HW_SPI_PORT = 0 # Set the SPI Port. Raspi has two.
    HW_SPI_DEV  = 0 # Set the SPI Device
    mcp = Adafruit_MCP3008.MCP3008(spi=SPI.SpiDev(HW_SPI_PORT, HW_SPI_DEV))
    client = InfluxDBClient(host='XXXXX', port=8086, username='admin', password='admin', database= 'db',ssl=False, verify_ssl=False)
    p1 = Process(target=producer,args=(0,))
    p2 = Process(target=producer,args=(1,))
    p3 = Process(target=producer,args=(2,))
    p4 = Process(target=producer,args=(3,))
    p5 = Process(target=producer,args=(4,))
    p6 = Process(target=producer,args=(5,))
    p1.start()
    p2.start()
    p3.start()
    p4.start()
    p5.start()
    p6.start()

是的…我必须经过六道工序才能在平均一秒钟内完成

那么,有没有办法使取样均匀? 要使时间戳如下所示:

1603469938916'5'26000   -0.175
1603469938916'6'26000   -0.172
1603469938916'7'26000   -0.178
1603469938916'8'26000   -0.175
1603469938916'9'26000   -0.182

我是说时间精度为0.1ms

谢谢!这一定是个奇怪的问题

附言: 我有个主意,有没有办法让我的时间戳的精度达到0.1ms?比如:

timestamp=datetime.datetime.utcnow()
...Some operation...
print(timestamp)

然后得到:1603469938916900000

这可能有用

是的,我找到了解决办法:

from datetime import datetime
import math
def format():
    dt = datetime.utcnow()
    dt_round_microsec = math.floor(dt.microsecond/100)*100 
    dt = dt.replace(microsecond=dt_round_microsec)
    return dt

欢迎提出更好的建议


Tags: producerimportspiadafruittargetdatetimetime时间
1条回答
网友
1楼 · 发布于 2024-06-03 00:15:47

一些建议

  1. 如果需要对ADC进行均匀采样,这是一个更难的问题
  2. 如果您“只需要”统一的时间戳间距,您可以随意采样,然后将时间戳设置为begin + iteration * 0.1ms。这个选项对于任何类型的科学数据收集都不是很好。10k采样/秒听起来您需要等间隔采样(例如音频采样)。因此,我将忽略选项2

对于选项1,您需要循环具有一致的迭代时间。在RPi上使用python很难保证这一点(我假设您使用的是Pi)。RPi操作系统不是实时的,因此您的循环可能会随机延迟。这里唯一的实际选择是使用外部微处理器以保证定时触发ADC

不过,我们可以试着让您编写的采样循环更好一些datetime.datetime.utcnow()可能是一个缓慢的系统调用。使用time.perf_counter()可以获得更好的结果。您可能还希望在循环内的列表中只存储valcurrent_time,并在不同的进程中在循环外组装完整的json正文,因为看起来您希望永远使用10ksps(并在单独的进程中发送到influxdb)

一般来说,raspberry pi硬件不适合在这些频率下对ADC进行连续实时采样

相关问题 更多 >