ExposureControl.py#

#############################################################
 # 
 # FILE:        ExposureControl.py
 # DATE:        04/28/2022
 # COMPANY:     BitFlow, Inc.
 # DESCRIPTION: An example demonstrating the use of the Timing Sequencer
 #              for exposure control. Note that the board and the camera
 #              should be configured correctly for this example to work.
 #
#############################################################

import platform

if(platform.system() == 'Windows'):
    import sys
    import msvcrt

    if (sys.version_info.major >= 3 and sys.version_info.minor >= 8):
        import os
        #Following lines specifying, the location of DLLs, are required for Python Versions 3.8 and greater
        os.add_dll_directory("C:\BitFlow SDK 6.5\Bin64")
        os.add_dll_directory("C:\Program Files\CameraLink\Serial")

import BFModule.BufferAcquisition as Buf
import BFModule.Display as Disp

import time
import threading


def AcqThread(ThreadName, CircAq, BufArray, disp):
    while(CircAq.GetAcqStatus().Start):
        try:
            CurBuf = CircAq.WaitForFrame(1000)
            if(disp.isOpen):
                disp.Update(BufArray[CurBuf.BufferNumber])
        except Exception as e:
            print(e)
            pass

def main():

    print('Exposure Control Example')
    print('---------------------------------')

    numBuffers = 100

    CirAq = Buf.clsCircularAcquisition()

    #Call Open board function by showing the Board select dialog
    CirAq.Open()
    print('Board has been opened\n')

    #Allocate the requested number of buffers
    BufArray = CirAq.BufferSetup(numBuffers)

    #Setup acquisition using the default options
    CirAq.AqSetup(Buf.SetupOptions.setupDefault)

    disp = Disp.clsDisp(CirAq)

    #Open the display surface
    disp.Open()

    t1 = threading.Thread(target=AcqThread, args=('AcqThread', CirAq, BufArray, disp))
    
    CirAq.AqControl(Buf.AcqCommands.Start, Buf.AcqControlOptions.Wait)
    t1.start()

    print('\nEnter \'x\' to Exit')
    print('Enter \'m\' to modify line/frame rate and exposure')
    print('Enter \'r\' to read the exposure control parameters')

    try:
        while True:
            ch = input('\nEnter command: ')
            if(ch.upper()=='X'):
                CirAq.AqControl(Buf.AcqCommands.Stop, Buf.AcqControlOptions.Wait)
                break

            elif(ch.upper() == 'M'):
                print("Please enter line/frame rate and exposure time parameters:")
                expTime = float(input("Enter exposure time in milliseconds: "))
                period = float(input("Enter line/frame period in milliseconds: "))

                print("\nTrigger Options:")
                print("0 - Free run mode")
                print("1 - One-shot from trigger")
                print("2 - One-shot from encoder")
                trigMode = Buf.NTGTrigModes(int(input("Enter trigger mode: ")))

                print(trigMode)

                print("\nExposure signal mode options:")
                print("0 - Asserted low")
                print("1 - Asserted high")
                selection = int(input("Enter exposure signal mode: "))

                if(selection == 0):
                    trigPolarity = False #Buf.TriggerPolarity.AssertedLow
                elif(selection == 1):
                    trigPolarity = True #Buf.TriggerPolarity.AssertedHigh
                else:
                    print("Invalid selection")

                print(trigPolarity)

                print("\nOutput signal options:")
                print("1 - CC1")
                print("2 - CC2")
                print("3 - CC3")
                print("4 - CC4")

                if (CirAq.isGen2):
                    #if (True):
                    print("5 - TRIGGER")
                    print("6 - ENCODER A")
                    print("7 - ENCODER B")
                    userInput = int(input("\nEnter output signal: "))

                    if(userInput < 5):
                        outputSignal = Buf.NTGOutputSignal(userInput)
                    else:
                        if(userInput == 5):
                            outputSignal = Buf.NTGOutputSignal.InputTrig
                        elif(userInput == 6):
                            outputSignal = Buf.NTGOutputSignal.InputEncA
                        elif(userInput == 7):
                            outputSignal = Buf.NTGOutputSignal.InputEncB

                    print(outputSignal)
                else:
                    print("5 - GPOUT0")
                    print("6 - GPOUT1")
                    print("7 - GPOUT2")
                    print("8 - GPOUT3")
                    print("9 - TRIGGER")
                    print("10 - ENCODER")

                    userInput = int(input("\nEnter output signal: "))

                    if(userInput < 5):
                        outputSignal = Buf.NTGOutputSignal(userInput)
                    else:
                        if(userInput == 5):
                            outputSignal = Buf.NTGOutputSignal.OutputGP0
                        elif(userInput == 6):
                            outputSignal = Buf.NTGOutputSignal.OutputGP1
                        elif(userInput == 7):
                            outputSignal = Buf.NTGOutputSignal.OutputGP2
                        elif(userInput == 8):
                            outputSignal = Buf.NTGOutputSignal.OutputGP3
                        elif(userInput == 9):
                            outputSignal = Buf.NTGOutputSignal.InputTrig
                        elif(userInput == 10):
                            outputSignal = Buf.NTGOutputSignal.InputEncA

                    print(outputSignal)

                exp = Buf.ExposureControl(expTime, period, trigMode, trigPolarity, outputSignal)

                CirAq.SetExposureControl(exp)
                print("\nProgramming new exposure parameters")
                
                try:
                    CirAq.SetExposureControl(exp)
                except Exception as e:
                    print(e)
                    print("Error programming new exposure. No changes made\n")
                else:
                    print('Done.')

            elif(ch.upper() == 'R'):
                print('\nReading Exposure control parameters')
                try:
                    exp = CirAq.GetExposureControl()
                except Exception as e:
                    print(e)
                    print("Error reading exposure control parameters.\n")
                else:
                    print('Exposure time =\t\t', exp.ExposurePeriod, ' ms')
                    print('Line Frame Period =\t', exp.LineFramePeriod, ' ms')
                    print('Trigger Mode =\t\t', exp.TriggerMode)
                    print('Assert High =\t\t', exp.AssertHigh)
                    print('Output Signal =')
                    if exp.OutputSignal == (Buf.NTGOutputSignal(0)):
                       print("\t\t\t", exp.OutputSignal)
                    else:
                        i = 1
                        while(i <= 0x2000):
                            if (int(exp.OutputSignal) & int(Buf.NTGOutputSignal(i)) == int(Buf.NTGOutputSignal(i))):
                                print("\t\t\t", Buf.NTGOutputSignal(i))
                            i = i*2;

    except KeyboardInterrupt:
        pass


    t1.join()

    #Close the display surface and free the resources
    disp.Close()

    #Deallocate buffers
    CirAq.BufferCleanup()

    #Close the board
    CirAq.Close()

if __name__ == "__main__":
    main()