From 81c07a5d88c8e2cb93355e0d7d8cfc93bd0c874b Mon Sep 17 00:00:00 2001 From: David Schleef Date: Sat, 9 Mar 2002 00:20:20 +0000 Subject: [PATCH] Patch from John Conner --- python/compy.c | 470 ++++++++++++++++++++++++++++++++++++++-------- python/sample1.py | 82 ++++++++ 2 files changed, 475 insertions(+), 77 deletions(-) create mode 100755 python/sample1.py diff --git a/python/compy.c b/python/compy.c index 815eb5d..f563918 100644 --- a/python/compy.c +++ b/python/compy.c @@ -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 @@ -18,136 +24,446 @@ #include /* for printf() */ #include +#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 index 0000000..a83b53a --- /dev/null +++ b/python/sample1.py @@ -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) + -- 2.26.2