我試圖模擬校準研究儀器的複合動作電位。目標是以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