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
