Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
298c1ea
Simple script to test cobolt laser
dccote May 22, 2019
fb62a99
Create README.md
May 22, 2019
d053f5a
Reorganizatio of files for teaching
dccote May 22, 2019
b8ab17c
Simple class-based strategy, for teaching purposes
dccote May 22, 2019
14e1a05
Created a debug port for cobolt.py, alllowed correction for CoboltLas…
dccote May 22, 2019
17a7422
Moved modifications to section 2-class
dccote May 22, 2019
9cb148e
Better printout, typo in 2-constructor fixed.
dccote May 22, 2019
07ecb03
Update README.md
dccote May 22, 2019
dff2a74
Update README.md
dccote May 22, 2019
f636106
Update README.md
dccote May 22, 2019
ee78a45
Fixed buffer that was not emptying
dccote May 22, 2019
36f834d
Update cobolt.py
dccote May 22, 2019
c636e02
Completed commands (p?) and added read() to DebugPort
dccote May 22, 2019
8322398
Merge branch 'master' into physicalDevice
dccote May 22, 2019
c38a9b9
Merge branch 'MaxCobolt' into physicalDevice
dccote May 22, 2019
282b351
Fixed up PhysicalDevice, CoboltLaserDevice and LaserDevice so they ar…
dccote May 22, 2019
510b7fa
Separate files, reorganized, started unit tests on Devices
dccote May 23, 2019
f212f79
Fixed testEcho and several bugs in DebugEchoCommPort
dccote May 23, 2019
5c65a29
Update testEcho.py
dccote May 23, 2019
d0e62b7
Update testEcho.py
dccote May 23, 2019
b12012d
Added a flush() method to flush (i.e. discard) all buffers.
dccote May 23, 2019
ff383b2
Before flushing() check port is open
dccote May 23, 2019
663e8c8
CoboltDebugSerial tested. readline removed.
dccote May 23, 2019
ddf070d
Test port completely, 100% coverage
dccote May 23, 2019
db3be91
coboltDevice test completed.
dccote May 23, 2019
7010ef3
Update CoboltDebugSerial.py
dccote May 23, 2019
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 32 additions & 0 deletions 1-simple/cobolt.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
try:
import serial as SP
except:
exit("pyserial must be installed with: pip install pyserial")

""" Simplest, most trivial strategy to talk to the Cobolt
laser, change its power. See manual in ../manuals/ page 27"""

port = SP.Serial("COM1") # Use '/dev/xxx on macOS'

""" Read laser power. Note:
1) b'' means binary
2) ends with \r meaning ASCII 13 dec
3) readline() will read up to next \n
"""

port.write(b'pa?\r')
reply = port.readline()
power = int(reply)
print("Power is {0}.".format(power))

# Set power
port.write(b'p 0.01\r')
# There is no reply according to protocol defined p.27

# Read power again
port.write(b'pa?\r')
reply = port.readline()
power = int(reply)
print("Power is now {0}.".format(power))

port.close()
41 changes: 41 additions & 0 deletions 2-class/cobolt.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
try:
import serial as SP
except:
exit("pyserial must be installed with: pip install pyserial")

""" Class-oriented strategy to talk to the Cobolt
laser, change its power. See manual in ../manuals/ page 27"""

class CoboltLaser:

def __init__(self, portName):
""" portName : "COM1", "/dev/xxx", etc...
opens automatically on creation """
self.port = None
self.port = SP.Serial(portName)

def __del__(self):
if self.port is not None:
self.port.close()

def setPower(self, powerInWatts):
command = "p {0:0.3f}\r".format(powerInWatts)
data = bytearray(command, "utf-8")
self.port.write(data)

def power(self):
self.port.write(b'pa?\r')
reply = self.port.readline()
print(reply)
power = float(reply.decode())
return power


if __name__ == "__main__":
try:
laser = CoboltLaser("COM1")
except:
exit("No laser found on COM1")

laser.setPower(powerInWatts=0.1)
print("Power is {0:0.3f} W".format(laser.power()))
69 changes: 69 additions & 0 deletions 3-class+debugPort/CoboltDebugSerial.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
class CoboltDebugSerial:
def __init__(self):
self.outputBuffer = bytearray()
self.lineEnding = b'\r'
self.power = 0.1
self.requestedPower = 0
self.isOpen = False

def open(self):
if self.isOpen:
raise IOError()
else:
self.isOpen = True

return

def close(self):
if not self.isOpen:
raise IOError()
else:
self.isOpen = False

return

def read(self, length) -> bytearray:
data = bytearray()
for i in range(0, length):
if len(self.outputBuffer) > 0:
byte = self.outputBuffer.pop(0)
data.append(byte)
else:
raise CommunicationReadTimeout("Unable to read data")

return data


def write(self, data:bytearray) -> int :
string = data.decode('utf-8')

match = re.search("pa\\?", string)
if match is not None:
replyData = bytearray("{0}\r".format(self.power), encoding='utf-8')
self.outputBuffer.extend(replyData)
return len(data)

match = re.search("p\\?", string)
if match is not None:
replyData = bytearray("{0}\r".format(self.requestedPower), encoding='utf-8')
self.outputBuffer.extend(replyData)
return len(data)

match = re.search("p (\\d+\\.?\\d+)\r", string)
if match is not None:
self.power = match.groups()[0]
return len(data)

raise ValueError("Unknown command: {0}".format(data))

def readline(self) -> bytearray:
data = bytearray()
byte = b''
while byte != self.lineEnding:
if len(self.outputBuffer) > 0:
byte = self.outputBuffer.pop(0)
data.append(byte)
else:
break

