Skip to content

Commit

Permalink
Updated nidaq adwin drivers for consistency
Browse files Browse the repository at this point in the history
For both instruments there is a single function for IO with arbitrary in/output. Input array can also be either 1D or 2D (i.e. 1xN). Returned output arrays are always 2D.

Co-Authored-By: mark-boon <[email protected]>
  • Loading branch information
heliox and Mark-Boon committed Jan 10, 2019
1 parent 0090755 commit 5ba5020
Show file tree
Hide file tree
Showing 5 changed files with 201 additions and 173 deletions.
89 changes: 51 additions & 38 deletions instruments/ADwin/ADbasic_8Read_4Write.BAK
Original file line number Diff line number Diff line change
Expand Up @@ -11,18 +11,19 @@
' Info_Last_Save = DARWIN-PC Darwin-PC\PNPNteam
'<Header End>
#Include ADwinGoldII.inc
DIM DATA_1[40000] AS LONG AS FIFO
DIM DATA_2[40000] AS LONG AS FIFO
DIM DATA_3[40000] AS LONG AS FIFO
DIM DATA_4[40000] AS LONG AS FIFO
DIM DATA_5[40000] AS LONG AS FIFO
DIM DATA_6[40000] AS LONG AS FIFO
DIM DATA_7[40000] AS LONG AS FIFO
DIM DATA_8[40000] AS LONG AS FIFO
DIM DATA_9[40000] AS LONG AS FIFO
DIM DATA_10[40000] AS LONG AS FIFO
DIM DATA_11[40000] AS LONG AS FIFO
DIM DATA_12[40000] AS LONG AS FIFO
DIM DATA_1[40003] AS LONG AS FIFO
DIM DATA_2[40003] AS LONG AS FIFO
DIM DATA_3[40003] AS LONG AS FIFO
DIM DATA_4[40003] AS LONG AS FIFO
DIM DATA_5[40003] AS LONG AS FIFO
DIM DATA_6[40003] AS LONG AS FIFO
DIM DATA_7[40003] AS LONG AS FIFO
DIM DATA_8[40003] AS LONG AS FIFO
DIM DATA_9[40003] AS LONG AS FIFO
DIM DATA_10[40003] AS LONG AS FIFO
DIM DATA_11[40003] AS LONG AS FIFO
DIM DATA_12[40003] AS LONG AS FIFO
DIM counter AS LONG

INIT:
FIFO_Clear(1)
Expand All @@ -40,21 +41,21 @@ INIT:

Rem set continuous conversion and range [-5, 5]V for ADCs
Seq_Mode(2, 2)
Seq_Set_Gain(2, 1)
Seq_Set_Gain(2, 0)
Seq_Mode(4, 2)
Seq_Set_Gain(4, 1)
Seq_Set_Gain(4, 0)
Seq_Mode(6, 2)
Seq_Set_Gain(6, 1)
Seq_Set_Gain(6, 0)
Seq_Mode(8, 2)
Seq_Set_Gain(8, 1)
Seq_Set_Gain(8, 0)
Seq_Mode(10, 2)
Seq_Set_Gain(10, 1)
Seq_Set_Gain(10, 0)
Seq_Mode(12, 2)
Seq_Set_Gain(12, 1)
Seq_Set_Gain(12, 0)
Seq_Mode(14, 2)
Seq_Set_Gain(14, 1)
Seq_Set_Gain(14, 0)
Seq_Mode(16, 2)
Seq_Set_Gain(16, 1)
Seq_Set_Gain(16, 0)

Seq_Select(1010101010101010b) Rem selects even ADCs (look in ADwin Gold II manual)
Seq_Start(1010101010101010b)
Expand All @@ -70,25 +71,37 @@ INIT:
Rem start flag
Par_80 = 0

Rem Amount of data to write
Par_79 = 0
Rem counter
counter = -1


