Your Ressources

Our Input

Here we provide with some bits of information that we think could be helpfull when using your DLnsec. Let’s start with some software snippets that can help you set up your own software environment for the DLnsec. We do not intend to offer a software suite for the laser, as our customers’ software environments and requirements are very different. However, we will try to give you at least some hints how the DLnsec can be implemented in a software surrounding. Our examples use Python3. However, the DLnsec understands a very simple plain text language that is spoken via virtual serial ports. It is therefore relatively easy to realize something similar in many other programming languages and on different hardware platforms. We use similar functions in our laboratory to calibrate and test the lasers. The code below is an excerpt from our lab software. It works as is when we try it on a Windows PC and on OpenSuse Linux, both with a standard Anaconda/Python3 installation. So we are confident that it will work on other platforms as well. Even if you have problems with the program at first, it is probably easy to fix and make it work on your computer. You are free to use the code snippets we provide and modify them to suit your needs, but please don’t blame us if they don’t work. Unfortunately, we cannot provide support for software development.
A note for first-time users: If you want to test whether your laser works with your computer for the first time, try the method with PuTTY or a similar terminal emulator as described in the user manual.

# -*- coding: utf-8 -*-
"""
Created on Fri Dec 20 15:42:25 2019

@author: Axel Griesmaier, LABS electronics

Copyright 2019 Axel Griesmaier

Permission is hereby granted, free of charge, to any person obtaining 
a copy of this software and associated documentation files (the "Software"), 
to deal in the Software without restriction, including without limitation 
the rights to use, copy, modify, merge, publish, distribute, sublicense, 
and/or sell copies of the Software, and to permit persons to whom the Software 
is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all 
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 
BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 
ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 
SOFTWARE.

"""

import serial
import six
import sys
import os
import time
import glob

open_connections = {}
nconnected = 0

def available_serial_ports(): 
    portsavail = []
    if sys.platform.startswith('win'):
        ports = ['COM%s' % (i + 1) for i in range(256)]
    elif sys.platform.startswith('linux') or sys.platform.startswith('cygwin'):
        ports = glob.glob('/dev/tty[A-Za-z]*')
    else:
        raise EnvironmentError('platform not supported')
    for port in ports:
        try:
            s = serial.Serial(port)
            s.close()
            portsavail.append(port)
        except (OSError, serial.SerialException):
            pass
    return portsavail  

def find_laser():
    ports = available_serial_ports()
    nfound = 0
    lasers = {}
    for port in ports:
        try:
            s = serial.Serial(port=port, baudrate=9600, bytesize=serial.EIGHTBITS, parity=serial.PARITY_NONE, timeout = 1)
            s.read()
            strn = 'HOWDY\n'
            s.write(strn.encode())
            answer = s.readline().strip().decode()
            s.read()
            if answer.startswith('Ready'):
                s.write(b'*IDN\n')
                answer = s.readline().strip().decode()
                s.read()
                nfound = nfound + 1
                if ('DLNSEC' in answer.upper()):
                    try:
                        model, serno = answer.split('_')
                    except:
                        model='unknown'
                        serno='00000'
                    lasers[nfound] = (port, serno, model)
                else:
                    model = 0
                    serno = 0
                    lasers[nfound] = (port, serno, model)
            s.close()
        except:
            pass
    print('')
    if (nfound>1):
        print("WARNING: More than one laser connected.") 
    print('')
    return lasers
