我正在尝试模拟复合动作电位,以校准研究仪器。目标是在250 Hz时输出一定的10 µV信号。低电压将在后面处理,对我来说主要问题是频率。下图显示了我正在尝试制作的系统概述。
通过从活体动物中获取数据,并在MATLAB中处理数据,我制作了一个低噪声信号,采用12位格式,共有789个值。然后我使用Git将存储在csv格式的仓库克隆到树莓派上。下面是我在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的需求都会有很大帮助。谢谢!