EVENT:
If (Par_80 = 1) Then
Rem writing
Par_1 = DATA_1
DAC(1, Par_1)
Par_2 = DATA_2
DAC(2, Par_2)
Par_3 = DATA_3
DAC(3, Par_3)
Par_4 = DATA_4
DAC(4, Par_4)
If (counter < Par_79) Then
If (counter < Par_79 - 1) Then
Rem writing
Par_1 = DATA_1
DAC(1, Par_1)
Par_2 = DATA_2
DAC(2, Par_2)
Par_3 = DATA_3
DAC(3, Par_3)
Par_4 = DATA_4
DAC(4, Par_4)
EndIf

Rem reading
DATA_5 = Seq_Read(2)
DATA_6 = Seq_Read(4)
DATA_7 = Seq_Read(6)
DATA_8 = Seq_Read(8)
DATA_9 = Seq_Read(10)
DATA_10 = Seq_Read(12)
DATA_11 = Seq_Read(14)
DATA_12 = Seq_Read(16)
Rem reading
DATA_5 = Seq_Read(2)
DATA_6 = Seq_Read(4)
DATA_7 = Seq_Read(6)
DATA_8 = Seq_Read(8)
DATA_9 = Seq_Read(10)
DATA_10 = Seq_Read(12)
DATA_11 = Seq_Read(14)
DATA_12 = Seq_Read(16)

Inc(counter)
EndIf
EndIf
Binary file modified instruments/ADwin/ADbasic_8Read_4Write.TB1
Binary file not shown.
65 changes: 39 additions & 26 deletions instruments/ADwin/ADbasic_8Read_4Write.bas
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ DIM DATA_9[40003] AS LONG AS FIFO
DIM DATA_10[40003] AS LONG AS FIFO
DIM DATA_11[40003] AS LONG AS FIFO
DIM DATA_12[40003] AS LONG AS FIFO
DIM counter AS LONG

INIT:
FIFO_Clear(1)
Expand All @@ -40,21 +41,21 @@ INIT:

Rem set continuous conversion and range [-5, 5]V for ADCs
Seq_Mode(2, 2)
Seq_Set_Gain(2, 1)
Seq_Set_Gain(2, 0)
Seq_Mode(4, 2)
Seq_Set_Gain(4, 1)
Seq_Set_Gain(4, 0)
Seq_Mode(6, 2)
Seq_Set_Gain(6, 1)
Seq_Set_Gain(6, 0)
Seq_Mode(8, 2)
Seq_Set_Gain(8, 1)
Seq_Set_Gain(8, 0)
Seq_Mode(10, 2)
Seq_Set_Gain(10, 1)
Seq_Set_Gain(10, 0)
Seq_Mode(12, 2)
Seq_Set_Gain(12, 1)
Seq_Set_Gain(12, 0)
Seq_Mode(14, 2)
Seq_Set_Gain(14, 1)
Seq_Set_Gain(14, 0)
Seq_Mode(16, 2)
Seq_Set_Gain(16, 1)
Seq_Set_Gain(16, 0)

Seq_Select(1010101010101010b) Rem selects even ADCs (look in ADwin Gold II manual)
Seq_Start(1010101010101010b)
Expand All @@ -70,25 +71,37 @@ INIT:
Rem start flag
Par_80 = 0

Rem Amount of data to write
Par_79 = 0
Rem counter
counter = -1


EVENT:
If (Par_80 = 1) Then
Rem writing
Par_1 = DATA_1
DAC(1, Par_1)
Par_2 = DATA_2
DAC(2, Par_2)
Par_3 = DATA_3
DAC(3, Par_3)
Par_4 = DATA_4
DAC(4, Par_4)
If (counter < Par_79) Then
If (counter < Par_79 - 1) Then
Rem writing
Par_1 = DATA_1
DAC(1, Par_1)
Par_2 = DATA_2
DAC(2, Par_2)
Par_3 = DATA_3
DAC(3, Par_3)
Par_4 = DATA_4
DAC(4, Par_4)
EndIf

