*
* Blaine Lee Copyright 11/2000 Licence LGPL 2.0
*
+* V 0.4 Major additions to add support for more of the comedilib
+* functions. So far we have support for the comedi_ commands
+* open, close, get_n_subdevices, get_driver_name, get_board_name
+* get_n_channels, get_maxdata, get_n_ranges, get_range,
+* to_phys, from_phys, data_read. Changed the way the debug
+* and printstatus code works.
* V 0.3 changed to tuple parsing & added version number __version__()
* V 0.21 Resynced with sorce that had printstats debugging code in it
* V 0.2 Added card number, so that multiple cards are supported
#include <stdio.h> /* for printf() */
#include <comedilib.h>
+#define Version 4
+
#define maxcards 4
-static short trigdata;
static comedi_t *compy_it[maxcards];
+#ifdef _COMEDILIB_DEPRECATED
static comedi_trig trig;
static int trigchan[2];
-static printstats=1;
-static int debug = 1;
+static short trigdata;
+#endif
+/******************************
+ * Debug flags - set with the
+ * open call. Output is sent
+ * to stderr.
+ *****************************/
+static int printstats=0; // if 1 prints mostly the received calling parms
+static int debug = 0; // if 1 print details of function calls
+
+/******************************
+ * compy_open()
+ * opens the requested comedi device
+ * args - a tuple containing
+ * int - board number (0 to maxcards)
+ * string - the comedi device to open
+ * int - printstats 0-no, 1-yes, 2-also debug
+ ******************************/
+static PyObject *
+compy_open( PyObject *self, PyObject *args )
+{
+ const char *filen;
+ int card;
+
+ if (!PyArg_ParseTuple(args, "isi", &card, &filen, &printstats))
+ return NULL;
+ if (printstats > 1)
+ debug = 1;
+
+ if ((card < 0) || (card >= maxcards))
+ return NULL;
-/*******************************/
+ if(printstats)
+ fprintf(stderr,"compy open '%s'\n",filen);
+
+ compy_it[card]=comedi_open(filen);
+
+ if(debug)
+ fprintf(stderr,"open returned %p\n",compy_it[card]);
+
+ return Py_BuildValue("i", 1);
+}
+
+/******************************
+ * compy_close()
+ * close the requested comedi device
+ * args - a tuple containing
+ * int - board number (0 to maxcards)
+ ******************************/
static PyObject *
-compy_open(self, args)
- PyObject *self;
- PyObject *args;
+compy_close( PyObject *self, PyObject *args )
{
- const char *filen;
- int card;
+ int card;
- if (!PyArg_ParseTuple(args, "isi", &card, &filen, &printstats))
- return NULL;
- if ((card < 0) || (card >= maxcards))
- return NULL;
+ if (!PyArg_ParseTuple(args, "i", &card))
+ return NULL;
+ if ((card < 0) || (card >= maxcards))
+ return NULL;
+ if(printstats)
+ fprintf(stderr,"compy close %d\n",card);
+ comedi_close(compy_it[card]);
- if(printstats)
- printf("compy open '%s'\n",filen);
+ return Py_BuildValue("i", 1);
+}
- compy_it[card]=comedi_open(filen);
+/******************************
+ * compy_get_n_subdevices()
+ * get the number of subdevices
+ * args -
+ * int - board number (0 to maxcards)
+ * returns the number of subdevices on card
+ ******************************/
+static PyObject *
+compy_get_n_subdevices( PyObject *self, PyObject *args )
+{
+ int card;
- if(debug)
- printf("open returned %p\n",compy_it[card]);
+ if (!PyArg_ParseTuple(args, "i:get_n_subdevices", &card))
+ return NULL;
+ if ((card < 0) || (card >= maxcards))
+ return NULL;
+ if(printstats)
+ fprintf(stderr,"compy get_n_subdevices %d\n",card);
- return Py_BuildValue("i", 1);
+ return Py_BuildValue("i", comedi_get_n_subdevices(compy_it[card]));
}
+/******************************
+ * compy_get_driver_name()
+ * get the number of subdevices
+ * args -
+ * int - board number (0 to maxcards)
+ * returns the name of the driver for the board
+ ******************************/
static PyObject *
-compy_data_read(PyObject *self, PyObject *args)
+compy_get_driver_name( PyObject *self, PyObject *args )
{
- int subd, chan;
- int card;
- lsampl_t data;
+ int card;
- if (!PyArg_ParseTuple(args, "(iii)", &card, &subd, &chan))
- return NULL;
- if ((card < 0) || (card >= maxcards))
- return NULL;
- if(debug)
- printf("compy trig dev %d subd %d chan %d\n",card,subd,chan);
+ if (!PyArg_ParseTuple(args, "i:get_driver_name", &card))
+ return NULL;
+ if ((card < 0) || (card >= maxcards))
+ return NULL;
+ if(printstats)
+ fprintf(stderr,"compy get_driver_name (%d)\n",card);
- comedi_data_read(compy_it[card],subd,chan,0,0,&data);
+ return Py_BuildValue("s", comedi_get_driver_name(compy_it[card]));
+}
- if(debug)
- printf("comedi_data_read value %d\n",data);
+/******************************
+ * compy_get_board_name()
+ * get the number of subdevices
+ * args -
+ * int - board number (0 to maxcards)
+ * returns the name of the driver for the board
+ ******************************/
+static PyObject *
+compy_get_board_name( PyObject *self, PyObject *args )
+{
+ int card;
+
+ if (!PyArg_ParseTuple(args, "i:get_board_name", &card))
+ return NULL;
+ if ((card < 0) || (card >= maxcards))
+ return NULL;
+ if(printstats)
+ fprintf(stderr,"compy get_board_name (%d)\n",card);
- return Py_BuildValue("i", data);
+ return Py_BuildValue("s", comedi_get_board_name(compy_it[card]));
}
+/******************************
+ * compy_get_subdevice_type()
+ * get the number of subdevices
+ * args -
+ * int - board number (0 to maxcards)
+ * returns the name of the driver for the board
+ ******************************/
static PyObject *
-compy_trig(self, args)
- PyObject *self;
- PyObject *args;
+compy_get_subdevice_type( PyObject *self, PyObject *args )
{
- int dev, chan, data;
- int card;
+ int card;
+ int sub_dev;
+
+ if (!PyArg_ParseTuple(args, "ii:get_subdevice_type", &card,&sub_dev))
+ return NULL;
+ if ((card < 0) || (card >= maxcards))
+ return NULL;
+ if(printstats)
+ fprintf(stderr,"compy get_subdevice_type (%d)\n",card);
- if (!PyArg_ParseTuple(args, "(iii)i", &card, &dev, &chan, &data))
- return NULL;
- if ((card < 0) || (card >= maxcards))
- return NULL;
- if(printstats)
- printf("compy trig card %d dev %d chanel %d val %d\n",card,dev,chan,data);
+ return Py_BuildValue("i", comedi_get_subdevice_type(compy_it[card],sub_dev));
+}
- trig.subdev=dev;
- trig.chanlist[0]=chan;
- trig.data[0]=data;
+/******************************
+ * compy_get_n_channels()
+ * get the number of channels on subdevice
+ * args -
+ * int - board number (0 to maxcards)
+ * int - subdevice
+ * returns number of channels on subdevice
+ ******************************/
+static PyObject *
+compy_get_n_channels( PyObject *self, PyObject *args )
+{
+ int card;
+ int sub_dev;
- comedi_trigger(compy_it[card],&trig);
+ if (!PyArg_ParseTuple(args, "ii", &card, &sub_dev))
+ return NULL;
+ if ((card < 0) || (card >= maxcards))
+ return NULL;
+ if(printstats)
+ fprintf(stderr,"compy get_n_channels ( %d, %d)\n",card,sub_dev);
- return Py_BuildValue("i", trig.data[0]);
+ return Py_BuildValue("i", comedi_get_n_channels(compy_it[card],sub_dev));
}
+/******************************
+ * compy_get_maxdata()
+ * get the maxdata value for a channel
+ * args -
+ * int - board number (0 to maxcards)
+ * int - subdevice number
+ * int - channel number
+ * returns maximum sample value for channel (0 on error)
+ ******************************/
static PyObject *
-compy_close(self, args)
- PyObject *self;
- PyObject *args;
+compy_get_maxdata( PyObject *self, PyObject *args )
{
- int card;
+ int card;
+ int sub_dev;
+ int channel;
+
+ if (!PyArg_ParseTuple(args, "iii:maxdata", &card,&sub_dev,&channel))
+ return NULL;
+ if ((card < 0) || (card >= maxcards))
+ return NULL;
+ if(printstats)
+ fprintf(stderr,"compy get_maxdata ( %d, %d, %d)\n",card,sub_dev,channel);
+
+ return Py_BuildValue("i", comedi_get_maxdata(compy_it[card],sub_dev,channel));
+}
- if (!PyArg_ParseTuple(args, "i", &card))
- return NULL;
- if ((card < 0) || (card >= maxcards))
- return NULL;
- if(printstats)
- printf("compy close %d\n",card);
- comedi_close(compy_it[card]);
+/******************************
+ * compy_get_n_ranges()
+ * get the number of ranges a channel
+ * args -
+ * int - board number (0 to maxcards)
+ * int - subdevice number
+ * int - channel number
+ * returns number of ranges for channel (-1 on error)
+ ******************************/
+static PyObject *
+compy_get_n_ranges( PyObject *self, PyObject *args )
+{
+ int card;
+ int sub_dev;
+ int channel;
+
+ if (!PyArg_ParseTuple(args, "iii:get_n_ranges", &card,&sub_dev,&channel))
+ return NULL;
+ if ((card < 0) || (card >= maxcards))
+ return NULL;
+ if(printstats)
+ fprintf(stderr,"compy get_n_ranges ( %d, %d, %d)\n",card,sub_dev,channel);
+
+ return Py_BuildValue("i", comedi_get_n_ranges(compy_it[card],sub_dev,channel));
+}
- return Py_BuildValue("i", 1);
+/******************************
+ * compy_get_range()
+ * get the number of ranges a channel
+ * args -
+ * int - board number (0 to maxcards)
+ * int - subdevice number
+ * int - channel number
+ * returns range information on channel
+ * tuple containing
+ * min value
+ * max value
+ * units ( 0-volts, 1-mAmps, 2-none)
+ ******************************/
+static PyObject *
+compy_get_range( PyObject *self, PyObject *args )
+{
+ comedi_range *rng_p;
+ int card;
+ int sub_dev;
+ int channel;
+ int range;
+
+ if (!PyArg_ParseTuple(args, "iiii:get_range", &card,&sub_dev,&channel,&range))
+ return NULL;
+ if ((card < 0) || (card >= maxcards))
+ return NULL;
+ if(printstats)
+ fprintf(stderr,"compy get_n_ranges ( %d, %d, %d, %d)\n",card,sub_dev,channel,range);
+
+ if ((rng_p = comedi_get_range(compy_it[card],sub_dev,channel,range))==NULL)
+ return NULL;
+ else
+ return Py_BuildValue("ddi", rng_p->min, rng_p->max, rng_p->unit);
}
-#define Version 3
+/******************************
+ * compy_to_phys()
+ * convert sample to physical units
+ * args -
+ * int - data
+ * tuple containing range information
+ * min value
+ * max value
+ * units ( 0-volts, 1-mAmps, 2-none)
+ * int - maxdata value for channel
+ * returns physical value (volts) for input
+ ******************************/
+static PyObject *
+compy_to_phys( PyObject *self, PyObject *args )
+{
+ comedi_range rng;
+ lsampl_t data;
+ lsampl_t maxdata;
+
+ if (!PyArg_ParseTuple(args, "i(ddi)i:to_phys",
+ &data,&rng.min,&rng.max,&rng.unit,&maxdata))
+ return NULL;
+ if(printstats)
+ fprintf(stderr,"compy get_to_phys ( %d, %8.3f, %8.3f, %d, %d)\n",
+ data,rng.min,rng.max,rng.unit,maxdata);
+
+ return Py_BuildValue("d",comedi_to_phys(data,&rng, maxdata) );
+}
+/******************************
+ * compy_from_phys()
+ * convert physical units to sample
+ * args -
+ * int - data
+ * tuple containing range information
+ * min value
+ * max value
+ * units ( 0-volts, 1-mAmps, 2-none)
+ * int - maxdata value for channel
+ * returns the sample value (0-maxdata)
+ ******************************/
+static PyObject *
+compy_from_phys( PyObject *self, PyObject *args )
+{
+ comedi_range rng;
+ double data;
+ lsampl_t maxdata;
+
+ if (!PyArg_ParseTuple(args, "d(ddi)i:from_phys",
+ &data,&rng.min,&rng.max,&rng.unit,&maxdata))
+ return NULL;
+ if(printstats)
+ fprintf(stderr,"compy get_from_phys ( %8.3f, %8.3f, %8.3f, %d, %d)\n",
+ data,rng.min,rng.max,rng.unit,maxdata);
+
+ return Py_BuildValue("i",comedi_from_phys(data,&rng, maxdata) );
+}
+/******************************
+ * compy_data_read()
+ * read the requested comedi device
+ * args -
+ * tuple containing
+ * int - board number (0 to maxcards)
+ * int - subdevice number
+ * int - channel number
+ * int - range
+ * int - aref
+ ******************************/
static PyObject *
-compy_version(self, args)
- PyObject *self;
- PyObject *args;
+compy_data_read(PyObject *self, PyObject *args)
{
- if(printstats)
- printf("Compy version %d\n",Version);
+ int card;
+ int subd, chan;
+ unsigned int range = 0;
+ unsigned int aref = 0;
+ lsampl_t data;
+
+ if (!PyArg_ParseTuple(args, "(ii)i|ii:data_read", &card, &subd, &chan,&range,&aref))
+ return NULL;
+ if ((card < 0) || (card >= maxcards))
+ return NULL;
+ if(debug)
+ fprintf(stderr,"compy_data_read dev %d subd %d chan %d range %d aref %d\n",card,subd,chan,range,aref);
+
+ comedi_data_read(compy_it[card],subd,chan,range,aref,&data);
- return Py_BuildValue("i", Version);
+ if(debug)
+ fprintf(stderr,"comedi_data_read value %d\n",data);
+
+ return Py_BuildValue("l", data);
+}
+
+#ifdef _COMEDILIB_DEPRECATED
+/******************************
+ * compy_trig()
+ * read the requested comedi device
+ * args - a tuple containing
+ * int - board number (0 to maxcards)
+ * int - subdevice number
+ * int - channel number
+ ******************************/
+static PyObject *
+compy_trig( PyObject *self, PyObject *args )
+{
+ int dev, chan, data;
+ int card;
+
+ if (!PyArg_ParseTuple(args, "(iii)i", &card, &dev, &chan, &data))
+ return NULL;
+ if ((card < 0) || (card >= maxcards))
+ return NULL;
+ if(printstats)
+ fprintf(stderr,"compy trig card %d dev %d chanel %d val %d\n",card,dev,chan,data);
+
+ trig.subdev=dev;
+ trig.chanlist[0]=chan;
+ trig.data[0]=data;
+
+ comedi_trigger(compy_it[card],&trig);
+
+ return Py_BuildValue("i", trig.data[0]);
+}
+#endif
+
+
+static PyObject *
+compy_version( PyObject *self, PyObject *args )
+{
+ if(printstats)
+ fprintf(stderr,"Compy version %d\n",Version);
+
+ return Py_BuildValue("i", Version);
}
/* List of functions defined in the module */
static PyMethodDef comedi_methods[] = {
- {"open", compy_open, METH_VARARGS},
- {"trig", compy_trig, METH_VARARGS},
- {"data_read", compy_data_read, METH_VARARGS},
- {"close", compy_close, METH_VARARGS},
- {"__version__", compy_version, METH_VARARGS},
- {NULL, NULL} /* sentinel */
+ {"open", compy_open, METH_VARARGS},
+ {"close", compy_close, METH_VARARGS},
+ {"get_n_subdevices",compy_get_n_subdevices, METH_VARARGS},
+ {"get_driver_name", compy_get_driver_name, METH_VARARGS},
+ {"get_board_name", compy_get_board_name, METH_VARARGS},
+ {"get_subdevice_type",compy_get_subdevice_type, METH_VARARGS},
+ {"get_n_channels", compy_get_n_channels, METH_VARARGS},
+ {"get_maxdata", compy_get_maxdata, METH_VARARGS},
+ {"get_n_ranges", compy_get_n_ranges, METH_VARARGS},
+ {"get_range", compy_get_range, METH_VARARGS},
+#ifdef _COMEDILIB_DEPRECATED
+ {"trig", compy_trig, METH_VARARGS},
+#endif
+ {"to_phys", compy_to_phys, METH_VARARGS},
+ {"from_phys", compy_from_phys, METH_VARARGS},
+ {"data_read", compy_data_read, METH_VARARGS},
+ {"__version__", compy_version, METH_VARARGS},
+ {NULL, NULL} /* sentinel */
};
+static char comedi_doc[] = "Module to interface comedi library to Python\n";
+
/* Initialization function for the module (*must* be called initxx) */
DL_EXPORT(void)
-initcomedi()
+initcomedi(void)
{
- /* Create the module and add the functions */
- (void) Py_InitModule("comedi", comedi_methods);
+ /* Create the module and add the functions */
+ (void) Py_InitModule3("comedi", comedi_methods, comedi_doc);
}
--- /dev/null
+#! /usr/bin/env python
+#
+# Sample1.py sample code to use python with comedi via the compy interface.
+# Compy: COMedi PYthon interface
+#
+# Blaine Lee Copyright 11/2000 Licence GPL 2.0
+#
+# V1 reworkd sample.py to test a number of the new functions added to
+# compy.c. Seems to work with the das16 driver. John Conner - 20020304
+# V0 hacked out of working code for others to look at.
+
+############# imports
+import os
+import stat
+import time
+import comedi # important if you want to use compy
+from string import *
+
+board = 0
+sub_dev = 0
+brd_dev = (board,sub_dev)
+channel = 0
+
+debug_level = 0
+
+comedi.open(board,"/dev/comedi0",debug_level)
+print 'The compy versions is ', comedi.__version__()
+
+driver_name = comedi.get_driver_name(board)
+board_name = comedi.get_board_name(board)
+num_subdevices = comedi.get_n_subdevices(board)
+print 'The board uses driver %s, is named %s and has %d subdevices'%(
+ driver_name,board_name,num_subdevices)
+for subdevice in range(0,num_subdevices):
+ print '\tsubdevice %d is type %d'%(
+ subdevice,comedi.get_subdevice_type(board,subdevice))
+print 'Subdevice %d has %d channels'%(
+ sub_dev,comedi.get_n_channels(board,sub_dev))
+
+maxdata = comedi.get_maxdata(board,sub_dev,channel)
+print 'The maximum input count for channel %d is %d'%(channel,maxdata)
+num_ranges = comedi.get_n_ranges(board,sub_dev,channel)
+print 'Channel %d has %d ranges'%(channel,num_ranges)
+for rng in range(0,num_ranges):
+ (min,max,unit) = comedi.get_range(board,sub_dev,channel,rng)
+ if unit == 0: unit = 'volts'
+ if unit == 1: unit = 'mAmps'
+ if unit == 2: unit = ''
+ print '\trange %d %8.3f -- %8.3f %s'%(rng,min,max,unit)
+
+rng = 0
+(min,max,unit) = comedi.get_range(board,sub_dev,channel,rng)
+val = comedi.data_read(brd_dev,channel,rng,0);
+volt = comedi.to_phys(val,(min,max,unit),maxdata);
+print 'range = %d input = %6d (%6d) or %8.4f volts'%(rng, val, val-32768, volt)
+
+rng = 1
+(min,max,unit) = comedi.get_range(board,sub_dev,channel,rng)
+val = comedi.data_read(brd_dev,channel,rng,0);
+volt = comedi.to_phys(val,(min,max,unit),maxdata);
+print 'range = %d input = %6d (%6d) or %8.4f volts'%(rng, val, val-32768, volt)
+
+rng = 2
+(min,max,unit) = comedi.get_range(board,sub_dev,channel,rng)
+val = comedi.data_read(brd_dev,channel,rng,0);
+volt = comedi.to_phys(val,(min,max,unit),maxdata);
+print 'range = %d input = %6d (%6d) or %8.4f volts'%(rng, val, val-32768, volt)
+
+rng = 3
+(min,max,unit) = comedi.get_range(board,sub_dev,channel,rng)
+val = comedi.data_read(brd_dev,channel,rng,0);
+volt = comedi.to_phys(val,(min,max,unit),maxdata);
+print 'range = %d input = %6d (%6d) or %8.4f volts'%(rng, val, val-32768, volt)
+
+rng = 1
+(min,max,unit) = comedi.get_range(board,sub_dev,channel,rng)
+volt = 1.5
+val = comedi.from_phys(volt,(min,max,unit),maxdata)
+print 'range = %d an input of %8.4f volts should give %6d from A/D' % (rng, volt, val)
+
+comedi.close(0)
+