Packaged with setuputils.
[pypiezo.git] / piezo / x_piezo.py
1 from pycomedi.single_aio import AO
2
3 class x_piezoError (Exception) :
4     pass
5
6 class x_piezo :
7     def __init__(self, xp_chan=1) :
8         self.verbose = False
9         self.xpSensitivity = 34.0 # nm/Volt
10         self.gain = 20 # Vpiezo / Voutput
11
12         self.AO = AO(chan=(xp_chan,))
13         self.AO.close()
14         #self.AO = sngAO.sngAOobj([xp_chan], -10, 10)
15
16         self.curOut = [self.nm2out(0)]*1
17         self.xpMax = self.nm2out(2000) # limits at 2 microns
18         self.xpMin = self.nm2out(-2000) # and -2 microns
19
20         self.wanderStep = self.nm2out(5) - self.nm2out(0)
21         # define default value changed callbacks
22         self.setExternalXPiezo = None
23     def curPos(self) :
24         return self.curOut[0]
25     def nm2out(self, nm) :
26         # nm / (nm/Vp * Vp/Vout) = Vout
27         # where Vout is Volts output by the DAQ card
28         # and Vp is Volts applied across the piezo
29         return self.phys_to_out(nm / (self.xpSensitivity * self.gain))
30     def out2nm(self, out) :
31         return self.out_to_phys(out) * self.xpSensitivity * self.gain
32     def out_to_phys(self, output) :
33         return self.AO.comedi_to_phys(0, output)
34     def phys_to_out(self, physical) :
35         return self.AO.phys_to_comedi(0, physical)
36     def pCurVals(self) :
37         print "X piezo output  : %6d" % self.curPos()
38     def jumpToPos(self, pos) :
39         self._check_range(pos)
40         if self.verbose :
41             print "Jump X piezo to %d (%g nm)" % (pos, self.out2nm(pos))
42         self.curOut[0] = pos
43         self.AO.open()
44         #self.AO.reserve()
45         self.AO.write(self.curOut)
46         self.AO.close()
47         #self.AO.unreserve()
48         if self.setExternalXPiezo != None :
49             self.setExternalXPiezo(self.out2nm(self.curPos()))
50         return self.curPos()
51     def wander(self) :
52         """
53         steps in one direction until it hits the boundary,
54         then reverses and walks back the other way.
55         """
56         newPos = self.curPos() + self.wanderStep
57         if self.verbose :
58             print "wander from %d to %d" % (self.curPos(), newPos)
59         try :
60             self._check_range(newPos)
61         except Exception :
62             # reached one limit, so turn around
63             self.wanderStep = -self.wanderStep
64             newPos += 2*self.wanderStep
65         return self.jumpToPos(newPos)           
66     def _check_range(self, pos) :
67         if pos > self.xpMax :
68             raise x_piezoError, "X piezo pos = %d > %d = max" % (pos, self.xpMax)
69         if pos < self.xpMin :
70             raise x_piezoError, "X piezo pos = %d < %d = min" % (pos, self.xpMin)
71
72 def test() :
73     print "test x_piezo()"
74     xp = x_piezo()
75     xp.verbose = True
76     xp.jumpToPos(xp.nm2out(0))
77     xp.wander()
78     xp.wander()
79     xp.wander()
80     xp.pCurVals()
81     curPos = xp.curPos()
82     curPosPhys = xp.out_to_phys(curPos)
83     curPos2 = xp.phys_to_out(curPosPhys)
84     if curPos != curPos2 :
85         raise x_piezoError, "Conversion %d -> %g -> %d not round trip" % (curPos, curPosPhys, curPos2)
86     print "success"
87
88 if __name__ == "__main__" :
89     test()