Generate and record analog output using DAC and ADC schedules
This demo generates some analog data on DAC (digital to analog converter) channels 0-2. This data is then read back on the ADC (analog to digital converters) by enabling ‘loopback.’ If Loopback is enabled, the device records internal output schedules as inputs. This is useful for testing and debugging.
Results are plotted using matplotlib.
import numpy as np
from pypixxlib import _libdpx as dp
import matplotlib.pyplot as plt
from psychopy import core
dp.DPxOpen()
#Simulate some data. Channels must have same length of data, use np.tile to repeat signals
#dacVoltages = [5,-2,0]
dacVoltages1 = np.tile(np.sin(2*np.pi*np.arange(0.0, 10.0, 0.05)), 50)
dacVoltages2 = np.tile(np.sin(2*np.pi*np.arange(0.0, 10.0, 0.01)), 10)
dacVoltages = np.vstack([dacVoltages1, dacVoltages2])
#Schedule parameters
onset = 0
rate = 10
rateUnits = 'hz'
dacChannels = [0,1]
adcChannels = [[0,'gnd'], [1, 'gnd'], [2, 'gnd']] #ADC channels must specify reference. 3 will point to Dac0
dacBaseAddress= 8e6
adcBaseAddress= 1e6
bufferSize = len(dacVoltages[1,:]) #buffer size uses 'frames' as a unit, includes all data from one sample
#configure and push configuration to device
dp.DPxWriteDacBuffer(dacVoltages, dacBaseAddress, dacChannels)
dacStatus = dp.DPxSetDacSchedule(onset, rate, rateUnits, bufferSize, dacChannels, dacBaseAddress)
adcStatus = dp.DPxSetAdcSchedule(onset, rate, rateUnits, bufferSize+1, adcChannels, adcBaseAddress)
#Enable loopback and stop ADC from recording external data
dp.DPxEnableDacAdcLoopback()
dp.DPxDisableAdcFreeRun()
#Push everything to the device
dp.DPxWriteRegCache()
#Start schedules
dp.DPxStartDacSched()
dp.DPxStartAdcSched()
dp.DPxUpdateRegCache()
dacStartTime = dp.DPxGetTime()
currentTime = dacStartTime
timeout = 5
#Start loop
while currentTime-dacStartTime<timeout:
dp.DPxUpdateRegCache()
currentTime = dp.DPxGetTime()
core.wait(0.5)
#import data
dp.DPxGetAdcStatus(adcStatus)
toRead = adcStatus['newBufferFrames']
bufferData, bufferTimetags = dp.DPxReadAdcBuffer(adcStatus, toRead)
dp.DPxStopDacSched()
dp.DPxStopAdcSched()
dp.DPxWriteRegCache()
dp.DPxClose()
#Plot
plt.ion()
fig = plt.figure()
ax = fig.add_subplot()
plotColors = ['-b', '-r', '-g']
plotOffsets = [0,2,5]
for i in range(0, len(adcChannels)):
plotData = [x+plotOffsets[i] for x in bufferData[i]]
line, = ax.plot(bufferTimetags, plotData, plotColors[i])
ax.set_autoscalex_on(True)
ax.set(xlabel='Time', ylabel='Voltage', title='ADC Channels 0-3 Input')
ax.grid()
plt.show()