1. Chris Lee-Messer
  2. sutter-dg4

Source

sutter-dg4 / dg4.py

# coding=UTF-8
# Chris Lee-Messer 12/15/2008 (c)
# requires pyserial for serial interface to the Sutter Lambda DG-4 high speed filter changer

from serial import *
import time

# in command mode, just send an integer 0-12 at least and the filter will change to that
# use ord() to convert a one character string result back to an integer for display

# value source: Lambda DG-4 high-speed filter changer operation manual Rev 2.10 (20051103)

SWITCH_TO_SERIAL=238 # switch the DG4 to serial mode, DG4 hangs until it receives the next serial command
OPEN_SHUTTER = 170

ND_ADJ_MARKER = 171 # DATANUM = 171 MARKER BETWEEN 235 OR 236 IN N.D. ADJUST
CLOSE_SHUTTER = 172 
ENABLE_TURBO_BLANKING=186
DISABLE_TURBO_BLANKING = 188 
TRIGGERED_BY_STROBE = 202
DISABLE_TRIGGERED_BY_STROBE = 203
SELECT_VIDEO_SYNC= 204 

DISABLE_VIDEO_SYNC = 205
SELECT_VIDEO_SYNC_GATED_BY_STROBE_LOW = 206
DISABLE_VIDEO_SYNC_GATED_BY_STROBE_LOW = 207
FREEZE_DISPLAY = 218 
TURN_DISPLAY_ON = 219 
START_LOADING_RING_BUFFER = 223 #START LOADING RING BUFFER (UP TO 256 VALUES)
START_REMOTE_CHANGE_OF_ND_FILTER_SETTING = 234 #START REMOTE CHANGE OF N.D. FILTER SETTING
INCREASE_THE_DAC_GALVO_VALUE = 235 #-SEND 171 AS SPACE
DECREASE_THE_DAC_GALVO_VALUE  = 236 # -SEND 171 AS SPACE
END_CHANGE_OF_ND_FILTER_SETTING_AND_SAVE = 237 
FORCE_ONLINE_FOR_CHANNEL_THAT_RECEIVED_IT = 238 
END_LOADING_RING_BUFFER_FILTERS = 240 
RUN_RING_BUFFER = 241 # (FIRST SELECT TRIGGER SOURCE)
END_RING_BUFFER_RUN = 242 

#toHex = lambda x:"".join([hex(ord(c))[2:].zfill(2) for c in x])
# str.encode("hex"), str.decode("hex")

class DG4Serial(object):
    def __init__(self, comname):
        """example comname = 3 if want to open com4 on windows
        
        Communication for the serial port requires the following settings:
        • Baud (data) rate (bits per second): 9600
        • Data bits: 8
        • Parity: None
        • Stop bits: 1
        
        The mode is indicated on the front panel display. The display will 
        indicate either PARALLEL, MANUAL OR SERIAL. The unit automatically selects
        the parallel mode at power on. When the value of 238 is received, the 
        display will switch to indicate SERIAL. If any communication errors occur,
        they will be indicated by the * symbol following the word SERIAL. If the
        238 command is not received correctly because of communication errors,
        the * symbol may replace letters in the word PARALLEL.
        Echoes of Serial Port Commands
        In the serial mode, the Lambda DG-4 controller responds to each command by
        echoing the command back to the host computer. This indicates that the
        command was received and will be executed promptly. If the command sent
        is the same as the last command received, it will not be echoed and the
        controller will take no action. Once the command has been executed completely,
        the controller will send a character with the value of 13, which is a carriage
        return.
        """
        self.com = Serial(comname)
        
    def wdec(self,val):
        self.com.write("%c" % val)  # do I need a reply?
    
    def cmd(self,val):
        self.wdec(val)
        while self.com.inWaiting():
            print "dg4: %d" % ord(self.com.read(1))
    
    
    
    

    def switchToSerialMode(self):
        self.wdec(SWITCH_TO_SERIAL)
        
    def clear(self):
        while self.com.inWaiting():
            print "clearing dg4: %d" % ord(self.com.read(1))
            
    def setupForStrobeFilter(self,filt=1,comnum=3):
        """
        specific to inverted rig where we use COM4 (comnum 3 opens COM4) to control the DG4
        this will set up the dg4 to switch to filter 1 setting on strobe pulse then
        back to 0 on the next strobe pulse
        """
        
        
        self.cmd(SWITCH_TO_SERIAL)
        time.sleep(0.5)
        self.cmd(START_LOADING_RING_BUFFER)
        time.sleep(0.5)
        self.cmd(filt)
        time.sleep(0.5)
        self.cmd(0)
        time.sleep(0.5)
        self.cmd(END_LOADING_RING_BUFFER_FILTERS)
        time.sleep(0.5)
        self.cmd(TRIGGERED_BY_STROBE)
        time.sleep(0.5)
        self.cmd(RUN_RING_BUFFER)
        time.sleep(0.5)

        return self
            
    # def waitForOK(self):
    # """loop until receive a 13 in return to know that last command has been fully executed"""
    
    # def waitForEcho
    
 
#  Reading the Status of the Lambda DG-4
#  T he Lambda DG-4 controller signals that it has completed commands received through its serial port by sending a carriage return back. 
#  so we're wating for int(13)
# The 
#~ following is an example of a QuickBASIC routine that might be used to monitor the status of the DG-4, assuming that #1 has already been 
#~ opened as the serial port to which the DG-4 is connected.


#~ In [2]: cd Desktop/
#~ C:\Documents and Settings\cleemesser\Desktop

#~ In [3]: from dg4 import *
#~ In [4]: dg = DG4Serial(3)

#~ In [5]: dg.cmd(SWITCH_TO_SERIAL)

#~ In [6]: dg.cmd(OPEN_SHUTTER)

#~ In [10]: dg.cmd(CLOSE_SHUTTER)
#~ repy: 170

#~ In [11]:   

def setupForStrobeFilter(filt=1,comnum=3):
    """
    specific to inverted rig where we use COM4 (comnum 3 opens COM4) to control the DG4
    this will set up the dg4 to switch to filter 1 setting on strobe pulse then
    back to 0 on the next strobe pulse
    """
    
    dg = DG4Serial(comnum)
    dg.setupForStrobeFilter(filt=filt,comnum=comnum)
    print "press enter to continue"
    r = raw_input()
    return dg
    
def exitToManualMode(dg):
    """
    exit serial command mode and allow for manual commands
    pass a DG4Serial object
    """
    dg.cmd(END_RING_BUFFER_RUN)
    time.sleep(0.5)
    dg.cmd(DISABLE_TRIGGERED_BY_STROBE)
    time.sleep(0.2)
    dg.cmd(TURN_DISPLAY_ON)
    
if __name__ == '__main__':
    setupForStrobeFilter(filt=1)