#pragma rtGlobals=1 // Use modern global access method. //////////////////////////////////////////////////////////////////////////////////////////////////// //Procedures for controlling a Lumencor light engine (http://lumencor.com) //08/10/2012 Josef G. Trapani (jtrapani@amherst.edu) //08/06/14 Updated to change light output intensity by single digits //Note: Procedure requires the VDT2.xop extension to be installed //Note: User must install the FTDI USB Serial driver for the USB to Serial (RS232) cable for the Lumencor: http://www.ftdichip.com/Drivers/VCP.htm //////////////////////////////////////////////////////////////////////////////////////////////////// Menu " Macros" "Lumencor",Start_Lumencor_Panel("start") End //////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////// // Panel for Lumencor Function Start_Lumencor_Panel(ctrlName) String ctrlName String savedDataFolder = GetDataFolder(1) // Save DoWindow Lumencor_Panel If (V_flag!=0) KillWindow Lumencor_Panel SetDataFolder root:Lumencor KillWaves /Z /A KillDataFolder /Z root:Lumencor Endif If (cmpstr(ctrlName,"start")==0) NewDataFolder /O/S root:Lumencor Variable /G Lumencor_intensity = 50 // DAC intensity 0xFF is full off and 0x00 is full on Variable /G Lumencor_On = 0 // 0 is Off and 1 is On Variable /G Lumencor_Temp // Lumencor Temp sensor String /G Lumencor_serialName // Lumencor serial device name Endif SetDataFolder savedDataFolder // and restore Variable returnNum = initLumencor(ctrlName) If (returnNum==-1) Abort "No Serial Devices Found! ---> Check menu /MISC/VDT2/" Elseif (returnNum==0) Print "Lumencor Light panel closed. Light is off." Elseif (returnNum==1) Lumencor_Panel(ctrlName) Endif End //////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////// //Initialize Lumencor Serial Devices Function initLumencor(ctrlName) String ctrlName String cmd String tempSerialList String tempSerialName String platform= UpperStr(igorinfo(2)) SVAR /z SerialName = root:Lumencor:Lumencor_serialName If ((cmpstr(ctrlName,"start")==0)&&(SVAR_Exists(SerialName)==1)) VDTGetPortList2 tempSerialList = S_VDT If (cmpstr(platform,"WINDOWS")==0) //Determine Serial Device Names tempSerialName = StringFromList(1, tempSerialList,";") If (cmpstr(tempSerialName, "COM4")!=0) KillDataFolder /Z root:Lumencor return -1 Else SerialName = StringFromList(1, tempSerialList,";") Endif Elseif (cmpstr(platform,"MACINTOSH")==0) //Determine Serial Device Names tempSerialName = StringFromList(0, tempSerialList,";") If (cmpstr(tempSerialName[0], "u")!=0) KillDataFolder /Z root:Lumencor return -1 Else SerialName = StringFromList(0, tempSerialList,";") Endif Else KillDataFolder /Z root:Lumencor return -1 Endif //VDTOpenPort2 $(SerialName) VDTOperationsPort2 $(SerialName) VDT2 baud=9600, stopbits=1, databits=8, parity=0 //Set GPIO 0-3 as open drain output "57 02 FF 50" VDTWriteBinary2 /TYPE=(0x48) 0x57, 0x02, 0xFF, 0x50 //Set GPIO 5-7 push-pull out, GPI0 4 open drain out "57 03 AB 50" VDTWriteBinary2 /TYPE=(0x48) 0x57, 0x03, 0xAB, 0x50 //Set Byte 1 (FF) as all Off: "4F FF 50" VDTWriteBinary2 /TYPE=(0x48) 0x4F, 0xFF, 0x50 //Full Off "4FFF50" return 1 ElseIf (cmpstr(ctrlName,"closePanelbutton")==0) VDTWriteBinary2 /TYPE=(0x48) 0x4F, 0xFF, 0x50 //Full Off "4FFF50" return 0 Endif // VDTWrite2 "W\002\255P" + "\r\n" //57 02 FF 50 ==> " \002" = 02Hex and \255 = FF hex // VDTWrite2 "W\003\171P" + "\r\n" //57 03 AB 50 ==> "\003" = 03Hex and \171 = AB hex // VDTWrite2 "O P" + "\r\n" //4F FF 50 - diasbles all channels // //Print "Lumencor serial port initialized" End //////////////////////////////////////////////////////////////////////////////////////// // Lumencor Controller Panel Static Function Lumencor_Panel(ctrlName) String ctrlName Variable Xcoord=200 Variable Ycoord=60 If (cmpstr(ctrlName,"start")==0) String info = IgorInfo(0) String screen1RectStr = StringByKey("SCREEN1", info) //e.g., "DEPTH=23,RECT=0,0,1280,1024" Variable depth, left, top, right, bottom sscanf screen1RectStr, "DEPTH=%d,RECT=%d,%d,%d,%d", depth, left,top, right, bottom top+=40 //adjust for title bar String platform= UpperStr(igorinfo(2)) If (cmpstr(platform,"WINDOWS")==0) NewPanel /N=Lumencor_Panel /W=(right-300,top,right,300) /FLT=2 /K=2 as "Light Driver v1.1" Else NewPanel /N=Lumencor_Panel /W=(right-380,top,right-80,300) /FLT=2 /K=2 as "Light Driver v1.1" Endif SetActiveSubwindow _endfloat_ ModifyPanel /W=Lumencor_Panel cbRGB=(62535,62535,62535), frameStyle=3, frameInset=5, noEdit=1, fixedSize=1 SetDrawLayer /W=Lumencor_Panel UserBack SetDrawEnv /W=Lumencor_Panel fillfgc= (45535,46535,46214) DrawRect /W=Lumencor_Panel 10,10,290,50 SetDrawEnv /W=Lumencor_Panel linefgc= (21845,21845,21845) DrawText /W=Lumencor_Panel 20,40,"Lumencor Light Driver" Button closePanelbutton,pos={210,20},size={60,20},proc=Start_Lumencor_Panel,title="Close", win=Lumencor_Panel CheckBox check1 pos={Xcoord-180,Ycoord+40}, title="white",mode=0, value=1,disable=0,proc=Lumencorcheck, win=Lumencor_Panel CheckBox check2 pos={Xcoord-180,Ycoord+60}, title="cyan (460-490nm)",mode=0, value=0,disable=0,proc=Lumencorcheck, win=Lumencor_Panel CheckBox check3 pos={Xcoord-180,Ycoord+80}, title="red",mode=0, value=0,disable=0,proc=Lumencorcheck, win=Lumencor_Panel Checkbox check4,pos={Xcoord-180,Ycoord},size={40,10},value=0,disable=0,proc=BigLumencorPanel,title="Big \rButton", win=Lumencor_Panel Button button3,pos={Xcoord-100,Ycoord+20},size={100,40},disable=0,proc=Lumencor_Start,title="Light is Off", win=Lumencor_Panel Button button3,fSize=16,fStyle=16,fColor=(255,255,255), win=Lumencor_Panel NVAR gIntensity= root:Lumencor:Lumencor_intensity Slider setvar1,pos={Xcoord+20,Ycoord},size={100,100},proc=updateIntensitySlider, title="% Intensity", win=Lumencor_Panel Slider setvar1, disable=0, live=0, fSize=12,limits={0,100,1}, value=gIntensity, disable=0, win=Lumencor_Panel SetVariable setvar3,pos={Xcoord+20,Ycoord+130},size={60,1},limits={0,100,1},title=" ",proc=updateIntensityBox, win=Lumencor_Panel SetVariable setvar3, disable=2, value=gIntensity, win=Lumencor_Panel NVAR gTemp = root:Lumencor:Lumencor_Temp SetVariable setvar2,pos={Xcoord-180,Ycoord+150},size={160,1},limits={1,1000,0},title="Sensor Temp:",fSize=12, proc=readLumencortemp, win=Lumencor_Panel SetVariable setvar2, disable=2, value=gTemp, win=Lumencor_Panel Endif End Function //////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////// //Lumencor checkbox for color selection Function Lumencorcheck (ctrlName,checked) : CheckBoxControl String ctrlName Variable checked NVAR /z event = root:Lumencor:Lumencor_On If (checked==1) // 1 if selelcted, 0 if not If (cmpstr(ctrlName,"check1")==0) //white checkbox CheckBox check1, disable=2, value=01, win=Lumencor_Panel CheckBox check2, disable=0, value=0, win=Lumencor_Panel CheckBox check3, disable=0, value=0, win=Lumencor_Panel Slider setvar1 disable=0, win=Lumencor_Panel Elseif (cmpstr(ctrlName,"check2")==0) //blue checkbox CheckBox check1, disable=0, value=0, win=Lumencor_Panel CheckBox check2, disable=2, value=01, win=Lumencor_Panel CheckBox check3, disable=0, value=0, win=Lumencor_Panel Slider setvar1 disable=1, win=Lumencor_Panel Elseif (cmpstr(ctrlName,"check3")==0) //red checkbox CheckBox check1, disable=0, value=0, win=Lumencor_Panel CheckBox check2, disable=0, value=0, win=Lumencor_Panel CheckBox check3, disable=2, value=1, win=Lumencor_Panel Endif If (event==1) //If light is ON Lumencor_start (ctrlName) Endif Endif End Function //////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////// //Big Button popup window Function BigLumencorPanel (ctrlName,checked) : CheckBoxControl String ctrlName Variable checked If (checked==1) // 1 if selelcted, 0 if not String info = IgorInfo(0) String screen1RectStr = StringByKey("SCREEN1", info) //e.g., "DEPTH=23,RECT=0,0,1280,1024" Variable depth, left, top, right, bottom sscanf screen1RectStr, "DEPTH=%d,RECT=%d,%d,%d,%d", depth, left,top, right, bottom String platform= UpperStr(igorinfo(2)) If (cmpstr(platform,"WINDOWS")==0) NewPanel /N=BigLumencor_Panel /W=(right-250,top,right,150) /FLT=2 Else NewPanel /N=BigLumencor_Panel /W=(right-300,top,right-50,150) /FLT=2 Endif ModifyPanel cbRGB=(30583,30583,30583) DoWindow /HIDE=1 /W=Lumencor_Panel Lumencor_Panel SetDrawLayer UserBack DrawRRect 16,15,240,135 Button button0,pos={30,25},size={200,100},proc=Lumencor_Start,title="On/Off",fSize=58 Checkbox check4,pos={0,0},size={40,10},value=1,disable=0,proc=BigLumencorPanel,title="Close" Else DoWindow /F /HIDE=0 /W=Lumencor_Panel Lumencor_Panel Checkbox check4,value=0, win=Lumencor_Panel Killwindow BigLumencor_Panel Endif End Function //////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////// //Light On/Off Lumencor Function Lumencor_start (ctrlName) : ButtonControl String ctrlName //Lumencor color selection NVAR /z event = root:Lumencor:Lumencor_On NVAR /z gIntensity = root:Lumencor:Lumencor_intensity If (event==0) controlInfo /W=Lumencor_Panel check1 //Determine Color choice white variable checknum1 = V_Value controlInfo /W=Lumencor_Panel check2 //Determine Color choice cyan variable checknum2 = V_Value controlInfo /W=Lumencor_Panel check3 //Determine Color choice red variable checknum3 = V_Value If (checknum1==1) //white VDTWriteBinary2 /TYPE=(0x48) 0x4F, 0x00, 0x50 //Enable all "4F 00 50" Slider setvar1 disable=0, win=Lumencor_Panel Button button3, win=Lumencor_Panel, title="Light is On", fColor=(65535,65535,65535) Button /Z button0, win=BigLumencorPanel, title="Light is On", fColor=(65535,20000,20000) ElseIf (checknum2==1) //blue VDTWriteBinary2 /TYPE=(0x48) 0x4F, 0x7B, 0x50 //Enables Cyan only (460-490nm) Button button3, win=Lumencor_Panel, title="Light is On", fColor=(20000,20000,65535) Button /Z button0, win=BigLumencorPanel, title="Light is On", fColor=(65535,20000,20000) ElseIf (checknum3==1) //red VDTWriteBinary2 /TYPE=(0x48) 0x4F, 0x7E, 0x50 //Enables Red only Button button3, win=Lumencor_Panel, title="Light is On", fColor=(65535,20000,20000) Button /Z button0, win=BigLumencorPanel, title="Light is On", fColor=(65535,20000,20000) Endif event=1 //switch the on/off flag ElseIf ((event==1)||(cmpstr(ctrlName,"Lumencorcheck")==0)) VDTWriteBinary2 /TYPE=(0x48) 0x4F, 0xFF, 0x50 //Full Off "4FFF50" Button button3, win=Lumencor_Panel, title="Light is Off",fColor=(255,255,255) Button /Z button0, win=BigLumencorPanel, title="Light is Off",fColor=(255,255,255) event=0 //switch the on/off flag Endif //readLumencortemp(ctrlName) ControlUpdate /A /W=Lumencor_Panel End //////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////// //Update Lumencor Intensity Slider Function updateIntensitySlider (name, value, event) : SliderControl String name // name of this slider control Variable value // value of slider Variable event // bit field: bit 0: value set; 1: mouse down, 2: mouse up, 3: mouse moved Variable DECintensity String HEXintensity String cmd String low String highNib String lowNib String Byte1 String Byte2 NVAR gIntensity = root:Lumencor:Lumencor_intensity // Lumencor Intensity gIntensity = value DECintensity = round((100-gIntensity)*255/100) //0 equals full intensity; 255 equals off (256 total DAC values) sprintf HEXintensity, "%4X", DECintensity //Byte 2 low nibble is the high nibble for the DAC byte //Byte 1 high nibble is the low nibble for the DAC byte //See handwritten notes for more info low = HEXintensity[2,3] //for values up to 256, only the low nibble matters; high=HEXintensity[0,1] lowNib = low[1] highNib = low[0] Byte1 = "0x"+lowNib+"0" Byte2 = "0xF"+highNib Sprintf cmd, "VDTWriteBinary2 /TYPE=(0x48) 0x53, 0x18, 0x03, 0x0F, %s, %s, 0x50",Byte2,Byte1 // For Violet, Cyan, Green, Red Execute cmd Sprintf cmd, "VDTWriteBinary2 /TYPE=(0x48) 0x53, 0x1A, 0x03, 0x0F, %s, %s, 0x50",Byte2,Byte1 // For Blue and Teal Execute cmd ControlUpdate /A /W=Lumencor_Panel End //////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////// //Update Lumencor Intensity Text Box Function updateIntensityBox (CtrlName,VarNum) String ctrlName Variable VarNum Variable DECintensity String HEXintensity String cmd String low String highNib String lowNib String Byte1 String Byte2 NVAR gIntensity = root:Lumencor:Lumencor_intensity // Lumencor Intensity gIntensity = VarNum DECintensity = round((100-gIntensity)*255/100) //0 equals full intensity; 255 equals off sprintf HEXintensity, "%4X", DECintensity low = HEXintensity[2,3] //for values up to 256, only the low nibble matters; high=HEXintensity[0,1] lowNib = low[1] highNib = low[0] Byte1 = "0x"+lowNib+"0" Byte2 = "0xF"+highNib Sprintf cmd, "VDTWriteBinary2 /TYPE=(0x48) 0x53, 0x18, 0x03, 0x0F, %s, %s, 0x50",Byte2,Byte1 // For Violet, Cyan, Green, Red Execute cmd Sprintf cmd, "VDTWriteBinary2 /TYPE=(0x48) 0x53, 0x1A, 0x03, 0x0F, %s, %s, 0x50",Byte2,Byte1 // For Blue and Teal Execute cmd ControlUpdate /A /W=Lumencor_Panel End //////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////// //Read IIC Temp Sensor Strings Function readLumencortemp(ctrlName) String ctrlName Variable tempTemp NVAR gTemp = root:Lumencor:Lumencor_Temp VDTWriteBinary2 /TYPE=(0x48) 0x53, 0x91, 0x02, 0x50 // Command String to the IIC Temp Sensor VDTReadBinary2 /TYPE=(0x50) tempTemp // Read as unsigned 16-bit. Data is in most-significant 11 bits. tempTemp = trunc(tempTemp / 32) // Shift right dropping 5 low-order bits. tempTemp *= 0.125 // Scale to degrees C. gTemp = tempTemp End //////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////