add pty-gpib-emulator from github
This commit is contained in:
33
pty-gpib-emulator/python/Device.py
Normal file
33
pty-gpib-emulator/python/Device.py
Normal file
@@ -0,0 +1,33 @@
|
||||
##
|
||||
## **** Device Class ****
|
||||
## by Aidan Macdonald (aidan.plenert.macdonald@gmail.com)
|
||||
##
|
||||
## Standard framework for the a Device that is attached
|
||||
## to the PTY_Interface
|
||||
##
|
||||
|
||||
|
||||
class Device:
|
||||
##
|
||||
##%% No initialization
|
||||
##
|
||||
|
||||
##%% handleCMD(pty_interface, command, arguments)
|
||||
## A device attached to a PTY_Interface will handle commands
|
||||
## passed to it from the PTY_Interface by a call made to
|
||||
## this function.
|
||||
##
|
||||
## pty_interface will be a referance to the interface that called
|
||||
## this function
|
||||
##
|
||||
## command will be a string with the text of the command read
|
||||
## from the pty device
|
||||
##
|
||||
## arguments is an array of the arguments to said command read
|
||||
## from the pty device
|
||||
##
|
||||
## The string returned by this function will be written to
|
||||
## the pty device
|
||||
##
|
||||
def handleCMD(self, fpl, cmd, args=[]):
|
||||
return ""
|
87
pty-gpib-emulator/python/PTY_Interface.py
Normal file
87
pty-gpib-emulator/python/PTY_Interface.py
Normal file
@@ -0,0 +1,87 @@
|
||||
##
|
||||
## **** PTY_Interface Class ****
|
||||
## by Aidan Macdonald (aidan.plenert.macdonald@gmail.com)
|
||||
##
|
||||
## This class generates a pty device that emulates the
|
||||
## tty device created by GPIB controllers such as
|
||||
## Prologix GPIB-USB Controller (prologix.biz)
|
||||
##
|
||||
## This class does NOT emulate the controller, but the
|
||||
## controller must be attached to this PTY Interface
|
||||
##
|
||||
## I may switch between the terms tty device and pty device.
|
||||
## They refer to the same thing.
|
||||
##
|
||||
|
||||
|
||||
import os
|
||||
import Device, Prologix
|
||||
|
||||
class Interface:
|
||||
|
||||
##%% Initialization - Interface(default_device, default_address)
|
||||
## accepts arguments default_device and default_address
|
||||
## the default_device will be connected at the default_address
|
||||
##
|
||||
## If the Interface address (PTY_Interface.addr) is changed, the
|
||||
## no longer have anything attached and will become functionless.
|
||||
## UNLESS, the default device handles the address change and copies itself
|
||||
## to the new address (Prologix_GPIB_USB does this, OR there is
|
||||
## another device attached there.
|
||||
##
|
||||
## if no arguments are given at initialization, defaults are
|
||||
## Device.Prologix_GPIB-USB at address 0
|
||||
##
|
||||
def __init__(self,
|
||||
default_device=Prologix.Prologix_GPIB_USB(),
|
||||
default_address=0 ):
|
||||
self.m, self.s = os.openpty()
|
||||
self.devices = {default_address:default_device}
|
||||
self.addr = default_address
|
||||
|
||||
##%% printFilename()
|
||||
## Prints the path to the PTY device generated (ie /dev/pts/2)
|
||||
##
|
||||
def printFilename(self):
|
||||
name = os.ttyname(self.s)
|
||||
print(name)
|
||||
return name
|
||||
|
||||
##%% run(readLen)
|
||||
## Runs the emulator which will read all statements written from the outside
|
||||
## to the pty device at the location given by self.printFilename(), then
|
||||
## runs what was read through self.handleInput(tty_in) and writes output
|
||||
## back to the pty device to be read from the outside
|
||||
##
|
||||
def run(self, readLen=100):
|
||||
self.running = True
|
||||
while (self.running):
|
||||
tty_in = os.read(self.m, readLen)
|
||||
for tty_out in self.handleInput(tty_in):
|
||||
os.write(self.m, tty_out)
|
||||
|
||||
|
||||
##%% handleInput(tty_in)
|
||||
## Recieves raw input that was read from the pty device, and
|
||||
## breaks it up and send it to the device listed at the current
|
||||
## address. That device must handle the command via dev.handleCMD(cmd, args)
|
||||
##
|
||||
def handleInput(self, tty_in):
|
||||
tty_in = tty_in.strip()
|
||||
|
||||
if tty_in != "" and self.addr in self.devices:
|
||||
dev = self.devices[self.addr]
|
||||
for cmd in tty_in.strip().split(";"):
|
||||
p = cmd.strip().split(" ")
|
||||
yield dev.handleCMD(self, p[0], p[1:]) + "\n"
|
||||
|
||||
yield "" # Must be a null string to prevent infinite loop
|
||||
|
||||
##%% addDevice(device, address)
|
||||
## Preferred way of connecting a device to the interface
|
||||
## at a given address
|
||||
##
|
||||
def addDevice(self, dev, addr):
|
||||
self.devices[addr] = dev
|
||||
|
||||
|
129
pty-gpib-emulator/python/PowerSupply.py
Normal file
129
pty-gpib-emulator/python/PowerSupply.py
Normal file
@@ -0,0 +1,129 @@
|
||||
##
|
||||
## <<<< Powersupply Emulators >>>>
|
||||
## by Aidan Macdonald (aidan.plenert.macdonald@gmail.com)
|
||||
##
|
||||
## Contains classes that emulate powersupplies by
|
||||
## building off the Device framework
|
||||
##
|
||||
|
||||
import Device, Prologix
|
||||
|
||||
## **** Power Supply class ****
|
||||
## by Aidan Macdonald (aidan.plenert.macdonald@gmail.com)
|
||||
##
|
||||
## General model of a basic Power Supply
|
||||
##
|
||||
|
||||
class PowerSupply(Prologix.Prologix_GPIB_USB):
|
||||
|
||||
##%% Initialization PowerSupply(volt, current)
|
||||
## Creates a framework for a Powersupply, but only binds
|
||||
## a reset call to "RST?". All other functions have been
|
||||
## left unbound so that children can bind them to respective
|
||||
## commands
|
||||
##
|
||||
## voltage and current default to 10
|
||||
##
|
||||
def __init__(self, volt=10, cur=10):
|
||||
Prologix.Prologix_GPIB_USB.__init__(self)
|
||||
self.addCMD("RST?", self.reset)
|
||||
|
||||
self.voltage = volt
|
||||
self.current = cur
|
||||
|
||||
##%% reset(pty, args)
|
||||
## returns that the device has been reset
|
||||
##
|
||||
def reset(self, fpl, args=[]):
|
||||
return "Power Supply has been reset"
|
||||
|
||||
##%% version(pty, args)
|
||||
## overrides the version function from superclass
|
||||
## left unbound here, because it was bound in the
|
||||
## superclass.
|
||||
##
|
||||
def version(self, fpl, args=[]):
|
||||
return "Power Supply Version 1.GEN"
|
||||
|
||||
##%% on(pty, args)
|
||||
## turns power supply on
|
||||
##
|
||||
def on(self, fpl, args=[]):
|
||||
return self.version(fpl, args) + " in now ON"
|
||||
##%% off(pty, args)
|
||||
## turns power supply off
|
||||
##
|
||||
def off(self, fpl, args=[]):
|
||||
return self.version(fpl, args) + " in now OFF"
|
||||
|
||||
##%% getVoltage(pty, args)
|
||||
## returns voltage
|
||||
##
|
||||
def getVoltage(self, fpl, args=[]):
|
||||
return self.voltage
|
||||
|
||||
##%% getCurrent(pty, args)
|
||||
## returns current
|
||||
##
|
||||
def getCurrent(self, fpl, args=[]):
|
||||
return self.current
|
||||
|
||||
|
||||
##%% setVoltage(pty, args)
|
||||
## sets voltage
|
||||
##
|
||||
def setVoltage(self, fpl, args=[]):
|
||||
try:
|
||||
self.voltage = float(args[0])
|
||||
return ""
|
||||
except:
|
||||
return "ERROR"
|
||||
##%% setCurrent(pty, args)
|
||||
## sets current
|
||||
##
|
||||
def setCurrent(self, fpl, args=[]):
|
||||
try:
|
||||
self.current = float(args[0])
|
||||
return ""
|
||||
except:
|
||||
return "ERROR"
|
||||
|
||||
|
||||
##
|
||||
## **** E3631A Power Supply Class ****
|
||||
## by Aidan Macdonald (aidan.plenert.macdonald@gmail.com)
|
||||
##
|
||||
## Emulates the E3631A Power Supply
|
||||
##
|
||||
|
||||
class E3631A(PowerSupply):
|
||||
##%% Initialization - E3631A(voltage, current)
|
||||
## see PowerSupply.PowerSupply documentation
|
||||
##
|
||||
## adds bindings for all of the PowerSupply functions
|
||||
##
|
||||
def __init__(self, volt=10, cur=10):
|
||||
PowerSupply.__init__(self, volt, cur)
|
||||
|
||||
self.addCMD("OUTP", self.outp)
|
||||
self.addCMD("MEAS:VOLT:DC", self.getVoltage)
|
||||
self.addCMD("MEAS:CURR:DC", self.getCurrent)
|
||||
self.addCMD("SET:VOLT:DC", self.setVoltage)
|
||||
self.addCMD("SET:CURR:DC", self.setCurrent)
|
||||
|
||||
##%% version(pty, args)
|
||||
## returns version
|
||||
##
|
||||
def version(self, fpl, args=[]):
|
||||
return "E3631A Power Supply"
|
||||
|
||||
##%% outp(pty, args)
|
||||
## function binding for the "OUTP" command
|
||||
## Used to turn the device on and off
|
||||
##
|
||||
def outp(self, fpl, args=[]):
|
||||
if args[0] == "ON":
|
||||
return self.on(fpl, args)
|
||||
elif args[0] == "OFF":
|
||||
return self.off(fpl, args)
|
||||
return ""
|
85
pty-gpib-emulator/python/Prologix.py
Normal file
85
pty-gpib-emulator/python/Prologix.py
Normal file
@@ -0,0 +1,85 @@
|
||||
##
|
||||
## **** Prologix_GPIB_USB Class ****
|
||||
##
|
||||
## A Device that emulates the functionality of the
|
||||
## Prologix GPIB-USB Controller (prologix.biz)
|
||||
##
|
||||
|
||||
|
||||
import Device, PTY_Interface
|
||||
|
||||
class Prologix_GPIB_USB(Device.Device):
|
||||
|
||||
##%% Initialization - Prologix_GPIB_USB()
|
||||
## Does not take arguments, but is VERY important
|
||||
## All classes that attempt to inherit this class,
|
||||
## must call this initialization.
|
||||
##
|
||||
## This creates a dictionary containing all the commands
|
||||
## to be run. If this dictionary is not created, this class
|
||||
## does nothing
|
||||
##
|
||||
def __init__(self):
|
||||
self.cmds = { "++ver":self.version, # "COMMAND":HANDLER
|
||||
"++addr":self.addr,
|
||||
"++kill":self.kill}
|
||||
|
||||
##%% handleCMD(pty_interface, command, arguments)
|
||||
## See Device.handleCMD documentation
|
||||
##
|
||||
## In Prologix_GPIB_USB, this function makes use of the
|
||||
## map made in initialization to find the command and
|
||||
## its associated handler, then call the handler and pass in
|
||||
## the pty_interface and the arguments
|
||||
##
|
||||
def handleCMD(self, fpl, cmd, args=[]):
|
||||
out = Device.Device.handleCMD(self, fpl, cmd, args)
|
||||
if out != "":
|
||||
return out
|
||||
elif cmd in self.cmds:
|
||||
return self.cmds[cmd](fpl, args)
|
||||
else:
|
||||
return ""
|
||||
|
||||
##%% version(pty, args)
|
||||
## Returns the device version
|
||||
##
|
||||
def version(self, fpl, args=[]):
|
||||
return "Prologix Version 1.1 Simulator (Python)"
|
||||
|
||||
##%% addr(pty, args)
|
||||
## If no arguments are given, returns the current address
|
||||
## of the pty interface
|
||||
##
|
||||
## if args are given, then an integer is parsed out of
|
||||
## the first argument and set as the address. This ensures
|
||||
## that a device exists at the following address
|
||||
##
|
||||
## Any errors return "ERROR"
|
||||
##
|
||||
def addr(self, fpl, args=[]):
|
||||
if args == []:
|
||||
return str(fpl.addr)
|
||||
else:
|
||||
try:
|
||||
fpl.addr = int(args[0])
|
||||
if not fpl.addr in fpl.devices:
|
||||
fpl.addDevice(PrologixAdapter(), fpl.addr)
|
||||
return ""
|
||||
except:
|
||||
return "ERROR"
|
||||
##%% kill(pty, args)
|
||||
## Stops the pty interface from running
|
||||
##
|
||||
def kill(self, fpl, args=[]):
|
||||
fpl.running = False
|
||||
return ""
|
||||
|
||||
##%% addCMD(command, handler_function)
|
||||
## Adds a command to the dictionary
|
||||
## Handler function must be of the form
|
||||
## func(pty_interface, arguments):
|
||||
##
|
||||
def addCMD(self, cmd, func):
|
||||
self.cmds[cmd] = func
|
||||
|
77
pty-gpib-emulator/python/SourceMeasurement.py
Normal file
77
pty-gpib-emulator/python/SourceMeasurement.py
Normal file
@@ -0,0 +1,77 @@
|
||||
##
|
||||
## <<<< Source Measurement Unit Emulators >>>>
|
||||
## by Aidan Macdonald (aidan.plenert.macdonald@gmail.com)
|
||||
##
|
||||
## Contains classes that emulate Source Measurement Units
|
||||
##
|
||||
|
||||
import Device, Prologix
|
||||
|
||||
## **** Source Measurement Class ****
|
||||
## by Aidan Macdonald (aidan.plenert.macdonald@gmail.com)
|
||||
##
|
||||
## General model of a basic Source Measurement Unit
|
||||
##
|
||||
|
||||
class SourceMeasurement(Prologix.Prologix_GPIB_USB):
|
||||
|
||||
##%% Initialization SourceMeasurement()
|
||||
## Creates the framework
|
||||
##
|
||||
|
||||
def __init__(self):
|
||||
Prologix.Prologix_GPIB_USB.__init__(self)
|
||||
|
||||
|
||||
|
||||
## **** Keithley 2400 Class ****
|
||||
## by Aidan Macdonald
|
||||
##
|
||||
## Support given for some commands
|
||||
##
|
||||
|
||||
from random import uniform as rand
|
||||
|
||||
class Keithley_2400(SourceMeasurement):
|
||||
|
||||
##%% Initialization - Keithley_2400()
|
||||
## Loads commands
|
||||
##
|
||||
|
||||
def __init__(self):
|
||||
SourceMeasurement.__init__(self)
|
||||
self.addCMD("IDN?", self.version)
|
||||
self.addCMD("*RST", self.noth)
|
||||
self.addCMD("*CLS", self.noth)
|
||||
self.addCMD("ABOR", self.noth)
|
||||
self.addCMD("*CLS", self.noth)
|
||||
self.addCMD("SYST:BEEP:STAT", self.noth)
|
||||
self.addCMD("SOURCE:CLEAR:AUTO", self.noth)
|
||||
self.addCMD("FORM:ELEM", self.noth)
|
||||
self.addCMD(":SOUR:FUNC", self.noth)
|
||||
self.addCMD("read?", self.randFloats)
|
||||
|
||||
## noth(pty, args)
|
||||
## Does nothing
|
||||
##
|
||||
def noth(self, fpl, args):
|
||||
pass # Do nothing
|
||||
|
||||
|
||||
def version(self, fpl, args):
|
||||
return 'KEITHLEY INSTRUMENTS INC.,MODEL 2400.EMULATOR'
|
||||
|
||||
## randFloats(pty, args)
|
||||
## returns a string of random floats
|
||||
##
|
||||
def randFloats(self, fpl, args):
|
||||
return str(rand(0, 2)) + ", " str(rand(0, 2))
|
||||
|
||||
## handleCMD(fpl, cmd, args)
|
||||
## Modified to be case insensitive
|
||||
##
|
||||
def handleCMD(self, fpl, cmd, args):
|
||||
SourceMeasurement.handleCMD(self, fpl, cmd.upper(), args)
|
||||
|
||||
|
||||
|
12
pty-gpib-emulator/python/fake_prologix.py
Executable file
12
pty-gpib-emulator/python/fake_prologix.py
Executable file
@@ -0,0 +1,12 @@
|
||||
#!/usr/bin/python
|
||||
|
||||
import PTY_Interface
|
||||
import PowerSupply
|
||||
|
||||
pty = PTY_Interface.Interface()
|
||||
pty.addDevice(PowerSupply.PowerSupply(), 5)
|
||||
pty.addDevice(PowerSupply.E3631A(), 3)
|
||||
|
||||
pty.printFilename()
|
||||
pty.run()
|
||||
|
5
pty-gpib-emulator/python/mkWiki.sh
Executable file
5
pty-gpib-emulator/python/mkWiki.sh
Executable file
@@ -0,0 +1,5 @@
|
||||
#!/bin/bash
|
||||
|
||||
NAME=`echo $1 | awk -F'.' '{ print $1 }'`
|
||||
|
||||
cat $1 | grep "##" | sed s/"##"//g | sed s/"\*\*"/"="/g | sed s/"<<<<"/"="/g | sed s/">>>>"/"="/g | sed s/"%%"/"*"/g > $2
|
14
pty-gpib-emulator/python/test.sh
Executable file
14
pty-gpib-emulator/python/test.sh
Executable file
@@ -0,0 +1,14 @@
|
||||
#!/bin/bash
|
||||
|
||||
cat < $1 &
|
||||
|
||||
echo "++ver" > $1
|
||||
echo "++addr" > $1
|
||||
echo "++addr 12" > $1
|
||||
echo "++addr" > $1
|
||||
|
||||
while true
|
||||
do
|
||||
read CMD
|
||||
echo $CMD > $1
|
||||
done
|
Reference in New Issue
Block a user