| optoMDC

Loading...
Searching...
No Matches
MR-E-3 Introduction

# Python SDK for controlling the MR-E-3

The optoMDC SDK is organized in the following way:

         Board.Channel.System.RegisterCommand(parameters)

Board : Low/mid level object for operating the firmware such as vector patterns, simple/pro commands, etc
Channel : A given channel, which can set input types, gain, etc.
System : Each channel has its own stages. From here you can call methods that get/set individual registers.
registers : Each system has several registers, which are dictionaries with elements regarding valid units/range.

## To begin with MR-E-3:

If necessary, flash the FW using: STM32 Cube Programmer This build of optoMDC is based on FW Version: 18282400-00-A_MRE3_1.2.741542

Import necessary module and initialize a board

    import optoMDC
    mre3 = optoMDC.connectmre3()

Define the system you want to interact with (board.channel.system)

    sig_gen = mre3.Channel_0.SignalGenerator

Start setting values

    sig_gen.SetAmplitude(0.1)

## Setting Up A Channel (Quick-Start Guide - Sinusoid):

Each Channel has a Manager for handling signal flow. This happens mostly behind-the-scenes, However, it is important to keep in mind the following procedure.

### (1) Set Input Stage > (2) Set Input Conditioning > (3) Set Control Mode > (4) Set Output Limiting

For example, to output a sinusoid on Channel_0 in open-loop (current) mode...

    import optoMDC
    mre3 = optoMDC.connectmre3()

    ch_0 = mre3.Channel_0

    ch_0.SignalGenerator.SetAsInput()                    # (1) here we tell the Manager that the sig gen is the desired input
    ch_0.InputConditioning.SetGain(1.0)                  # (2) here we tell the Manager some input conditioning parameters
    ch_0.SetControlMode(optoMDC.Units.CURRENT)         # (3) here we tell the Manager that our input will be in units of current
    ch_0.LinearOutput.SetCurrentLimit(0.7)               # (4) here we tell the Manager to limit the current to 700mA (default)

    ch_0.Manager.CheckSignalFlow()                       # This is a useful method to make sure the signal flow is configured correctly.

The channel is configured. The output of the Signal Generator will now proceed through the signal flow mentioned above.

Therefore, next we will configure the output of the Signal Generator.

    sg_0 = mre3.Channel_0.SignalGenerator

    sg_0.SetUnit(optoMDC.Units.CURRENT)                 # here we set the sig gen to output in units of current (This must match the control mode!)
    sg_0.SetShape(optoMDC.Waveforms.SINUSOIDAL)         # here we set the sig gen output waveform type
    sg_0.SetFrequency(10.0)                             # here we set the frequency in Hz
    sg_0.SetAmplitude(0.100)                            # here we set the amplitude in Amps
    sg_0.Run()                                          # done.

## Setting Up A Channel (Quick-Start Guide - DC output):

Each Channel has a Manager for handling signal flow. This happens mostly behind-the-scenes, However, it is important to keep in mind the following procedure.

###

For example, to output a sinusoid on Channel_0 in open-loop (current) mode...

    import optoMDC
    mre3 = optoMDC.connectmre3()

    ch_0 = mre3.Channel_0

    ch_0.StaticInput.SetAsInput()                        # (1) here we tell the Manager that we will use a static input
    ch_0.InputConditioning.SetGain(1.0)                  # (2) here we tell the Manager some input conditioning parameters
    ch_0.SetControlMode(optoMDC.Units.CURRENT)           # (3) here we tell the Manager that our input will be in units of current
    ch_0.LinearOutput.SetCurrentLimit(0.7)               # (4) here we tell the Manager to limit the current to 700mA (default)

    ch_0.Manager.CheckSignalFlow()                       # This is a useful method to make sure the signal flow is configured correctly.

The channel is configured. The output of the Static system will now proceed through the signal flow mentioned above.

Therefore, next we will configure the output of the Static System.

    si_0 = mre3.Channel_0.StaticInput

    si_0.SetCurrent(0.075)                              # here we set a static output of 75mA. (Control mode above must also be CURRENT!)

There are many other systems to interact with and configure. For more information, see the links below...

### Check out the link below for an overview of all of the available systems and their methods (such as OpticalFeedback, Logger, and VectorPatternUnit)

General Systems

    mre3.Channel_0.VectorPatternUnit.SetExternalTrigger()
    mre3.Channel_0.InputConditioning.SetGain(0.7)

