CLSerialCom.py

#############################################################
 # 
 # FILE:        CLSerialCom.py
 # DATE:        11/16/2021
 # AUTHOR:      Arjun Krishna
 # COMPANY:     BitFlow, Inc.
 # DESCRIPTION: Rudimentary implementation of a Camera Link serial com terminal client using 
 #              mutli-threading to handle user command input and data reception from the camera's
 #              serial device asynchronously.
 #
#############################################################

import sys

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.CLComm as CLCom

import sys
import time
import msvcrt
import threading

g_run = False

# thread to handle reading and printing incoming data
def readThread(ThreadName, CL):
    global g_run

    while(g_run):
        try:
            inStr = CL.SerialRead(256, 10)
            if(len(inStr) != 0):
                print(inStr, end="")
        except:
            pass

#thread to handle reading and printing incoming data using CL 2.1 API
def readThread_2_1(ThreadName, CL):
    global g_run

    while(g_run):
        try:
           inStr = CL.SerialReadEx(256, 10)
           if(len(inStr) != 0):
               print(inStr, end="")
        except:
            pass


def main():
    global g_run

    CL = CLCom.clsCLAllSerial()
    
    #Initialize serial device using board open dialog
    CL.SerialInit()

    #Get serial port info
    portInfo = CL.PortInfo

    print('Camera Link Serial DLL, Manufacturer: ', portInfo.ManufacturerName)
    print('Camera Link Serial DLL, Port ID: ', portInfo.PortID)
    print(portInfo.Version)
    
    supportedBauds = CL.GetSupportedBaudRates()
    bauds = dict(Baud9600=False, Baud19200=False,Baud38400=False, Baud57600=False,Baud115200=False, Baud230400=False,Baud460800=False, Baud921600=False)
    
    #prompt user to make a selection from the supported baud rates list
    for i, v in bauds.items():
        if(supportedBauds & 1):
            bauds[i] = True
        supportedBauds = supportedBauds >> 1

    print("Select Baud Rate:")
    print("\n    BaudRates\t|  Supported")
    print("-------------------------------")
    idx = 0
    for i, v in bauds.items():
        print(idx,'-', i, '\t- ', v)
        idx += 1

    while 1:
        try:
            opt = int(input('Select an option (0 to 7): '))
        except:
            print("Invalid choice. Try again.")
            continue
        if(opt < 0 or opt > 7):
            print("Invalid choice. Try again.")
        elif(list(bauds.values())[opt] == False):
            print("Baud rate not supported. Try again.")
        else:
            CL.SetBaudRate(CLCom.BaudRates(pow(2, opt)))
            break

    #if CL Version 2.1 is supported, use the CL 2.1 API
    if(int(portInfo.Version) >= int(CLCom.Versions.CL_VERSION_2_1)):
        t1 = threading.Thread(target=readThread_2_1, args=('readThread', CL))
    else:
        t1 = threading.Thread(target=readThread, args=('readThread', CL))

    g_run = True
    t1.start()

    print("\nReady")
    print('Type \"Exit\" to quit\n')

    while g_run:
        # Get message from stdio
        for line in sys.stdin:
            # check for exit
            if(line.rstrip('\n').upper() == 'EXIT'):
                g_run = False
                break
            else:
                try:
                    # Add <CR> as required by most cameras and write to serial port
                    CL.SerialWrite(line.rstrip('\n') + '\r', 100)
                except Exception as e:
                    print(e)
        time.sleep(0)
    
    g_run = False
    t1.join()

    # Close port
    CL.SerialClose()

if __name__ == "__main__":
    main()