Rem reading
DATA_5 = Seq_Read(2)
DATA_6 = Seq_Read(4)
DATA_7 = Seq_Read(6)
DATA_8 = Seq_Read(8)
DATA_9 = Seq_Read(10)
DATA_10 = Seq_Read(12)
DATA_11 = Seq_Read(14)
DATA_12 = Seq_Read(16)
Rem reading
DATA_5 = Seq_Read(2)
DATA_6 = Seq_Read(4)
DATA_7 = Seq_Read(6)
DATA_8 = Seq_Read(8)
DATA_9 = Seq_Read(10)
DATA_10 = Seq_Read(12)
DATA_11 = Seq_Read(14)
DATA_12 = Seq_Read(16)

Inc(counter)
EndIf
EndIf
86 changes: 73 additions & 13 deletions instruments/ADwin/adwinIO.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
import os
import numpy as np
import time
import matplotlib.pyplot as plt

DEVICENUMBER = 1
RAISE_EXCEPTIONS = 1
Expand All @@ -21,26 +22,29 @@ def initInstrument():
adw = ADwin(DEVICENUMBER, RAISE_EXCEPTIONS)
return adw

def FloatToLong(x):
def FloatToLong(x, Vmax):
'''
Converts float values to integers,
more specifically this function maps [-10, 10] -> [0, 65536]
more specifically this function maps [-10, 10) -> [0, 65536)
'''
for i in range(len(x)):
x[i] = int((x[i] + 10) / 20 * 65536)
x[i] = int(np.round((x[i] + Vmax) / (2*Vmax / 65535)))
return x

def LongToFloat(x, Vmax):
'''
Converts integer values to floats,
more specifically this function maps [0, 65536] -> [-Vmax, Vmax]
more specifically this function maps [0, 65536) -> [-Vmax, Vmax)
'''
for i in range(len(x)):
x[i] = 2*Vmax/65536 * x[i] - Vmax
if isinstance(x, int):
x = 2*Vmax/65536 * x - Vmax
else:
for i in range(len(x)):
x[i] = 2*Vmax/65536 * x[i] - Vmax
return x


def IO(adw, inputs, Fs, inputPorts = [1, 0, 0, 0, 0, 0, 0]):
def IO(adw, Input, Fs, inputPorts = [1, 0, 0, 0, 0, 0, 0]):
'''
This function will write each row of array inputs on a separate
analog output of the ADwin at the specified sample frequency Fs.
Expand All @@ -54,14 +58,30 @@ def IO(adw, inputs, Fs, inputPorts = [1, 0, 0, 0, 0, 0, 0]):
Please look at the ADbasic file while reading this file.
Write FIFOs: 1 - 4
Read FIFOs: 5 - 12
Inputs arguments
----------------
adw: adwin
Input: N x M array, N output ports, M datapoints
Fs: sample frequency
inputPorts**: binary list containing ones for the used input ports
Returns
-------
P x M output array, P input ports, M datapoints
'''
# Input preparation
if len(Input.shape) == 1:
Input = Input[np.newaxis,:]

inputs = Input.copy()
InputSize = inputs.shape[1]
for i in range(inputs.shape[0]):
inputs[i, :] = FloatToLong(list(inputs[i, :]))
inputs[i, :] = FloatToLong(list(inputs[i, :]), 10)
x = np.zeros((8, InputSize), dtype = int)
x[:inputs.shape[0], :] = inputs
outputs = [[], [], [], [], [], [], [], []] # Eight empty output lists
lastWrite = False

try:
if os.name == 'posix':
Expand All @@ -70,7 +90,6 @@ def IO(adw, inputs, Fs, inputPorts = [1, 0, 0, 0, 0, 0, 0]):
adw.Boot('C:\\ADwin\\ADwin' + PROCESSORTYPE + '.btl')
adw.Load_Process('C:\\Users\\PNPNteam\\Documents\\GitHub\\SkyNEt\\instruments\\ADwin\\ADbasic_8Read_4Write.TB1')
adw.Set_Processdelay(1, int(300e6 / Fs)) # delay in clock cycles

