![]() |
optoOIS
|
Vector Pattern Unit Trigger
from enum import IntEnum
import optoOIS
from optoOIS.tools.definitions import OperationMode, UnitType
class ExternalTrigger(IntEnum):
DISABLED = 0
RISING_FALLING_EDGE = 1
RISING_EDGE = 2
# connect to the prism (COM port detected automatically)
mre3ois = optoOIS.connectmre3ois()
x_points = 4
y_points = 4
matrix_vector = []
for i in range(0, x_points):
for j in range(0, y_points):
matrix_vector.append([i, j])
print("Matrix vector is: " + str(matrix_vector))
XY_factor = 40 # division factor to represent the values in XY coordinates
offset_x = -0.2
offset_y = -0.2
matrix_vector = [[x / XY_factor + offset_x, y / XY_factor + offset_y] for [x, y] in matrix_vector]
matrix_vector.insert(0, matrix_vector[0]) # insert first point twice for constant dwell time for every point
print("Matrix vector transposed to XY is: " + str(matrix_vector))
vector_to_vpu_memory = []
for i in range(2):
for j in range(0, x_points * y_points + 1):
vector_to_vpu_memory.append((matrix_vector[j][i]))
print("Vector sent to VPU memory: " + str(vector_to_vpu_memory))
# load to memory
mre3ois.VectorPatternMemory.SetPattern(index=0, vector=vector_to_vpu_memory)
vpu0 = mre3ois.Channel_0.VectorPatternUnit # setting x-axis to vector pattern unit
vpu1 = mre3ois.Channel_1.VectorPatternUnit # setting y-axis to vector pattern unit
vpu0.SetUnit(UnitType.XY) # calibrated close loop for x-axis
vpu1.SetUnit(UnitType.XY) # calibrated close loop for y-axis
X_Freq_sample_speed = 16 # sampling rate of vector pattern unit X axis
Y_Freq_sample_speed = 16 # sampling rate of vector pattern unit Y axis
# VPU setting
vpu0.SetFreqSampleSpeed(X_Freq_sample_speed)
vpu1.SetFreqSampleSpeed(Y_Freq_sample_speed)
vpu0.SetCycles(1)
vpu1.SetCycles(1)
vpu0.SetAsInput()
vpu1.SetAsInput()
vpu0.SetStart(0) # first index
vpu0.SetEnd(x_points * y_points + 1) # last index
vpu1.SetStart(x_points * y_points + 1) # first index
vpu1.SetEnd(2 * x_points * y_points + 2) # last index
# trigger setting to rising edge and input
vpu0.SetExternalTrigger(ExternalTrigger.RISING_EDGE.value)
vpu1.SetExternalTrigger(ExternalTrigger.RISING_EDGE.value)
vpu0.SetExtTriggerGPIO(True)
vpu1.SetExtTriggerGPIO(True)
Check Step Response
import optoOIS
import numpy as np
import time
import matplotlib.pyplot as plt
from optoOIS.tools.definitions import OperationMode
# connect to the prism (COM port detected automatically)
mre3ois = optoOIS.connectmre3ois()
# Setup logger (See Firmware manual for register values)
mre3ois.Logger.set_register('logged_register_0', 0xe802) # current A: 0xe802
mre3ois.Logger.set_register('logged_register_1', 0xe902) # current B: 0xe902
mre3ois.Logger.set_register('logged_register_2', 0x2300) # OF A: 0x2300
mre3ois.Logger.set_register('logged_register_3', 0x2301) # OF B: 0x2301
mre3ois.Logger.set_register('logged_register_4', 0x3b00) # X: 0x3b00
mre3ois.Logger.set_register('logged_register_5', 0x3b01) # Y: 0x3b01
logger_numDataPoints = 2000 # maximum is 5000
logger_sampleRate = 10000 # maximum is 10000
mre3ois.Logger.SetSamplingFrequency(logger_sampleRate)
mre3ois.Channel_0.LinearOutput.SetCurrentLimit(1.1) # Maximum is 1.136 A
mre3ois.Channel_1.LinearOutput.SetCurrentLimit(1.1) # Maximum is 1.136 A
Xaxis_halfstep_dgr = 5 # used, the step response is measured in X axis
Yaxis_halfstep_dgr = 0 # not used
Xaxis_halfStep_xy = np.tan(Xaxis_halfstep_dgr * 2 * np.pi / 180) / np.tan(
50 * np.pi / 180) # conversion from mech. angle to x,y coordinate
print("Halfstep value in XY coordinate: " + str(round(Xaxis_halfStep_xy, 3)))
# Set control mode to close loop in XY coordinates on both axes
mre3ois.MiscFeatures.SetOperationMode(OperationMode.XY_CONTROL.value)
mre3ois.Channel_0.StaticInput.SetAsInput()
mre3ois.Channel_1.StaticInput.SetAsInput()
mre3ois.Channel_0.StaticInput.SetXY(0)
mre3ois.Channel_1.StaticInput.SetXY(0)
mre3ois.Channel_0.StaticInput.SetXY(-Xaxis_halfStep_xy)
time.sleep(0.2)
mre3ois.Logger.RunLogger() # triggers data aquisition
mre3ois.Channel_0.StaticInput.SetXY(Xaxis_halfStep_xy) # change of setpoint
time.sleep(logger_numDataPoints / logger_sampleRate + 0.1)
mre3ois.Logger.StopLogger() # stop logger after all samples are collected
mre3ois.Channel_0.StaticInput.SetXY(0)
# time will be linearly spaced at the given sampling rate
t = np.linspace(0, logger_numDataPoints / logger_sampleRate, num=logger_numDataPoints, endpoint=False) # in s
# get data from MR-E-3_OIS_OIS (takes a while to transmit over serial connection)
cA = mre3ois.Logger.GetLog(0, 0, logger_numDataPoints)
cB = mre3ois.Logger.GetLog(1, 0, logger_numDataPoints)
ofA = mre3ois.Logger.GetLog(2, 0, logger_numDataPoints)
ofB = mre3ois.Logger.GetLog(3, 0, logger_numDataPoints)
x = mre3ois.Logger.GetLog(4, 0, logger_numDataPoints)
y = mre3ois.Logger.GetLog(5, 0, logger_numDataPoints)
fig, axs = plt.subplots(4, 1, figsize=(8, 8), sharex=True)
# first subplot
axs[0].plot(t, cA)
axs[0].set_title('currA (A)', loc='left')
axs[0].set_ylabel('A')
# second
axs[1].plot(t, cB)
axs[1].set_title('currB (A)', loc='left')
axs[1].set_ylabel('A')
# third
axs[2].plot(t, x)
axs[2].set_title('X units', loc='left')
axs[2].set_ylabel('X')
# fourth
axs[3].plot(t, y)
axs[3].set_title('Y units', loc='left')
axs[3].set_ylabel('Y')
axs[3].set_xlabel('time (s)')
# make all subplots nicer
for ax in axs:
ax.grid(True, alpha=0.3)
fig.suptitle('MR-E-3_OIS logger data', fontsize=14)
fig.tight_layout(rect=[0, 0.03, 1, 0.95]) # leave space for main title
plt.show()
mre3ois.disconnect()
Setup Signal Generator
import optoOIS
import numpy as np
import time
import matplotlib.pyplot as plt
from optoOIS.tools.definitions import OperationMode, UnitType, WaveformShape
# connect to the prism (COM port detected automatically)
mre3ois = optoOIS.connectmre3ois()
# Setup logger (See Firmware manual for register values)
mre3ois.Logger.set_register('logged_register_0', 0xe802) # current A: 0xe802
mre3ois.Logger.set_register('logged_register_1', 0xe902) # current B: 0xe902
mre3ois.Logger.set_register('logged_register_2', 0x2300) # OF A: 0x2300
mre3ois.Logger.set_register('logged_register_3', 0x2301) # OF B: 0x2301
mre3ois.Logger.set_register('logged_register_4', 0x3b00) # X: 0x3b00
mre3ois.Logger.set_register('logged_register_5', 0x3b01) # Y: 0x3b01
logger_numDataPoints = 5000 # maximum is 5000
logger_sampleRate = 1000 # maximum is 10000
mre3ois.Logger.SetSamplingFrequency(logger_sampleRate)
mre3ois.Channel_0.LinearOutput.SetCurrentLimit(1.1) # Maximum is 1.136 A
mre3ois.Channel_1.LinearOutput.SetCurrentLimit(1.1) # Maximum is 1.136 A
# Signal generator waveform parameters
Xaxis_amp_deg = 10.0
Yaxis_amp_deg = 4.0
Xaxis_offset_deg = 0.0
Yaxis_offset_deg = 0.0
Xaxis_freq = 3.0
Yaxis_freq = 5.0
Xaxis_amp_xy = np.tan(Xaxis_amp_deg * 2 * np.pi / 180) / np.tan(
50 * np.pi / 180) # conversion from mech. angle to x,y coordinate
Yaxis_amp_xy = np.tan(Yaxis_amp_deg * 2 * np.pi / 180) / np.tan(
50 * np.pi / 180) # conversion from mech. angle to x,y coordinate
Xaxis_offset_xy = np.tan(Xaxis_offset_deg * 2 * np.pi / 180) / np.tan(
50 * np.pi / 180) # conversion from mech. angle to x,y coordinate
Yaxis_offset_xy = np.tan(Yaxis_offset_deg * 2 * np.pi / 180) / np.tan(
50 * np.pi / 180) # conversion from mech. angle to x,y coordinate
print("X amplitude value in XY coordinate: " + str(round(Xaxis_amp_xy, 3)))
print("Y amplitude value in XY coordinate: " + str(round(Yaxis_amp_xy, 3)))
print("X offset value in XY coordinate: " + str(round(Xaxis_offset_xy, 3)))
print("Y offset value in XY coordinate: " + str(round(Yaxis_offset_xy, 3)))
# Signal generator settings
sig_gen_0 = mre3ois.Channel_0.SignalGenerator
sig_gen_1 = mre3ois.Channel_1.SignalGenerator
sig_gen_0.SetAsInput()
sig_gen_1.SetAsInput()
sig_gen_0.SetUnit(UnitType.XY)
sig_gen_1.SetUnit(UnitType.XY)
sig_gen_0.SetShape(WaveformShape.TRIANGULAR)
sig_gen_1.SetShape(WaveformShape.SINUSOIDAL)
sig_gen_0.SetFrequency(float(Xaxis_freq))
sig_gen_1.SetFrequency(float(Yaxis_freq))
sig_gen_0.SetAmplitude(float(Xaxis_amp_xy))
sig_gen_1.SetAmplitude(float(Yaxis_amp_xy))
sig_gen_0.SetOffset(float(Xaxis_offset_xy))
sig_gen_1.SetOffset(float(Yaxis_offset_xy))
time.sleep(0.2)
mre3ois.Logger.RunLogger() # triggers data acquisition
mre3ois.set_value([sig_gen_0.run, sig_gen_1.run], [1, 1]) # runs the signal generator
time.sleep(logger_numDataPoints / logger_sampleRate + 0.1)
mre3ois.Logger.StopLogger() # stop logger after all samples are collected
mre3ois.set_value([sig_gen_0.run, sig_gen_1.run], [0, 0]) # stops the signal generator
# static input moves the prism to 0 position
mre3ois.Channel_0.StaticInput.SetAsInput()
mre3ois.Channel_1.StaticInput.SetAsInput()
mre3ois.Channel_0.StaticInput.SetXY(0)
mre3ois.Channel_1.StaticInput.SetXY(0)
# time will be linearly spaced at the given sampling rate
t = np.linspace(0, logger_numDataPoints / logger_sampleRate, num=logger_numDataPoints, endpoint=False) # in s
# get data from MR-E-3_OIS_OIS (takes a while to transmit over serial connection)
cA = mre3ois.Logger.GetLog(0, 0, logger_numDataPoints)
cB = mre3ois.Logger.GetLog(1, 0, logger_numDataPoints)
ofA = mre3ois.Logger.GetLog(2, 0, logger_numDataPoints)
ofB = mre3ois.Logger.GetLog(3, 0, logger_numDataPoints)
x = mre3ois.Logger.GetLog(4, 0, logger_numDataPoints)
y = mre3ois.Logger.GetLog(5, 0, logger_numDataPoints)
fig, axs = plt.subplots(4, 1, figsize=(8, 8), sharex=True)
# currA
axs[0].plot(t, cA, linewidth=1.2)
axs[0].set_title("currA (A)", loc="left")
axs[0].set_ylabel("A")
axs[0].grid(True, alpha=0.3)
# currB
axs[1].plot(t, cB, linewidth=1.2)
axs[1].set_title("currB (A)", loc="left")
axs[1].set_ylabel("A")
axs[1].grid(True, alpha=0.3)
# X units
axs[2].plot(t, x, linewidth=1.2)
axs[2].set_title("X units", loc="left")
axs[2].set_ylabel("X")
axs[2].grid(True, alpha=0.3)
# Y units
axs[3].plot(t, y, linewidth=1.2)
axs[3].set_title("Y units", loc="left")
axs[3].set_ylabel("Y")
axs[3].set_xlabel("time (s)")
axs[3].grid(True, alpha=0.3)
# Hide x tick labels on upper plots (only bottom one shows time)
for ax in axs[:-1]:
ax.label_outer()
fig.suptitle("MR-E-3_OIS logger data (sine test)", fontsize=14)
fig.tight_layout(rect=[0, 0.03, 1, 0.95])
plt.show()
mre3ois.disconnect()