return data
121 changes: 121 additions & 0 deletions 3-class+debugPort/cobolt.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
try:
import serial as SP
except:
exit("pyserial must be installed with: pip install pyserial")
import re

class CoboltDebugSerial:
def __init__(self):
self.outputBuffer = bytearray()
self.lineEnding = b'\r'
self.power = 0.1
self.requestedPower = 0
self.isOpen = True

def open(self):
if self.isOpen:
raise IOError()
else:
self.isOpen = True

return

def close(self):
if not self.isOpen:
raise IOError()
else:
self.isOpen = False

return

def read(self, length) -> bytearray:
data = bytearray()
for i in range(0, length):
if len(self.outputBuffer) > 0:
byte = self.outputBuffer.pop(0)
data.append(byte)
else:
raise CommunicationReadTimeout("Unable to read data")

return data


def write(self, data:bytearray) -> int :
string = data.decode('utf-8')

match = re.search("pa\\?", string)
if match is not None:
replyData = bytearray("{0}\r".format(self.power), encoding='utf-8')
self.outputBuffer.extend(replyData)
return len(data)

match = re.search("p\\?", string)
if match is not None:
replyData = bytearray("{0}\r".format(self.requestedPower), encoding='utf-8')
self.outputBuffer.extend(replyData)
return len(data)

match = re.search("p (\\d+\\.?\\d+)\r", string)
if match is not None:
self.power = match.groups()[0]
return len(data)

raise ValueError("Unknown command: {0}".format(data))

def readline(self) -> bytearray:
data = bytearray()
byte = b''
while byte != self.lineEnding:
if len(self.outputBuffer) > 0:
byte = self.outputBuffer.pop(0)
data.append(byte)
else:
break

return data

""" Class-oriented strategy to talk to the Cobolt
laser, change its power. See manual in ../manuals/ page 27"""

class CoboltLaser:

def __init__(self, portName):
""" portName : "COM1", "/dev/xxx", etc...
opens automatically on creation """
self.port = None
if portName == "debug":
self.port = CoboltDebugSerial()
else:
self.port = SP.Serial(portName)

def __del__(self):
if self.port is not None:
self.port.close()

def setPower(self, powerInWatts):
command = "p {0:0.3f}\r".format(powerInWatts)
data = bytearray(command, "utf-8")
self.port.write(data)

def power(self):
self.port.write(b'pa?\r')
reply = self.port.readline()
power = float(reply.decode())
return power


if __name__ == "__main__":
try:
laser = CoboltLaser("COM1")
except:
laser = CoboltLaser("debug")

laser.setPower(powerInWatts=0.1)
print("Power is {0:0.3f} W".format(laser.power()))

laser.setPower(powerInWatts=0.01)
print("Power is {0:0.3f} W".format(laser.power()))

laser.setPower(powerInWatts=0.001)
print("Power is {0:0.3f} W".format(laser.power()))

108 changes: 108 additions & 0 deletions CoboltDebugSerial.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
import re
from CommunicationPort import *

class CoboltDebugSerial:
def __init__(self):
self.outputBuffer = bytearray()
self.lineEnding = b'\r'
self.power = 0.1
self.isOn = True
self.requestedPower = 0
self._isOpen = True

@property
def is_open(self):
return self._isOpen

def open(self):
if self._isOpen:
raise IOError("port is already open")
else:
self._isOpen = True

return

def close(self):
self._isOpen = False

return

def flush(self):
return

def read(self, length) -> bytearray:
data = bytearray()
for i in range(0, length):
if len(self.outputBuffer) > 0:
byte = self.outputBuffer.pop(0)
data.append(byte)
else:
raise CommunicationReadTimeout("Unable to read data")

return data


def write(self, data:bytearray) -> int :
string = data.decode('utf-8')

match = re.search("pa\\?", string)
if match is not None:
replyData = bytearray("{0:0.4f}\r\n".format(self.power), encoding='utf-8')
self.outputBuffer.extend(replyData)
return len(data)

match = re.search("p\\?", string)
if match is not None:
replyData = bytearray("{0:0.4f}\r\n".format(self.requestedPower), encoding='utf-8')
self.outputBuffer.extend(replyData)
return len(data)

match = re.search("p (\\d+\\.?\\d+)\r", string)
if match is not None:
self.power = float(match.groups()[0])
replyData = bytearray("OK\r\n", encoding='utf-8')
self.outputBuffer.extend(replyData)
return len(data)

match = re.search("l1\r", string)
if match is not None:
self.isOn = True
replyData = bytearray("OK\r\n", encoding='utf-8')
self.outputBuffer.extend(replyData)
return len(data)

match = re.search("l0\r", string)
if match is not None:
self.isOn = False
replyData = bytearray("OK\r\n", encoding='utf-8')
self.outputBuffer.extend(replyData)
return len(data)

match = re.search("sn\\?\r", string)
if match is not None:
replyData = bytearray("123456\r\n", encoding='utf-8')
self.outputBuffer.extend(replyData)
return len(data)

match = re.search("ilk\\?\r", string)
if match is not None:
replyData = bytearray("1\r\n", encoding='utf-8')
self.outputBuffer.extend(replyData)

return len(data)

# Error:
replyData = bytearray("Syntax error: {0}", encoding='utf-8')
self.outputBuffer.extend(replyData)

# def readline(self) -> bytearray:
# data = bytearray()
# byte = b''
# while byte != self.lineEnding:
# if len(self.outputBuffer) > 0:
# byte = self.outputBuffer.pop(0)
# data.append(byte)
# else:
# break

# return data
Loading