class DLnsec():
    def __init__(self, port = ''):
        self.port = port
        if ( port != '' ):
            self.open()
        else:
            self = connect()
        self.pre = None
        self.width = None
        self.laserison = None
        self.modeis = None
        self.powerset = None
        self.t_cycle = None
        self.freq = None
    def open(self):
        self.serial = serial.Serial(port=self.port,baudrate=9600,bytesize=serial.EIGHTBITS,parity=serial.PARITY_NONE,timeout=2)
        self.serial.write_timeout = 1
        self.serial.read_timeout = 1
    def close(self):
        self.serial.close()
        del self
    def write(self,cmd):
        self.serial.write(cmd + b'\n')
    def read(self, cmd):
        self.serial.write(cmd + b'\n')
        answer = self.serial.readline().strip().decode()
        self.serial.read()
        return answer
    def on(self):
        self.write(b'*ON')
        self.laserison = 1
    def off(self):
        self.write(b'*OFF')
        self.laserison = 0
    def set_power(self,pwr):
        strn = 'PWR' + '{:0d}'.format(pwr)
        self.write(strn.encode())
        answer = self.get_power()
        return answer
    def pwr(self, pwr):
        answer = self.set_power(pwr)
        return answer
    def power(self, pwr):
        return self.set_power(pwr)
    def get_power(self):
        answer = self.read(b'PWR?')
        self.powerset = int(answer)
        return int(answer)
    def set_mode(self, mode):
        assert mode in ['LAS', 'INT', 'EXT', 'STOP']
        self.write(bytes(mode, encoding='utf-8')+b'')
        self.modeis = mode
    def set_width(self, width):
        assert type(width) == int
        assert width >=0
        assert width <=255
        self.width = width
        self.write(b'WID %i'%int(width))
        self.t_width = 1/16e6*self.pre*(width+1)
    def set_prescaler(self, pre):
        assert type(pre) == int
        assert pre in [1, 8, 64, 256, 1024]
        self.pre = pre
        self.write(b'PRE %i'%int(pre))
        self.freq = 16e6/256/pre
        self.t_cycle = 1 / self.freq
		
def connect(ser = ''):
    """open conneciton to laser or return handle if already open"""
    if ser == '':
        if len(open_connections) == 0: #no open connections 
            all_lasers = find_laser() #find all available lasers
            if (len(all_lasers) == 0):
                raise RuntimeError('No lasers found.')    
            next_laser = all_lasers.popitem() #next available laser
            port = next_laser[1][0]
            ser = next_laser[1][1]
            model = next_laser[1][2]
            laser = DLnsec(port)
            open_connections[ser] = laser
            return laser
        else: #there are open connections
			if (len(all_lasers) > 0): #there are lasers connected but not yet open
				next_laser = all_lasers.popitem() #next available laser
				port = next_laser[1][0]
				ser = next_laser[1][1]
				model = next_laser[1][2]
				laser = DLnsec(port)
				open_connections[ser] = laser
				return laser
			else:
				raise RuntimeError('No more un-connected lasers.') 
    else:
        if ser in open_connections: # ser ist schon geƶffnet
            return open_connections[ser]
        else: # ser ist noch nicht offen
            all_lasers = find_laser()
            if ser in all_lasers: #is ser a valid port?
                port = all_lasers[ser][1][0]
                laser = DLnsec(port)
                open_connections[ser] = laser
                return laser
            else:
                raise RuntimeError( 'Couldn\'t find DLnsec on port ' + ser )      
def get_open_connections():
    return open_connections

if __name__ == '__main__':
    lasers = find_laser()
    print ('Connected lasers:')
    print (lasers)

If you try this Python3 program make sure you have all libraries installed and you have the right to access the serial ports of your computer (root privileges or a change of the user rights for ‘/dev/ttyXYZ’ or similar might be necessary on Linux platforms). If everything works correctly, something like this should work and get the DLnsec running:

In [1]: runfile('/home/axel/controlDLnsec.py', wdir='/home/axel')

WARNING: More than one laser connected.

Connected lasers:
{1: ('/dev/ttyUSB2', '00050', 'DLnsec0633'), 2: ('/dev/ttyUSB1', '00049', 'DLnsec0450'), 3: ('/dev/ttyUSB0', '00048', 'DLnsec0520')}
In [2]: laser1 = connect()
WARNING: More than one laser connected.
In [3]: laser2 = connect()
In [4]: laser1.on()
In [5]: laser1.set_power(10)
In [6]: laser1.set_mode('LAS')
In [7]: laser2.on()
In [8]: laser2.set_power(10)
In [9]: laser2.set_mode('LAS')

As you can see, the connect() selects the next available laser and establishes a serial connection to it. The connect() and find_laser() functions save you from looking into the hardware-manager to identify the right serial port. However, if you want to establish a connection to a laser connected to a specific port, using DLnsec directly is even simpler and also faster. The DLnsec class provides simple methods for controlling the laser. If you save the above code as DLnsec.py, you can import the class and use it in your own programs.

import DLnsec
laser = DLnsec('COM4')
laser.get_power()

should work

Comments are closed.