adw.Start_Process(1)

# Clear all FIFOs
Expand All @@ -87,22 +106,36 @@ def IO(adw, inputs, Fs, inputPorts = [1, 0, 0, 0, 0, 0, 0]):
for i in range(1, 5):
adw.SetFifo_Long(i, list(x[i-1, :]), InputSize)
written = InputSize
lastWrite = True



# Notices the ADbasic how much datapoints to
adw.Set_Par(79, InputSize)
# Start reading/writing FIFO's when Par80 == 1
adw.Set_Par(80, 1)
read = -1 # Read additional datapoint, because write lags behind

if (lastWrite):
time.sleep((InputSize - read)/Fs) # If the last values are put in the write memory, wait a bit until they are written

while(read < InputSize):
empty = adw.Fifo_Empty(1)
full = adw.Fifo_Full(5)

# Read values if read FIFOs are full enough
if(full > 2000):
if(full > 2000 and not lastWrite):
for i in range(5, 13): # Read ports are 5 to 12
y = adw.GetFifo_Long(i, 2000)
outputs[i-5] += LongToFloat(list(y), 5)
outputs[i-5] += LongToFloat(list(y), 10)
read += 2000

elif(lastWrite):
for i in range(5, 13): # Read ports are 5 to 12
y = adw.GetFifo_Long(i, full)
outputs[i-5] += LongToFloat(list(y), 10)
read += full

# Write values if write FIFOs are empty enough
if(written < InputSize):
if(empty > 2000 and written+2000 <= InputSize):
Expand All @@ -113,6 +146,8 @@ def IO(adw, inputs, Fs, inputPorts = [1, 0, 0, 0, 0, 0, 0]):
for i in range(1, 5):
adw.SetFifo_Long(i, list(x[i-1, written:]), InputSize-written)
written = InputSize
lastWrite = True
time.sleep((InputSize - read)/Fs) # If the last values are put in the write memory, wait a bit until they are written

adw.Stop_Process(1)
adw.Clear_Process(1)
Expand All @@ -126,19 +161,21 @@ def IO(adw, inputs, Fs, inputPorts = [1, 0, 0, 0, 0, 0, 0]):
i = 0
for index, val in enumerate(inputPorts):
if(val):
outputArray[i] = outputs[index, 1:InputSize + 1]
outputArray[i] = outputs[index, 1:InputSize+1]
i += 1

return outputArray


def setControlVoltages(adw, x, Fs):
'''
x is a list of 4 values with desired control voltages in V.
'''

x = np.asarray(x) #convert x to numpy array
x = (x + 10) / 20 * 65536
x = x.astype(int)

x = np.tile(x, (FifoSize, 1))

InputBin = x.copy() # convert float array to integer values
Expand All @@ -163,3 +200,26 @@ def setControlVoltages(adw, x, Fs):

except ADwinError as e:
print('***', e)


def reset(adw):
'''
Resets the 4 DACs to 0V at a speed of 0.5V/s
'''
Fs = 1000
stepsize = 0.0005 # in units of V
DAC_values = []
DAC_diff = []
no_steps = []

for i in range(1,5):
DAC_values += [LongToFloat(adw.Get_Par(i), 10)]
no_steps += [int(abs(DAC_values[i-1]/stepsize))]

reset_inputs = np.zeros((4, max(no_steps)))
for i in range(reset_inputs.shape[0]):
reset_inputs[i,:no_steps[i]] = np.linspace(DAC_values[i], 0, no_steps[i], endpoint = True)

resetData = IO(adw, reset_inputs, Fs)


Loading

0 comments on commit 5ba5020

Please sign in to comment.