1 """Use Comedi drivers for single-shot digital input/output
3 Being single-shot implementations, read/writes will be software timed,
4 so this module would not be a good choice if you need millisecond
5 resolution. However, it does provide a simple and robust way to
6 generate/aquire signals at 1 second and greater timescales.
13 class dioError (Exception) :
18 def __init__(self, filename="/dev/comedi0", subdevice=2, chan=(0,1,2,3), aref=0, range=0, output=True) :
19 self.filename = filename
20 self.subdev = subdevice
25 self.dev = c.comedi_open(filename)
27 raise dioError, "Cannot open %s" % self.filename
28 type = c.comedi_get_subdevice_type(self.dev, self.subdev)
29 if type != c.COMEDI_SUBD_DIO :
30 raise dioError, "Comedi subdevice %d has wrong type %d" % (self.subdev, type)
35 def set_to_output(self) :
36 for chan in self.chan :
37 rc = c.comedi_dio_config(self.dev, self.subdev, chan, c.COMEDI_OUTPUT)
38 if rc != 1 : # yes, comedi_dio_config returns 1 on success, -1 on failure, as of comedilib-0.8.1
39 raise dioError, 'comedi_dio_config("%s", %d, %d, %d) returned %d' % (self.filename, self.subdev, chan, c.COMEDI_OUTPUT, rc)
41 def set_to_input(self) :
42 for chan in self.chan :
43 rc = c.comedi_dio_config(self.dev, self.subdev, chan, c.COMEDI_INPUT)
45 raise dioError, 'comedi_dio_config("%s", %d, %d, %d) returned %d' % (self.filename, self.subdev, chan, c.COMEDI_INPUT, rc)
47 def write_chan_index(self, chan_index, data) :
48 if self.output != True :
49 raise dioError, "Must be an output to write"
50 rc = c.comedi_data_write(self.dev, self.subdev, self.chan[chan_index], self.range, self.aref, data);
51 if rc != 1 : # the number of samples written
52 raise dioError, "comedi_data_write returned %d" % rc
53 def read_chan_index(self, chan_index) :
54 if self.output == True :
55 raise dioError, "Must be an input to read"
56 rc, data = c.comedi_data_read(self.dev, self.subdev, self.chan[chan_index], self.range, self.aref);
57 if rc != 1 : # the number of samples read
58 raise dioError, "comedi_data_read returned %d" % rc
60 def write_port(self, data) :
61 "Channel significance increases with array index"
62 for i in range(len(self.chan)) :
63 self.write_chan_index(i, (data >> i) % 2)
66 for i in range(len(self.chan)) :
67 data += self.read_chan_index(i) << i
70 class write_dig_port (dio_obj) :
71 def __call__(self, data) :
77 d.write_chan_index(0, 1)
78 d.write_chan_index(0, 0)
81 data = d.read_chan_index(0)
82 print "channel %d is %d" % (d.chan[0], data)
84 print "port value is %d" % data
85 print "dio_obj success"
87 def _test_write_dig_port() :
89 for data in [0, 1, 2, 3, 4, 5, 6, 7] :
91 print "write_dig_port success"
95 _test_write_dig_port()
97 if __name__ == "__main__" :