我试图模拟校准研究仪器的复合动作电位。目标是以250 Hz输出某个10μV信号。低电压将在稍后处理,对我来说主要问题是频率。下面的图片显示了我正在尝试制作的系统的概况。树莓派上的Python延迟
通过从活的动物的数据采集,以及处理在MATLAB中的数据,我已经由低噪声信号,并在12位格式789倍的值。然后我使用Git克隆了以csv格式将其存储到Raspberry Pi的存储库。以下是我在RPi上编写的Python脚本。您可以跳到脚本中的def main来查看功能。
#!/usr/bin/python
import spidev
from time import sleep
import RPi.GPIO as GPIO
import csv
import sys
import math
DEBUG = False
spi_max_speed = 20 * 1000000
V_Ref = 5000
Resolution = 2**12
CE = 0
spi = spidev.SpiDev()
spi.open(0,CE)
spi.max_speed_hz = spi_max_speed
LDAQ = 22
GPIO.setmode(GPIO.BOARD)
GPIO.setup(LDAQ, GPIO.OUT)
GPIO.output(LDAQ,GPIO.LOW)
def setOutput(val):
lowByte = val & 0b11111111 #Make bytes using MCP4921 data sheet info
highByte = ((val >> 8) & 0xff) | 0b0 << 7 | 0b0 << 6 | 0b1 << 5 | 0b1 << 4
if DEBUG :
print("Highbyte = {0:8b}".format(highByte))
print("Lowbyte = {0:8b}".format(lowByte))
spi.xfer2([highByte, lowByte])
def main():
with open('signal12bit.csv') as signal:
signal_length = float(raw_input("Please input signal length in ms: "))
delay = float(raw_input("Please input delay after signal in ms: "))
amplitude = float(raw_input("Please input signal amplitude in mV: "))
print "Starting Simulant with signal length %.1f ms, delay %.1f ms and amplitude %.1f mV." % (signal_length, delay, amplitude)
if not DEBUG : print "Press ctrl+c to close."
sleep (1) #Wait a sec before starting
read = csv.reader(signal, delimiter=' ', quotechar='|')
try:
while(True):
signal.seek(0)
for row in read: #Loop csv file rows
if DEBUG : print ', '.join(row)
setOutput(int(row)/int((V_Ref/amplitude))) #Adjust amplitude, not super necessary to do in software
sleep (signal_length/(data_points*1000) #Divide by 1000 to make into ms, divide by length of data
sleep (delay/1000)
except (KeyboardInterrupt, Exception) as e:
print(e)
print "Closing SPI channel"
setOutput(0)
GPIO.cleanup()
spi.close()
if __name__ == '__main__':
main()
该脚本几乎按预期工作。将MCP4921 DAC的输出引脚连接到示波器可以很好地再现信号,并正确输出后续延迟。
不幸的是,数据点比我需要的要多得多。我能够将信号塞入的最短时间约为79毫秒。这是因为在休眠功能中除以789000,我知道这对Python和Pi来说太多了,因为读取csv文件需要时间。但是,如果我尝试手动创建数组,并将这些值取出而不是读取csv文件,我可以实现6 kHz以上的频率而不会丢失。
我的问题是
我怎样才能得到这个信号出现在250 Hz的频率,并从用户的输入可靠地降低呢?我想过在脚本中手动将789值写入数组,然后将SPI速度更改为适合250 Hz的值。这可以消除慢速csv阅读器功能,但是不能减少用户输入的频率。无论如何,消除对csv.read的需求将会有很大的帮助。谢谢!
您可以从您的csv阅读器中创建一个列表,以便将其缓存在内存中。 –
我试过这样做,但它似乎没有任何区别。在这个脚本之前,我从来没有用Python进行过编程,你能否具体解释一下如何只读取一次csv,然后循环缓存的列表呢? – Tachyon
'250Hz'=您是否意味着每个789个样本之间有4ms? – barny