Patch from John Conner <conner@empiredi.com>
authorDavid Schleef <ds@schleef.org>
Sat, 9 Mar 2002 00:20:20 +0000 (00:20 +0000)
committerDavid Schleef <ds@schleef.org>
Sat, 9 Mar 2002 00:20:20 +0000 (00:20 +0000)
python/compy.c
python/sample1.py [new file with mode: 0755]

index 815eb5dd712fa9b53e5157e6010cbfe9d3738cbe..f563918ee85c26d75f67722b94a0d2148ea0964f 100644 (file)
@@ -7,6 +7,12 @@
 *
 * 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);
 }
 
 
diff --git a/python/sample1.py b/python/sample1.py
new file mode 100755 (executable)
index 0000000..a83b53a
--- /dev/null
@@ -0,0 +1,82 @@
+#! /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)
+