### Check out the link below for an overview of the Board-level utility commands (such as load snapshot)

Utility Commands

    mre3.load_snapshot(2)
    mre3.reset()

### Setting up operation modes for both channels

    from optoMDC import OperationMode
    from optoMDC.mre3 import MRE3Board
    from optoKummenberg.tools.list_comports import get_ftdi_port
    from optoICC.tools.definitions import *

    port = get_ftdi_port()
    mre3  = MRE3Board(port, verbose=False)
    mre3.MiscFeatures.SetFEvoltage()                                    # front end voltage
    mre3.channel[0].LinearOutput.SetCurrentLimit(0.15)                  # limit max input current
    mre3.channel[1].LinearOutput.SetCurrentLimit(0.15)

    # set open loop (feedthrough) mode
    mre3.MiscFeatures.SetOperationMode(OperationMode.CURRENT.value)

    # set optical feedback mode
    mre3.MiscFeatures.SetOperationMode(OperationMode.OF_CONTROL.value)
    OFA = mre3.OpticalFeedback.GetOpticalFeedbackA()                    # readout optical feedback values
    OFB = mre3.OpticalFeedback.GetOpticalFeedbackB()

    # set XY PID mode
    mre3.MiscFeatures.SetOperationMode(OperationMode.XY_CONTROL.value)
    RBFX = mre3.RadialBasisFunction.GetMirrorCoordinateX()              # readout radial basis function values
    RBFY = mre3.RadialBasisFunction.GetMirrorCoordinateY()

### Setting up operation mode manually for one channel

    import optoMDC
    from optoKummenberg import EnChannel, EnStage, EnSignalFlowPath

    mre3 = optoMDC.connectmre3()
    sfm = mre3.SignalFlowManager

    OPEN_LOOP_SYSTEM_ID = 0xB8
    PID_STAGE_SYSTEM_ID_BASE = 0xB8
    SYSTEM_ID_OPTICAL_FEEDBACK = 0x23
    RADIAL_BASIS_FUNCTION = 0x3B

    #   Switch optical feedback on all channels, it is enough to call this function only once
    sfm.SetStageSystem(EnSignalFlowPath.FEED_BACK, EnStage.OUTPUT_COND, EnChannel.CHANNEL_0, SYSTEM_ID_OPTICAL_FEEDBACK)

    #   Switch radial basis function on all channels, turning on XY control
    #   To switch back to OF control mode, it is needed to call this function with OPEN_LOOP_SYSTEM_ID instead of RADIAL_BASIS_FUNCTION
    sfm.SetStageSystem(EnSignalFlowPath.FEED_BACK, EnStage.OUTPUT, EnChannel.CHANNEL_0, RADIAL_BASIS_FUNCTION)

    #   Switch operation mode system to PID on Channel_0
    #   To switch back to open loop, use OPEN_LOOP_SYSTEM_ID instead of PID_STAGE_SYSTEM_ID_BASE
    sfm.SetStageSystem(EnSignalFlowPath.MAIN_FLOW, EnStage.CONTROL, EnChannel.CHANNEL_0, PID_STAGE_SYSTEM_ID_BASE)

### Setting Registers Directly

Additional operations are available directly through the Board object (get/set multiple, reset, etc)
For example, multiple set/get can be done (up to 8 at once).
After the following commands, the Signal Generator system will output a sinusoid on channel 0 (You must still configure the Manager!)

    import optoMDC
    mre3 = optoMDC.connectmre3()

    mngr = mre3.Channel_0.Manager
    sig_gen = mre3.Channel_0.SignalGenerator

    systems = [mngr.input,     mngr.control,   sig_gen.shape,                sig_gen.frequency, sig_gen.amplitude, sig_gen.unit,          sig_gen.run]
    values  = [sig_gen.sys_id, sig_gen.sys_id, optoMDC.Waveforms.SINUSOIDAL, 10.0,              0.1,               optoMDC.Units.CURRENT, True       ]

    mre3.set_value(systems, values)
    mre3.get_value(systems)

Note: You can find which registers a system has by calling `get_register_names`

    >>> sig_gen.get_register_names()
    ['unit', 'run', 'shape', 'frequency', 'amplitude', 'offset', 'phase', 'cycles', 'duty_cycle']

### For More Examples, See The Page Below:

Additional Examples