Пример #1
0
int init_daq(double min_range, double max_range, int range_update) {
    int i = 0;

    if (!DEV_OPEN) {
        it = comedi_open("/dev/comedi0");
        if (it == NULL) {
            comedi_perror("comedi_open");
            ADC_OPEN = FALSE;
            DEV_OPEN = FALSE;
            return -1;
        }
        DEV_OPEN = TRUE;
    }

    subdev_ai = comedi_find_subdevice_by_type(it, COMEDI_SUBD_AI, subdev_ai);
    if (subdev_ai < 0) {
        return -2;
        ADC_OPEN = FALSE;
    }


    subdev_ao = comedi_find_subdevice_by_type(it, COMEDI_SUBD_AO, subdev_ao);
    if (subdev_ao < 0) {
        HAS_AO = FALSE;
    } else {
        HAS_AO = TRUE;
    }

    printf("Subdev AI  %i ", subdev_ai);
    channels_ai = comedi_get_n_channels(it, subdev_ai);
    printf("Analog  Channels %i ", channels_ai);
    maxdata_ai = comedi_get_maxdata(it, subdev_ai, i);
    printf("Maxdata %i ", maxdata_ai);
    ranges_ai = comedi_get_n_ranges(it, subdev_ai, i);
    printf("Ranges %i ", ranges_ai);
    ad_range = comedi_get_range(it, subdev_ai, i, ranges_ai - 1);
    if (range_update) {
        ad_range->min = min_range;
        ad_range->max = max_range;
    }
    printf(": ad_range .min = %.3f, max = %.3f\n", ad_range->min,
            ad_range->max);

    if (HAS_AO) {
        printf("Subdev AO  %i ", subdev_ao);
        channels_ao = comedi_get_n_channels(it, subdev_ao);
        printf("Analog  Channels %i ", channels_ao);
        maxdata_ao = comedi_get_maxdata(it, subdev_ao, i);
        printf("Maxdata %i ", maxdata_ao);
        ranges_ao = comedi_get_n_ranges(it, subdev_ao, i);
        printf("Ranges %i ", ranges_ao);
        da_range = comedi_get_range(it, subdev_ao, i, ranges_ao - 1);
        printf(": da_range .min = %.3f, max = %.3f\n", da_range->min,
                da_range->max);
    }

    ADC_OPEN = TRUE;
    comedi_set_global_oor_behavior(COMEDI_OOR_NUMBER);
    return 0;
}
Пример #2
0
ComediChan::ComediChan(comedi_t *dev, unsigned minor, unsigned subdev, unsigned chan, unsigned range, unsigned aref, const double * range_override_min, const double * range_override_max, DAQTaskProxy *daq)
  : m_dev(dev), m_minor(minor), m_subdev(subdev), m_chan(chan), m_range(range), m_aref(aref), daq(daq)
{

  m_isdio = m_isai = m_isao = false;

  int t = comedi_get_subdevice_type(m_dev, m_subdev);
  if (t == COMEDI_SUBD_AO) m_isao = true;
  else if (t == COMEDI_SUBD_AI) m_isai = true;
  else if (t == COMEDI_SUBD_DIO) m_isdio = true;
  else {
    err = "Invalid parameters.";
    return;
  }
  if (range_override_min) m_rangeMin = *range_override_min;
  else {
    comedi_range *r = comedi_get_range(dev, subdev, chan, range);
    if (!r) { err = "Invalid parameters."; return; }
    m_rangeMin = r->unit == UNIT_mA ? r->min*1e3 : r->min;
  }
  if (range_override_max) m_rangeMax = *range_override_max;
  else {
    comedi_range *r = comedi_get_range(dev, subdev, chan, range);
    if (!r) { err = "Invalid parameters."; return; }
    m_rangeMax = r->unit == UNIT_mA ? r->max*1e3 : r->max;
  }
  m_maxdata = comedi_get_maxdata(dev, subdev, chan);
  if (!m_maxdata) m_maxdata = 1;
  err = "";
}
Пример #3
0
double readpin(int chan)
{
  comedi_t *it;
  lsampl_t data, maxdata;
  comedi_range *rang;
  int readres;
  double outval;

  if((it=comedi_open("/dev/comedi0"))==NULL) {
    printf("fail open");
  }

  comedi_set_global_oor_behavior(COMEDI_OOR_NUMBER);

  readres=comedi_data_read(it,subdev,chan,0,aref, & data);
  if(!readres) {
    comedi_perror("comedi_data_read: ");
  }
 

  rang = comedi_get_range(it, subdev, chan, 0);
  maxdata = comedi_get_maxdata(it, subdev, chan);

  outval = comedi_to_phys(data, rang, maxdata);

  printf("data=%d\noutval=%g\nreadres=%d\n",data, outval, readres);

  return outval;
}
Пример #4
0
 /**
  * @brief AIO_channel Constructor
  * @param dname Device name
  * @param sd    subdevice
  * @param ch    channel
  * @param rng   range
  * @param input true if it's input channel
  * @param uID   channel unique ID
  */
    AIO_channel(QString dname,int sd,int ch, int rng, int input, int uID)
        {
        deviceName=dname;subdevice =sd; Channel=ch; is_input=input;ChannelID=uID;
        rangeN=rng;
        range = comedi_get_range(it,subdevice, Channel,rangeN);
        maxdata = comedi_get_maxdata(it, subdevice,Channel);
        }
Пример #5
0
/**
 * @brief constructor from the ini file
 *
 * @param keyname Ini file keyword
 * @param input true if it is an input channel
 */
    AIO_channel(QString keyname, int input)
        {
        read_fromIni(keyname, &deviceName, &subdevice, &Channel, &rangeN);
        range = comedi_get_range(it,subdevice, Channel,rangeN);
        maxdata = comedi_get_maxdata(it, subdevice,Channel);
        is_input=input;
        }
Пример #6
0
ComediAnalogOutputSoftCal::ComediAnalogOutputSoftCal(const char *deviceFile, uint outputSubdevice,
                                                     uint writeChannel, double outputConversionFactor,
                                                     uint aref, bool resetOutput)
        : ComediAnalogIOSoftCal(deviceFile, outputSubdevice, &writeChannel, 1, PLUS_MINUS_TEN, aref),
          m_outputConversionFactor(outputConversionFactor), m_resetOutput(resetOutput)
{
        Logger(Debug, "ComediAnalogOutputSoftCal::ComediAnalogOutputSoftCal()\n");
        int flag = comedi_get_softcal_converter(m_subdevice, m_channels[0], m_range,
                        COMEDI_FROM_PHYSICAL, m_calibration, &m_converter);
        if (flag != 0) {
                Logger(Critical, "comedi_get_softcal_converter: %s.\n", comedi_strerror(comedi_errno()));
                throw "Error in comedi_get_softcal_converter()";
        }
#ifdef TRIM_ANALOG_OUTPUT
        // get physical data range for subdevice (min, max, phys. units)
        m_dataRange = comedi_get_range(m_device, m_subdevice, m_channels[0], m_range);
        Logger(Debug, "Range for 0x%x (%s):\n\tmin = %g\n\tmax = %g\n", m_dataRange,
                        (m_dataRange->unit == UNIT_volt ? "volts" : "milliamps"),
                        m_dataRange->min, m_dataRange->max);
        if(m_dataRange == NULL) {
                Logger(Critical, "comedi_get_range: %s.\n", comedi_strerror(comedi_errno()));
                throw "Error in comedi_get_range()";
        }
#endif
}
Пример #7
0
double get_adc_volts(int chan, int diff, int range)
{
	lsampl_t data[OVER_SAMPLE]; // adc burst data buffer
	int retval;
	comedi_range *ad_range;
	comedi_insn daq_insn;

	ADC_ERROR = FALSE; // global fault flag

	if (diff == TRUE) {
		aref_ai = AREF_DIFF;
	} else {
		aref_ai = AREF_GROUND;
	}

	// configure the AI channel for reads
	daq_insn.subdev = subdev_ai;
	daq_insn.chanspec = CR_PACK(chan, range, aref_ai);
	daq_insn.insn = INSN_READ;
	daq_insn.n = OVER_SAMPLE;
	daq_insn.data = data;

	retval = comedi_do_insn(it, &daq_insn); // send one instruction to the driver
	if (retval < 0) {
		comedi_perror("comedi_do_insn in get_adc_volts");
		ADC_ERROR = TRUE;
		bmc.raw[chan] = 0;
		return 0.0;
	}

	ad_range = comedi_get_range(it, subdev_ai, chan, range);
	bmc.raw[chan] = data[0];
	return comedi_to_phys(data[0], ad_range, maxdata_ai); // return the double result
}
Пример #8
0
bool ComediAnalogOutputHardCal::initialise()
{
        // get physical data range for subdevice (min, max, phys. units)
        m_dataRange = comedi_get_range(m_device, m_subdevice, m_channels[0], m_range);
        Logger(Debug, "Range for 0x%x (%s):\n\tmin = %g\n\tmax = %g\n", m_dataRange,
                        (m_dataRange->unit == UNIT_volt ? "volts" : "milliamps"),
                        m_dataRange->min, m_dataRange->max);
        if(m_dataRange == NULL) {
                comedi_perror(m_deviceFile);
                comedi_close(m_device);
                return false;
        }
        
        // read max data value
        m_maxData = comedi_get_maxdata(m_device, m_subdevice, m_channels[0]);
        Logger(Debug, "Max data = %ld\n", m_maxData);
}
Пример #9
0
double read_volts(int subdev, int chan, int range) {
  lsampl_t data, maxdata;
  int readres;
  comedi_range *rang;
  double outval;

  comedi_set_global_oor_behavior(COMEDI_OOR_NUMBER);
  readres=comedi_data_read(it,subdev,chan,range,aref, & data);
  if(!readres) {
    comedi_perror("comedi_data_read: ");
  }
  rang = comedi_get_range(it, subdev, chan, range);
  maxdata = comedi_get_maxdata(it, subdev, chan);
  outval = comedi_to_phys(data, rang, maxdata);
  //printf("data=%d\noutval=%g\nreadres=%d\n",data, outval, readres);
  return outval;

}
Пример #10
0
int setup_read_wave(int subd, int chan, int range, int npnts) {
  //  assert(it!=NULL);

  printf("setup_read_wave...");fflush(stdout);
  int ret;
  int wv_n=++cmd->chanlist_len, wv_i=wv_n-1;
  lsampl_t data;
  //printf("wv_i %d \n", wv_i);

  ///assert(cmd!=NULL);

  if(cmd->chanlist==NULL) {
    cmd->chanlist=malloc(sizeof(unsigned int));
  } else {
    if(realloc(cmd->chanlist, (wv_n)*sizeof(unsigned int))==NULL) 
      { printf("realloc cmd fail \n"); return -1;}
  }
  cmd->chanlist[wv_i]= CR_PACK(chan,range,aref);
  if(npnts>cmd->stop_arg) cmd->stop_arg=npnts;

  cmd->scan_end_arg=wv_n;

  //test_board_read(it);

  comedi_command_test(it,cmd);
  ret=comedi_command_test(it,cmd);
  if(ret!=0){
    comedi_perror("comedi_command_test fail on read");
    return -1;
  }
  //test_board_read(it);

  inp_res[wv_i]=malloc(npnts*sizeof(double));
  inp_rang[wv_i]=comedi_get_range(it, subd, chan, range);
  inp_maxdata[wv_i]=comedi_get_maxdata(it, subd, chan);
  comedi_data_read(it,subd,chan,range,aref, & data);
  //printf("found sdtype %d \n", comedi_find_subdevice_by_type(it, COMEDI_SUBD_AI,0));

  //printf("setup subd %d chan %d rng %d:  data=%d outval=%g\n",subd, chan, range, data, comedi_to_phys(data, inp_rang[wv_i], inp_maxdata[wv_i]));
  printf("done\n");fflush(stdout);

  return wv_i;
}
Пример #11
0
int init_daq(void)
{
	int i = 0, range_index = 0;
	comedi_range *ad_range;

	if (!DEV_OPEN) {
		it = comedi_open(comedi_dev);
		if (it == NULL) {
			comedi_perror("comedi_open");
			ADC_OPEN = FALSE;
			DEV_OPEN = FALSE;
			HAVE_DIO = FALSE;
			HAVE_AI = FALSE;
			return -1;
		}
		DEV_OPEN = TRUE;
	}

	subdev_ai = comedi_find_subdevice_by_type(it, COMEDI_SUBD_AI, subdev_ai);
	if (subdev_ai < 0) {
		return -1;
		ADC_OPEN = FALSE;
	}

	printf("Subdev  %i ", subdev_ai);
	channels_ai = comedi_get_n_channels(it, subdev_ai);
	printf("Analog  Channels %i ", channels_ai);
	maxdata_ai = comedi_get_maxdata(it, subdev_ai, i);
	printf("Maxdata %i ", maxdata_ai);
	ranges_ai = comedi_get_n_ranges(it, subdev_ai, i);
	printf("Ranges %i ", ranges_ai);

	for (range_index = 0; range_index < ranges_ai; range_index++) {
		ad_range = comedi_get_range(it, subdev_ai, i, range_index);
		printf(": range %i, min = %.1f, max = %.1f ", range_index,
		ad_range->min, ad_range->max);
	}
	printf("\n");

	ADC_OPEN = TRUE;
	comedi_set_global_oor_behavior(COMEDI_OOR_NUMBER);
	return 0;
}
Пример #12
0
/**
 * facq_comedi_misc_get_min:
 * @dev: A comedi_t device.
 * @subindex: The subdevice index.
 * @chanlist: A #FacqChanlist object.
 * @err: A #GError.
 *
 * It's equal to facq_comedi_misc_get_max() but instead of returning the
 * maximum values, returns the minimum expected real values.
 *
 * Returns: A gdouble array. Free it with g_free():
 */
gdouble *facq_comedi_misc_get_min(comedi_t *dev,guint subindex,const FacqChanlist *chanlist,GError **err)
{
	guint iochans_n = 0, i = 0, chanspec = 0, chan = 0,range = 0;
	GError *local_err = NULL;
	gdouble *min = NULL;
	comedi_range *rng = NULL;

	g_return_val_if_fail(FACQ_IS_CHANLIST(chanlist),NULL);

	iochans_n = facq_chanlist_get_io_chans_n(chanlist);
	if(!iochans_n){
		g_set_error_literal(&local_err,
			FACQ_COMEDI_MISC_ERROR,
				FACQ_COMEDI_MISC_ERROR_FAILED,
					"The chanlist is empty");
		goto error;
	}
	min = g_new0(gdouble,iochans_n);
	for(i = 0;i < iochans_n;i++){
		chanspec = facq_chanlist_get_io_chanspec(chanlist,i);
		facq_chanlist_chanspec_to_src_values(chanspec,&chan,
						     &range,NULL,NULL);
		rng = comedi_get_range(dev,subindex,chan,range);
		if(!rng){
			g_set_error_literal(&local_err,
				FACQ_COMEDI_MISC_ERROR,
					FACQ_COMEDI_MISC_ERROR_FAILED,
						comedi_strerror(comedi_errno()));
		}
		min[i] = rng->min;
	}

	return min;
	
	error:
	if(min)
		g_free(min);
	if(local_err)
		g_propagate_error(err,local_err);
	return NULL;
}
Пример #13
0
double get_adc_volts(int chan, int diff, int range)
{
	lsampl_t data[OVER_SAMPLE];	// adc burst data buffer
	int retval, intg, i;
	comedi_range *ad_range;
	comedi_insn daq_insn;

	ADC_ERROR = FALSE;	// global fault flag

	if (diff == TRUE) {
		aref_ai = AREF_DIFF;
	} else {
		aref_ai = AREF_GROUND;
	}

	intg = 0;	// clear the integration counter
	// configure the AI channel for burst reads of OVER_SAMPLE times with the passed params
	daq_insn.subdev = subdev_ai;
	daq_insn.chanspec = CR_PACK(chan, range, aref_ai);
	daq_insn.insn = INSN_READ;
	daq_insn.n = OVER_SAMPLE;
	daq_insn.data = data;

	retval = comedi_do_insn(it, &daq_insn); // send one instruction to the driver
	if (retval < 0) {
		comedi_perror("comedi_do_insn in get_adc_volts");
		ADC_ERROR = TRUE;
		bmc.raw[chan] = 0;
		return 0.0;
	}
	for (i = 0; i < OVER_SAMPLE; i++) {
		intg += data[i];
	}
	data[0] = intg >> OVER_SAMPLE_SHIFTS;

	ad_range = comedi_get_range(it, subdev_ai, chan, range);
	bmc.raw[chan] = data[0];
	return comedi_to_phys(data[0], ad_range, ((1 << (OVER_SAMPLE_ADC + OVER_SAMPLE_BITS)) - 1)); // return the double result
}
Пример #14
0
void print_card_info(comedi_t *card)
{

  //We get the number of ranges for this card
  int n_ranges;
  int chan=1;
  n_ranges=comedi_get_n_ranges( card, SUBDEV, chan);
  printf("This card have %d ranges\n",n_ranges);
  int i;
  
  //We display information about these ranges
  comedi_range *act_range;
  for(i=0;i<n_ranges;i++)
    {
      act_range=comedi_get_range( card, SUBDEV, chan,i);
      printf("range %d\t min %f\t max %f\t unit: %s\n",i,act_range->min,act_range->max,display_unit(act_range->unit));
    }

  //We get the maxdata
  int maxdata;
  maxdata=comedi_get_maxdata(card,SUBDEV,chan);
  printf("maximum data value %d\n",maxdata);

}
Пример #15
0
/* -------------------------------------------------------------------- */
static long dsetWrite_devAoSyncComedi(aoRecord *pao) {
  CONTEXT *p_myContext; 
  COMEDIDEV_AO *p_myAnalogOutput;
  double myMinimumVoltage;
  double myMaximumVoltage;
  char p_myWarmstartFilename[BUFLEN];
  FILE *p_myFileHandle;


  dsetLog(3,__FILE__ "[%d] -> %s(%s)\n", __LINE__, __func__,pao->name);

  pao->pact=TRUE;

  p_myContext=(CONTEXT *)pao->dpvt;
  p_myAnalogOutput=p_myContext->p_analogOutput;
  myMaximumVoltage=p_myContext->maximumVoltage;
  myMinimumVoltage=p_myContext->minimumVoltage;

  if (pao->val>pao->drvh) pao->val=pao->drvh;
  if (pao->val<pao->drvl) pao->val=pao->drvl;

  umask(0000);
  sprintf(p_myWarmstartFilename, WARMSTART_FILE_PREFIX "/%s", pao->name);
  p_myFileHandle=fopen(p_myWarmstartFilename,"w");
  if (p_myFileHandle==NULL) {
    dsetLog(1, __FILE__ "[%d] Error: %s\n", __LINE__, pao->name);
    dsetLog(1, __FILE__ "[%d] Error: Couldn't open file >%s<\n",
		    __LINE__, p_myWarmstartFilename);
    sleep(SLEEPTIME_ERROR);
    return(ERROR);
  }
  fprintf(p_myFileHandle,"%lg",pao->val);
  fclose(p_myFileHandle);

  
  if (pao->drvh!=myMaximumVoltage || pao->drvl!=myMinimumVoltage) {
    p_myAnalogOutput->range=getOptimalOperatingRange(pao);
    p_myAnalogOutput->c_range=comedi_get_range(p_myAnalogOutput->device,
                                             p_myAnalogOutput->subdevice,
                                             p_myAnalogOutput->channel,
                                             p_myAnalogOutput->range);	
  }
    
  p_myAnalogOutput->data=comedi_from_phys(
			pao->val,
			p_myAnalogOutput->c_range,
			p_myAnalogOutput->maxdata);

  dsetLog(7, __FILE__ "[%d] Synchronous write of a single value\n", __LINE__);
 
  if( comedi_data_write(
			p_myAnalogOutput->device,
                        p_myAnalogOutput->subdevice,
                        p_myAnalogOutput->channel,
                        p_myAnalogOutput->range,
                        p_myAnalogOutput->aref,
                        p_myAnalogOutput->data) <= ERROR ) {
        comedi_perror(p_myAnalogOutput->p_deviceFilename);
        sleep(SLEEPTIME_ERROR);
        return(ERROR);
  }


  dsetLog(2,__FILE__ "[%d] %s -> %lg\n", __LINE__, pao->name, pao->val);

  pao->pact=FALSE;

  dsetLog(3, __FILE__ "[%d] <- %s\n", __LINE__, __func__ );

  /* CONVERT according to calibration settings */
  return(CONVERT);

}
Пример #16
0
MainWindow::MainWindow( QWidget *parent ) :
    QWidget(parent),
    adChannel(0),
    psthLength(1000),
    psthBinw(20),
    spikeThres(1),
    psthOn(0),
    spikeDetected(false),
    time(0),
    linearAverage(0)
{
  // initialize comedi
  const char *filename = "/dev/comedi0";

  /* open the device */
  if( (dev = comedi_open(filename)) == 0 )
  {
    comedi_perror(filename);
    exit(1);
  }

  // do not produce NAN for out of range behaviour
  comedi_set_global_oor_behavior(COMEDI_OOR_NUMBER); 

  maxdata = comedi_get_maxdata(dev, COMEDI_SUB_DEVICE, 0);
  crange = comedi_get_range(dev,COMEDI_SUB_DEVICE,0,0);
  numChannels = comedi_get_n_channels(dev, COMEDI_SUB_DEVICE);

  chanlist = new unsigned[numChannels];

  /* Set up channel list */
  for( int i=0; i<numChannels; i++ )
    chanlist[i] = CR_PACK(i, COMEDI_RANGE_ID, AREF_GROUND);

  int ret = comedi_get_cmd_generic_timed( dev,
                                          COMEDI_SUB_DEVICE,
                                          &comediCommand,
                                          numChannels,
                                          (int)(1e9/(SAMPLING_RATE)) );

  if(ret < 0)
  {
    printf("comedi_get_cmd_generic_timed failed\n");
    exit(-1);
  }

  /* Modify parts of the command */
  comediCommand.chanlist = chanlist;
  comediCommand.stop_src = TRIG_NONE;
  comediCommand.stop_arg = 0;

  /* comedi_command_test() tests a command to see if the
   * trigger sources and arguments are valid for the subdevice.
   * If a trigger source is invalid, it will be logically ANDed
   * with valid values (trigger sources are actually bitmasks),
   * which may or may not result in a valid trigger source.
   * If an argument is invalid, it will be adjusted to the
   * nearest valid value.  In this way, for many commands, you
   * can test it multiple times until it passes.  Typically,
   * if you can't get a valid command in two tests, the original
   * command wasn't specified very well. */
  ret = comedi_command_test(dev, &comediCommand);

  if(ret < 0)
  {
    comedi_perror("comedi_command_test");
    exit(-1);
  }

  fprintf(stderr, "first test returned %d\n", ret);

  ret = comedi_command_test(dev, &comediCommand);
  if(ret < 0)
  {
    comedi_perror("comedi_command_test");
    exit(-1);
  }

  fprintf(stderr, "second test returned %d\n", ret);

  if(ret != 0)
  {
    fprintf(stderr,"Error preparing command\n");
    exit(-1);
  }

  // the timing is done channel by channel
  // this means that the actual sampling rate is divided by
  // number of channels
  if ((comediCommand.convert_src ==  TRIG_TIMER)&&(comediCommand.convert_arg)) {
	  sampling_rate=(((double)1E9 / comediCommand.convert_arg)/numChannels);
  }
  
  // the timing is done scan by scan (all channels at once)
  // the sampling rate is equivalent of the scan_begin_arg
  if ((comediCommand.scan_begin_src ==  TRIG_TIMER)&&(comediCommand.scan_begin_arg)) {
	  sampling_rate=(double)1E9 / comediCommand.scan_begin_arg;
  }

  // 50Hz or 60Hz mains notch filter
  iirnotch = new Iir::Butterworth::BandStop<IIRORDER>;
  assert( iirnotch != NULL );
  iirnotch->setup (IIRORDER, sampling_rate, NOTCH_F, NOTCH_F/10.0);

  /* start the command */
  ret = comedi_command(dev, &comediCommand);
  if(ret < 0)
  {
    comedi_perror("comedi_command");
    exit(1);
  }

  int subdev_flags = comedi_get_subdevice_flags(dev, COMEDI_SUB_DEVICE);

  if( (sigmaBoard = subdev_flags & SDF_LSAMPL) )
    readSize = sizeof(lsampl_t) * numChannels;
  else
    readSize = sizeof(sampl_t) * numChannels;

  //  Initialize data for plots
  for(int i=0; i<MAX_PSTH_LENGTH; i++)
  {
    xData[i] = i;     // time axis
    yData[i] = 0;
    timeData[i] = double(i)*psthBinw; // psth time axis
    spikeCountData[i] = 0;
    psthData[i] = 0;
  }

  // the gui, straight forward QT/Qwt
  resize(640,420);
  QHBoxLayout *mainLayout = new QHBoxLayout( this );

  QVBoxLayout *controlLayout = new QVBoxLayout;
  mainLayout->addLayout(controlLayout);

  QVBoxLayout *plotLayout = new QVBoxLayout;
  plotLayout->addStrut(400);
  mainLayout->addLayout(plotLayout);

  // two plots
  RawDataPlot = new DataPlot(xData, yData, psthLength, 
			     crange->max, crange->min, this);
  plotLayout->addWidget(RawDataPlot);
  RawDataPlot->show();

  plotLayout->addSpacing(20);

  MyPsthPlot = new PsthPlot(timeData, psthData, psthLength/psthBinw, this);
  plotLayout->addWidget(MyPsthPlot);
  MyPsthPlot->show();

  /*---- Buttons ----*/

  // AD group
  QGroupBox   *ADcounterGroup = new QGroupBox( "A/D Channel", this );
  QVBoxLayout *ADcounterLayout = new QVBoxLayout;

  ADcounterGroup->setLayout(ADcounterLayout);
  ADcounterGroup->setAlignment(Qt::AlignJustify);
  ADcounterGroup->setSizePolicy( QSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed) );
  controlLayout->addWidget( ADcounterGroup );

  QwtCounter *cntChannel = new QwtCounter(ADcounterGroup);
  cntChannel->setRange(0, numChannels-1, 1);
  cntChannel->setValue(adChannel);
  ADcounterLayout->addWidget(cntChannel);
  connect(cntChannel, SIGNAL(valueChanged(double)), SLOT(slotSetChannel(double)));

  filter50HzCheckBox = new QCheckBox( "50Hz filter" );
  filter50HzCheckBox->setEnabled( true );
  ADcounterLayout->addWidget(filter50HzCheckBox);

  // psth functions
  QGroupBox   *PSTHfunGroup  = new QGroupBox( "Actions", this );
  QVBoxLayout *PSTHfunLayout = new QVBoxLayout;

  PSTHfunGroup->setLayout(PSTHfunLayout);
  PSTHfunGroup->setAlignment(Qt::AlignJustify);
  PSTHfunGroup->setSizePolicy( QSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed) );
  controlLayout->addWidget( PSTHfunGroup );

  averagePsth = new QComboBox(PSTHfunGroup);
  averagePsth->addItem(tr("PSTH"));
  averagePsth->addItem(tr("VEP"));
  PSTHfunLayout->addWidget(averagePsth);
  connect( averagePsth, SIGNAL(currentIndexChanged(int)), SLOT(slotAveragePsth(int)) );

  triggerPsth = new QPushButton(PSTHfunGroup);
  triggerPsth->setText("PSTH on");
  triggerPsth->setCheckable(true);
  PSTHfunLayout->addWidget(triggerPsth);
  connect(triggerPsth, SIGNAL(clicked()), SLOT(slotTriggerPsth()));

  QPushButton *clearPsth = new QPushButton(PSTHfunGroup);
  clearPsth->setText("clear data");
  PSTHfunLayout->addWidget(clearPsth);
  connect(clearPsth, SIGNAL(clicked()), SLOT(slotClearPsth()));

  QPushButton *savePsth = new QPushButton(PSTHfunGroup);
  savePsth->setText("save data");
  PSTHfunLayout->addWidget(savePsth);
  connect(savePsth, SIGNAL(clicked()), SLOT(slotSavePsth()));

  // psth params
  QGroupBox   *PSTHcounterGroup = new QGroupBox( "Parameters", this );
  QVBoxLayout *PSTHcounterLayout = new QVBoxLayout;

  PSTHcounterGroup->setLayout(PSTHcounterLayout);
  PSTHcounterGroup->setAlignment(Qt::AlignJustify);
  PSTHcounterGroup->setSizePolicy( QSizePolicy(QSizePolicy::Fixed,
					       QSizePolicy::Fixed) );
  controlLayout->addWidget( PSTHcounterGroup );

  QLabel *psthLengthLabel = new QLabel("Sweep length", PSTHcounterGroup);
  PSTHcounterLayout->addWidget(psthLengthLabel);

  QwtCounter *cntSLength = new QwtCounter(PSTHcounterGroup);
  cntSLength->setNumButtons(2);
  cntSLength->setIncSteps(QwtCounter::Button1, 10);
  cntSLength->setIncSteps(QwtCounter::Button2, 100);
  cntSLength->setRange(1, MAX_PSTH_LENGTH, 1);
  cntSLength->setValue(psthLength);
  PSTHcounterLayout->addWidget(cntSLength);
  connect(cntSLength, 
	  SIGNAL(valueChanged(double)), 
	  SLOT(slotSetPsthLength(double)));

  QLabel *binwidthLabel = new QLabel("Binwidth", PSTHcounterGroup);
  PSTHcounterLayout->addWidget(binwidthLabel);

  cntBinw = new QwtCounter(PSTHcounterGroup);
  cntBinw->setNumButtons(2);
  cntBinw->setIncSteps(QwtCounter::Button1, 1);
  cntBinw->setIncSteps(QwtCounter::Button2, 10);
  cntBinw->setRange(1, 100, 1);
  cntBinw->setValue(psthBinw);
  PSTHcounterLayout->addWidget(cntBinw);
  connect(cntBinw, SIGNAL(valueChanged(double)), SLOT(slotSetPsthBinw(double)));

  QLabel *thresholdLabel = new QLabel("Spike Threshold", PSTHcounterGroup);
  PSTHcounterLayout->addWidget(thresholdLabel);

  editSpikeT = new QTextEdit("0");
  QFont editFont("Courier",14);
  QFontMetrics editMetrics(editFont);
  editSpikeT->setMaximumHeight ( editMetrics.height()*1.2 );
  editSpikeT->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
  editSpikeT->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
  editSpikeT->setFont(editFont);
  PSTHcounterLayout->addWidget(editSpikeT);
  connect(editSpikeT, SIGNAL(textChanged()), SLOT(slotSetSpikeThres()));

  thresholdMarker = new QwtPlotMarker();
  thresholdMarker->setValue(0,0);
  thresholdMarker->attach(RawDataPlot);
  thresholdMarker->setLineStyle(QwtPlotMarker::HLine);

  // Generate timer event every 50ms
  (void)startTimer(50);

}
Пример #17
0
/**
 * @brief Get the information from Comedi library
 *
 */
void MainWindow::GetComediInfo()
    {
    int i,j;
    int n_subdevices,type;
    int chan,n_chans;
    int n_ranges;
    int subdev_flags;
    comedi_range *rng;

    ChannelList.clear();
    // at the moment we are using the default device
    const char optionsfilename[]="/dev/comedi0";
    QString DeviceName=AppSettings.value(Key_Comedi_Device_Name).toString();
    if (DeviceName.length()<=0) DeviceName=optionsfilename;
    it = comedi_open(optionsfilename);
    if(!it)
        {
        QMessageBox::warning(this, optionsfilename,
            tr("Can not open the device\n"),
            QMessageBox::Ok);
        };
    cbComediDevice->addItem(optionsfilename,1);
    AppSettings.setValue(Key_Comedi_Device_Name,DeviceName);

    QString buffer="Overall info:\n";
    //buffer+=QString    printf("  Version code: 0x%06x\n", comedi_get_version_code(it));
    buffer+=QString("  Comedi version code: 0x%06x\n").arg(comedi_get_version_code(it));
    buffer+=QString("  Driver name: %1\n").arg(comedi_get_driver_name(it));
    buffer+=QString("  Board name: %1\n").arg(comedi_get_board_name(it));
    n_subdevices = comedi_get_n_subdevices(it);
    buffer+=QString(" Number of subdevices: %1\n").arg(n_subdevices);

    tlComediInfo->setText(buffer);

    int channel_unique_id=1;


    // Now scan subdevices
    for(i = 0; i < n_subdevices; i++)
        {
        buffer.clear();
        type = comedi_get_subdevice_type(it, i);
        if(type==COMEDI_SUBD_UNUSED) continue;

        QTextEdit * tabText=new QTextEdit;
        buffer+=QString("Subdevice %1\n").arg(i);
        buffer+=QString("Type: %1 (%2)\n").arg(type).arg(subdevice_types[type]);

        subdev_flags = comedi_get_subdevice_flags(it, i);
        QString flagsstring;
        flagsstring.sprintf("flags: 0x%08x\n",subdev_flags);
        buffer+=flagsstring;

        n_chans=comedi_get_n_channels(it,i);
        buffer+=QString("  Number of channels: %1\n").arg(n_chans);
        if ((type==1)||(type==2)) // Analog input or output
            {
            for(chan=0;chan<n_chans;chan++)
                {
                // here!
                ChannelList.append(AIO_channel(QString(optionsfilename),i,chan,0,type==1,++channel_unique_id));
                };
            };


        if(!comedi_maxdata_is_chan_specific(it,i))
            {
            buffer+=QString("  Maximal data value: %1\n").arg((unsigned long)comedi_get_maxdata(it,i,0));
            }
            else
            {
            buffer+=QString("  Maximal data value is channel specific:\n");
            for(chan=0;chan<n_chans;chan++)
                {
                buffer+=QString("    Channel %1: %2\n").arg(chan).arg
                    ((unsigned long)comedi_get_maxdata(it,i,chan));
                }
            };

        buffer+=QString("  ranges:\n");
        if (!comedi_range_is_chan_specific(it,i))
            {
            n_ranges=comedi_get_n_ranges(it,i,0);
            buffer+=QString("    All channels:");
            for(j=0;j<n_ranges;j++)
                {
                rng=comedi_get_range(it,i,0,j);
//                buffer+=QString(" [%g,%g]",rng->min,rng->max);
                buffer+=QString(" [%1,%2]").arg(rng->min).arg(rng->max);
                }
            buffer+=QString("\n");
            }
            else
            {
            for (chan=0;chan<n_chans;chan++)
                {
                n_ranges=comedi_get_n_ranges(it,i,chan);
                printf("    chan%d:",chan);
                for(j=0;j<n_ranges;j++)
                    {
                    rng=comedi_get_range(it,i,chan,j);
                    printf(" [%g,%g]",rng->min,rng->max);
                    }
                printf("\n");
                }

            }
        tabText->setText(buffer);
        tabWidget->addTab(tabText,QString("subdevice %1").arg(i));
        }
        //printf("  command:\n");
        //get_command_stuff(it,i);


    tabWidget->setTabText(0,tr("Connections"));

    // Create channles we might need; all are input channels save one


     Ini_ImI=   new AIO_channel(Key_Im_Input,1);
     Ini_CmdI=  new AIO_channel(Key_Cmd_Input,1);
     Ini_CmI=   new AIO_channel(Key_Cm_Tlgf_Input,1);
     Ini_GainT= new AIO_channel(Key_Gain_Tlgf_Input,1);
     Ini_FreqT= new AIO_channel(Key_Freq_Tlgf_Input,1);
     Ini_LswT=  new AIO_channel(Key_Lsw_Tlgf_Input,1);

     Ini_CmdO=  new AIO_channel(Key_Cmd_Output,0);


     for (int ch=0;ch<ChannelList.count();ch++)
        {
        if (ChannelList[ch].is_input)
            {
            cbxAI_Im->addItem(ChannelList[ch].Description(),ChannelList[ch].ID());
            if (ChannelList[ch]==Ini_ImI)  {
                int zzz=cbxAI_Im->count();
                cbxAI_Im->setCurrentIndex(zzz-1);
                };

            cbxAI_Cmd->addItem(ChannelList[ch].Description(),ChannelList[ch].ID());
            if (ChannelList[ch]==Ini_CmdI) { cbxAI_Cmd->setCurrentIndex(cbxAI_Cmd->count()-1); };

            cbxAI_Cm_tlg->addItem(ChannelList[ch].Description(),ChannelList[ch].ID());
            if (ChannelList[ch]==Ini_CmI)  { cbxAI_Cm_tlg->setCurrentIndex(cbxAI_Cm_tlg->count()-1); };

            cbxAI_Gain_tlg->addItem(ChannelList[ch].Description(),ChannelList[ch].ID());
            if (ChannelList[ch]==Ini_GainT){ cbxAI_Gain_tlg->setCurrentIndex(cbxAI_Gain_tlg->count()-1); };

            cbxAI_Freq_tlg->addItem(ChannelList[ch].Description(),ChannelList[ch].ID());
            if (ChannelList[ch]==Ini_FreqT) { cbxAI_Freq_tlg->setCurrentIndex(cbxAI_Freq_tlg->count()-1); };

            cbxAI_Lsw_tlg->addItem(ChannelList[ch].Description(),ChannelList[ch].ID());
            if (ChannelList[ch]==Ini_LswT) { cbxAI_Lsw_tlg->setCurrentIndex(cbxAI_Lsw_tlg->count()-1); };
            }
            else
            {
            cbxAO_Cmd->addItem(ChannelList[ch].Description(),ChannelList[ch].ID());
            if (ChannelList[ch]==Ini_CmdO)
                {
                cbxAO_Cmd->setCurrentIndex(cbxAO_Cmd->count()-1);
                };
            };

        };
    return;
    }
Пример #18
0
bogio_spec *bogio_open(bogio_spec *spec)
{
    unsigned int *chanlist;       /* For Comedi channel flags */
    unsigned int osr;             /* Oversampling rate */
    int i;
    
    /* Maybe the caller didn't have a bogio_spec */
    if (spec == NULL) {
        spec            = calloc(1U, sizeof(bogio_spec));
        /* We have to set these here because 0 is a valid argument */
        spec->subdevice = 0U;
        spec->range     = 0U; /* +/- 4V */
        spec->aref      = AREF_GROUND;
    }
    
    /* Set defaults if the caller didn't supply parameters */
    if (spec->comedi_device == NULL)
        spec->comedi_device = "/dev/comedi0";
    if (spec->sample_rate == 0)
        spec->sample_rate = 1000; /* 1kHz default sample rate */
    if (spec->channels == 0)
        spec->channels = 8;       /* 8 input channels by default */
    /* implied: oversampling = 0 (no oversampling) */
    
    /* Reserve memory for the Comedi command */
    spec->m_cmd = calloc(1, sizeof(comedi_cmd));
    
    /* Try to open the device */
    spec->m_dev = comedi_open(spec->comedi_device);
    if (spec->m_dev == NULL){
        comedi_perror(spec->comedi_device);
        return NULL;
    }
    
    /* Calculate the oversampled rate for the target sample rate */
    spec->oversampling = 0; /* To do! */
    osr = spec->oversampling ? spec->oversampling : 1;
    osr *= (1000000000U/spec->sample_rate);   /* That's 1e9 */
    
    /* Set up channel list */
    chanlist = (unsigned int *)calloc(spec->channels, sizeof(unsigned int));
    for(i=0 ; i < spec->channels ; i++)
        chanlist[i]=CR_PACK(i, spec->range, spec->aref);
    
    i = comedi_get_cmd_generic_timed(spec->m_dev,
                                     spec->subdevice,
                                     spec->m_cmd,
                                     spec->channels,
                                     osr
                                    );
    if (i < 0) {
        fprintf(stderr, "comedi_get_cmd_generic_timed failed\n");
        return NULL;
    }
    
    /* Modify parts of the command */
    spec->m_cmd->chanlist     = chanlist;
    spec->m_cmd->chanlist_len = spec->channels;
    spec->m_cmd->scan_end_arg = spec->channels;
    spec->m_cmd->stop_src     = TRIG_NONE;
    spec->m_cmd->stop_arg     = 0;

    /* comedi_command_test() tests a command to see if the
       trigger sources and arguments are valid for the subdevice.
       If a trigger source is invalid, it will be logically ANDed
       with valid values (trigger sources are actually bitmasks),
       which may or may not result in a valid trigger source.
       If an argument is invalid, it will be adjusted to the
       nearest valid value.  In this way, for many commands, you
       can test it multiple times until it passes.  Typically,
       if you can't get a valid command in two tests, the original
       command wasn't specified very well. */
    i = comedi_command_test(spec->m_dev, spec->m_cmd);
    if (i < 0) {
        comedi_perror("comedi_command_test -- first attempt");
        exit(-1);
    }
    /* fprintf(stderr,"first test returned %d\n",i); */

    i = comedi_command_test(spec->m_dev, spec->m_cmd);
    if (i < 0){
        comedi_perror("comedi_command_test -- second attempt");
        return NULL;
    }
    /* fprintf(stderr,"second test returned %d\n",i); */
    
    if (i != 0){
        fprintf(stderr,"Error preparing command\n");
        return NULL;
    }
    
    /* Make sure the sample rate wasn't modified */
    if (spec->m_cmd->convert_src==TRIG_TIMER && spec->m_cmd->convert_arg)
        spec->sample_rate = 1E9/spec->m_cmd->convert_arg;

    if (spec->m_cmd->scan_begin_src==TRIG_TIMER && spec->m_cmd->scan_begin_arg)
        spec->sample_rate = 1E9/spec->m_cmd->scan_begin_arg;

    /* start the command */
    i = comedi_command(spec->m_dev, spec->m_cmd);
    if (i < 0) {
        comedi_perror("comedi_command");
        return NULL;
    }
    
    /* That worked: report the current settings */
    /* Read the maxdata value and range for each channel;
       it will be used later for normalisation */
    spec->m_max_sample = calloc(spec->channels, sizeof(lsampl_t));
    spec->fsd = calloc(spec->channels, sizeof(comedi_range *));
    for (i = 0 ; i < spec->channels ; i++) {
        spec->m_max_sample[i] = comedi_get_maxdata(spec->m_dev,
                                                   spec->subdevice,
                                                   i);
        spec->fsd[i]          = comedi_get_range(spec->m_dev,
                                                 spec->subdevice,
                                                 i,
                                                 spec->range);
    }

    return spec;
}
Пример #19
0
/* -------------------------------------------------------------------- */
static long dsetRead_devAiSyncComedi(aiRecord *pai)
{
  CONTEXT  *p_myContext;
  int       mySubdevice;
  int       myChannel;
  int       myRange = 0;
  int       myAnalogReference;
  int       myPinNumber;
  char      p_myDeviceFile[BUFLEN];
  comedi_t *p_myComediFileHandle;
  lsampl_t  data;
  int       maxdata;
  int       ret;

  dsetLog(3, __FILE__ "[%d] -> %s(%s)\n", __LINE__, __func__, pai->name );

  p_myContext = pai->dpvt;
  p_myComediFileHandle = p_myContext->p_comediFileHandle;
  myChannel            = p_myContext->channel;
  myRange              = p_myContext->range;
  myAnalogReference    = p_myContext->analogReference;
  mySubdevice          = p_myContext->subdevice;
  myPinNumber          = p_myContext->pinNumber;
  strcpy(p_myDeviceFile, p_myContext->p_deviceFile);

#if 0
  dsetLog(7,__FILE__ "[%d] Subdevice  = %d PinNumber =%d\n",
          __LINE__,  mySubdevice, myPinNumber);
  dsetLog(7,__FILE__ "[%d] AnalogReference  = %d Channel=%d\n",
          __LINE__,  myAnalogReference, myChannel);

  dsetLog(7, __FILE__ "[%d] -> Range is %d\n", __LINE__, myRange);

#endif

  maxdata = comedi_get_maxdata(p_myComediFileHandle, mySubdevice, myChannel);

#if 0
  dsetLog(7,__FILE__ "[%d] maxdata  = %d pn=%d\n",
          __LINE__,  maxdata, myPinNumber);
  dsetLog(7,__FILE__ "[%d] Data %d -> device %s\n", __LINE__, data, pai->name);

  dsetLog(7,__FILE__ "[%d] New Range  = %lg\n",
          comedi_get_range(p_myComediFileHandle, mySubdevice,
                           myChannel, myRange));
#endif

  ret = comedi_data_read(p_myComediFileHandle, mySubdevice, myChannel,
                         myRange, myAnalogReference, &data);
  if (ret < 0) {
    comedi_perror(p_myDeviceFile);
    dsetLog(1, __FILE__ "[%d] Error: Couldn't read hardware\n", __LINE__);
    sleep(SLEEPTIME_ERROR);

    return(ERROR);
  }

  pai->val = comedi_to_phys(data,
                             comedi_get_range(p_myComediFileHandle, mySubdevice,
                                              myChannel, myRange),
                             maxdata);

  pai->udf = isnan(pai->val);

  dsetLog(7,__FILE__ "[%d] pai->udf is %d \n", __LINE__, pai->udf);

  if (pai->udf) {
    pai->val = 10;
    dsetLog(7,__FILE__ "[%d] Error: Cable is disconnected, please verify\n", __LINE__);
  }

  dsetLog(7,__FILE__ "[%d] val,rval=%lg,%d -> %s\n",
          __LINE__, pai->val, pai->rval, pai->name);

  dsetLog(3,__FILE__ "[%d] <- %s\n", __LINE__, __func__);

  return(NO_AUTOMATIC_CONVERSION);
  /*return(DO_AUTOMATIC_CONVERSION); */
}
Пример #20
0
int main(int argc, char *argv[])
{
	comedi_t *dev;
	comedi_cmd c,*cmd=&c;
	int ret;
	int total=0;
	int i;
	struct timeval start,end;
	int subdev_flags;
	lsampl_t raw;
	struct parsed_options options;

	init_parsed_options(&options);
	parse_options(&options, argc, argv);

	/* The following variables used in this demo
	 * can be modified by command line
	 * options.  When modifying this demo, you may want to
	 * change them here. */
	options.filename = "/dev/comedi0";
	options.subdevice = 0;
	options.channel = 0;
	options.range = 6;  
	options.aref = AREF_DIFF;
	options.n_chan = 8;
	options.n_scan = 100000;
	options.freq = 1000.0;
	options.physical = 1;

	/* open the device */
	dev = comedi_open(options.filename);
	if(!dev){
		comedi_perror(options.filename);
		exit(1);
	}

	// Print numbers for clipped inputs
	comedi_set_global_oor_behavior(COMEDI_OOR_NUMBER);

	/* Set up channel list */
	//for(i = 0; i < options.n_chan/2; i++){
	for(i = 0; i < options.n_chan; i++){	
		chanlist[i] = CR_PACK(options.channel + i, options.range, options.aref);
		range_info[i] = comedi_get_range(dev, options.subdevice, options.channel, options.range);
		maxdata[i] = comedi_get_maxdata(dev, options.subdevice, options.channel);
	}

/*
    for(i = options.n_chan/2; i < options.n_chan; i++){
        fprintf(stderr,"%d: %d\n", i, options.channel + i + 8);
        chanlist[i] = CR_PACK(options.channel + i + 8, options.range, options.aref);
        range_info[i] = comedi_get_range(dev, options.subdevice, options.channel, options.range);
        maxdata[i] = comedi_get_maxdata(dev, options.subdevice, options.channel);
    }    
*/

	/* prepare_cmd_lib() uses a Comedilib routine to find a
	 * good command for the device.  prepare_cmd() explicitly
	 * creates a command, which may not work for your device. */
	prepare_cmd_lib(dev, options.subdevice, options.n_scan, options.n_chan, 1e9 / options.freq, cmd);
	//prepare_cmd(dev, options.subdevice, options.n_scan, options.n_chan, 1e9 / options.freq, cmd);

	fprintf(stderr, "command:\n");
	dump_cmd(stderr, cmd);

	/* this is only for informational purposes */
	gettimeofday(&start, NULL);
	fprintf(stderr,"start time: %ld.%06ld\n", start.tv_sec, start.tv_usec);

	/* start the command */
	ret = comedi_command(dev, cmd);
	if(ret < 0){
		comedi_perror("comedi_command");
		exit(1);
	}
	subdev_flags = comedi_get_subdevice_flags(dev, options.subdevice);
	while(1){
		ret = read(comedi_fileno(dev),buf,BUFSZ);
		if(ret < 0){
			/* some error occurred */
			perror("read");
			continue;
		}else if(ret == 0){
			/* reached stop condition */
			break;
		}else{
			static int col = 0;
			int bytes_per_sample;
			total += ret;
			if(options.verbose)fprintf(stderr, "read %d %d\n", ret, total);
			if(subdev_flags & SDF_LSAMPL)
				bytes_per_sample = sizeof(lsampl_t);
			else
				bytes_per_sample = sizeof(sampl_t);
			for(i = 0; i < ret / bytes_per_sample; i++){
				if(subdev_flags & SDF_LSAMPL) {
					raw = ((lsampl_t *)buf)[i];
				} else {
					raw = ((sampl_t *)buf)[i];
				}
				print_datum(raw, col, options.physical);
				col++;
				if(col == options.n_chan){
					printf("\n");
					col=0;
				}
			}
		}
	}

	/* this is only for informational purposes */
	gettimeofday(&end,NULL);
	fprintf(stderr,"end time: %ld.%06ld\n", end.tv_sec, end.tv_usec);

	end.tv_sec -= start.tv_sec;
	if(end.tv_usec < start.tv_usec){
		end.tv_sec--;
		end.tv_usec += 1000000;
	}
	end.tv_usec -= start.tv_usec;
	fprintf(stderr,"time: %ld.%06ld\n", end.tv_sec, end.tv_usec);

	return 0;
}
Пример #21
0
int main(int argc, char *argv[])
{
  comedi_cmd cmd;
  int err;
  int n, m, k;
  comedi_t *dev;
  unsigned int chanlist[100];
  unsigned int maxdata;
  comedi_range *rng;
  int ret;
  struct parsed_options options;
  int fn = 256*256;
  sampl_t *data, *dp;
  float v;

  init_parsed_options(&options);
  options.subdevice = -1;
  options.n_chan = 100000;/* default number of samples */
  parse_options(&options, argc, argv);

  dev = comedi_open( options.filename );
  if(dev == NULL){
    fprintf(stderr, "error opening %s\n", options.filename);
    return -1;
  }
  if(options.subdevice < 0)
    options.subdevice = comedi_find_subdevice_by_type(dev, COMEDI_SUBD_AI, 0);

  maxdata = comedi_get_maxdata(dev, options.subdevice, options.channel);
  rng = comedi_get_range(dev, options.subdevice, options.channel, options.range);

  memset(&cmd,0,sizeof(cmd));
  /*
  cmd.subdev = options.subdevice;
  cmd.flags = 0;
  cmd.start_src = TRIG_INT;
  cmd.start_arg = 0;
  cmd.scan_begin_src = TRIG_TIMER;
  cmd.scan_begin_arg = 1e9 / options.freq;
  cmd.convert_src = TRIG_TIMER;
  cmd.convert_arg = 1e9 / options.freq / 50;
  cmd.scan_end_src = TRIG_COUNT;
  cmd.scan_end_arg = options.n_chan;
  cmd.stop_src = TRIG_COUNT;
  cmd.stop_arg = fn;
  cmd.stop_src = TRIG_NONE;
  cmd.stop_arg = 0;
  */

  cmd.scan_begin_src = TRIG_TIMER;
  cmd.flags = TRIG_ROUND_NEAREST;
  err = comedi_get_cmd_generic_timed( dev, options.subdevice,
				      &cmd, options.n_chan,
				      1e9 / options.freq );
  cmd.start_src = TRIG_INT;
  cmd.start_arg = 0;
  cmd.scan_end_arg = options.n_chan;
  cmd.stop_src = TRIG_NONE;
  cmd.stop_arg = 0;
  
  cmd.chanlist = chanlist;
  cmd.chanlist_len = options.n_chan;

  for ( k=0; k<options.n_chan; k++ )
    chanlist[k] = CR_PACK(k, options.range, options.aref);

  dump_cmd(stderr,&cmd);

  if ( cmd.scan_begin_arg > 1e9 / options.freq ) {
    fprintf( stderr, "frequency too high! Maximum possible is %g Hz\n", 1.0e9/cmd.scan_begin_arg );
    comedi_close( dev );
    return 1;
  }

  err = comedi_command_test(dev, &cmd);
  if (err > 0 && err != 4 ) {
    fprintf( stderr, "comedi_command_test returned %d\n", err );
    dump_cmd(stdout,&cmd);
    exit(1);
  }
  
  err = comedi_command_test(dev, &cmd);
  if (err > 0 && err != 4 ) {
    fprintf( stderr, "comedi_command_test returned %d\n", err );
    dump_cmd(stdout,&cmd);
    exit(1);
  }

  dump_cmd(stderr,&cmd);

  /* init data buffer: */
  data = (sampl_t *)malloc( fn*sizeof( sampl_t ) );
  if(data == NULL ){
    perror("malloc\n");
    exit(1);
  }
  
  fprintf( stderr, "execute command ...\n" );
  if ((err = comedi_command(dev, &cmd)) < 0) {
    comedi_perror("comedi_command");
    exit(1);
  }
  
  fprintf( stderr, "start analog input ...\n" );
  ret = comedi_internal_trigger(dev, options.subdevice, 0);
  if(ret < 0){
    perror("comedi_internal_trigger\n");
    exit(1);
  }
  
  n = 0;
  while( 1 ) {
    m = read(comedi_fileno(dev),(void *)data,fn*sizeof( sampl_t));
    if(m<0){
      if ( errno != EAGAIN ) {
	perror("read");
	exit(0);
      }
      else {
	fprintf( stderr, "... no more data can be read! Try later.\n" );
	usleep( 100000 );
      }
    }
    else {
      m /= sizeof( sampl_t);
      fprintf( stderr, "read %d samples\n",m);
      n+=m;
    }
  }
  comedi_cancel( dev, cmd.subdev );

  fprintf( stderr, "finished\n" );

  /* save data: */

  dp = data;  
  for ( k=0; k<n; k++ ) {
    v = comedi_to_phys(*dp, rng, maxdata);
    printf( "%g\n", v );
    /*    printf( "%d\n", *dp );*/
    ++dp;
  }

  free( data );

  comedi_close( dev );
  
  return 0;
}
Пример #22
0
ComediScope::ComediScope( ComediRecord *comediRecordTmp, 
			  int channels, 
			  float f, 
			  int port_for_ext_data, 
			  int maxComediDevs,
			  int first_dev_no,
			  int req_sampling_rate,
			  const char* defaultTextStringForMissingExtData,
			  int fftdevnumber, int fftchannel, int fftmaxf
	)
    : QWidget( comediRecordTmp ) {

	channels_in_use = channels;

	tb_init=1;
	tb_counter=tb_init;
	comediRecord=comediRecordTmp;
	// erase plot
	eraseFlag = 1;

	fftdevno = fftdevnumber;
	fftch = fftchannel;
	fftmaxfrequency = fftmaxf;

	// for ASCII
	rec_file=NULL;

	// filename
	rec_filename=new QString();

	// flag if data has been recorded and we need a new filename
	recorded=0;

	if (port_for_ext_data>0) {
		fprintf(stderr,
			"Expecting a connection on TCP port %d. \n"
			"Start your client now, for example: \n"
			"telnet localhost %d\n"
			"Press Ctrl-C to abort.\n",
			port_for_ext_data,
			port_for_ext_data);
		ext_data_receive = new Ext_data_receive(
			port_for_ext_data,
			defaultTextStringForMissingExtData
			);
	} else {
		ext_data_receive = NULL;
	}	


	//////////////////////////////////////////////////////////////

	setAttribute(Qt::WA_OpaquePaintEvent);

	int range = 0;
	int aref = AREF_GROUND;
	// do not produce NAN for out of range behaviour
	comedi_set_global_oor_behavior(COMEDI_OOR_NUMBER);

	// create an array which keeps the comedi devices
	dev = new comedi_t*[maxComediDevs];
	for(int devNo=0;devNo<maxComediDevs;devNo++) {
		dev[devNo] = NULL;
	}
	// let's probe how many we have
	nComediDevices = 0;
	for(int devNo=0;devNo<maxComediDevs;devNo++) {
		char filename[128];
		sprintf(filename,"/dev/comedi%d",devNo+first_dev_no);
		dev[devNo] = comedi_open(filename);
		if(dev[devNo]){
			nComediDevices = devNo + 1;
		} else {
			break;
		}
	}

	// none detected
	if (nComediDevices<1) {
		fprintf(stderr,"No comedi devices detected!\n");
		exit(1);
	}

	// create channel lists
	chanlist = new unsigned int*[nComediDevices];
	// create command structures
	cmd = new comedi_cmd*[nComediDevices];
	// find the subdevice which is analogue in
	subdevice = comedi_find_subdevice_by_type(dev[0],COMEDI_SUBD_AI,0);

	// check if user has specified channels or if requested
	// number of channels make sense
	if ((channels_in_use < 1)||
	    (channels_in_use > comedi_get_n_channels(dev[0],subdevice)))
	{
		channels_in_use = comedi_get_n_channels(dev[0],subdevice);
	}

	// create channel lists and the command structures
	for(int devNo=0;devNo<nComediDevices;devNo++) {
		chanlist[devNo] = new unsigned int[channels_in_use];
		assert( chanlist[devNo]!=NULL );
		for(int i=0;i<channels_in_use;i++){
			chanlist[devNo][i] = CR_PACK(i,range,aref);
		}
		cmd[devNo] = new comedi_cmd;
		assert( dev[devNo]!=NULL );
		int r = comedi_get_cmd_generic_timed(dev[devNo],
						     subdevice,
						     cmd[devNo],
						     channels_in_use,
						     (int)(1e9/req_sampling_rate));
		if(r<0){
			comedi_perror("comedi_get_cmd_generic_timed failed\n");
			exit(-1);
		}
		/* Modify parts of the command */
		cmd[devNo]->chanlist           = chanlist[devNo];
		cmd[devNo]->chanlist_len       = channels_in_use;
		cmd[devNo]->scan_end_arg = channels_in_use;
		cmd[devNo]->stop_src=TRIG_NONE;
		cmd[devNo]->stop_arg=0;
		int ret = comedi_command_test(dev[devNo],cmd[devNo]);
		if(ret<0){
			comedi_perror("1st comedi_command_test failed\n");
			exit(-1);
		}
		ret = comedi_command_test(dev[devNo],cmd[devNo]);
		if(ret<0){
			comedi_perror("2nd comedi_command_test failed\n");
			exit(-1);
		}
		if(ret!=0){
			fprintf(stderr,"Error preparing command.\n");
			exit(-1);
		}
	}

	// the timing is done channel by channel
	// this means that the actual sampling rate is divided by
	// number of channels
	if ((cmd[0]->convert_src ==  TRIG_TIMER)&&(cmd[0]->convert_arg)) {
		sampling_rate=((1E9 / cmd[0]->convert_arg)/channels_in_use);
	}
	
	// the timing is done scan by scan (all channels at once)
	// the sampling rate is equivalent of the scan_begin_arg
	if ((cmd[0]->scan_begin_src ==  TRIG_TIMER)&&(cmd[0]->scan_begin_arg)) {
		sampling_rate=1E9 / cmd[0]->scan_begin_arg;
	}

	// initialise the graphics stuff
	ypos = new int**[nComediDevices];
	assert(ypos != NULL);
	for(int devNo=0;devNo<nComediDevices;devNo++) {
		ypos[devNo]=new int*[channels_in_use];
		assert(ypos[devNo] != NULL);
		for(int i=0;i<channels_in_use;i++) {
			ypos[devNo][i] = new int[MAX_DISP_X];
			assert( ypos[devNo][i] != NULL);
			for(int j=0;j<MAX_DISP_X;j++) {
				ypos[devNo][i][j]=0;
			}
		}
	}

	xpos=0;
	nsamples=0;

	maxdata = new lsampl_t[nComediDevices];
	assert( maxdata != NULL );
	crange = new comedi_range*[nComediDevices];
	assert( crange != NULL );
	for(int devNo=0;devNo<nComediDevices;devNo++) {
		// we just go for the default ranges
		maxdata[devNo]=comedi_get_maxdata(dev[devNo],subdevice,0);
		crange[devNo]=comedi_get_range(dev[devNo],subdevice,0,0);
	}

	// 50Hz or 60Hz mains notch filter
	iirnotch = new Iir::Butterworth::BandStop<IIRORDER>**[nComediDevices];
	assert( iirnotch != NULL );
	adAvgBuffer = new float*[nComediDevices];
	assert( adAvgBuffer != NULL );
	daqData = new lsampl_t*[nComediDevices];
	assert( daqData != NULL );
	for(int devNo=0;devNo<nComediDevices;devNo++) {
		iirnotch[devNo] = new Iir::Butterworth::BandStop<IIRORDER>*[channels_in_use];
		assert( iirnotch[devNo] != NULL );
		// floating point buffer for plotting
		adAvgBuffer[devNo]=new float[channels_in_use];
		assert( adAvgBuffer[devNo] != NULL );
		for(int i=0;i<channels_in_use;i++) {
			adAvgBuffer[devNo][i]=0;
			iirnotch[devNo][i] = new Iir::Butterworth::BandStop<IIRORDER>;
			assert( iirnotch[devNo][i] != NULL );
		}
		// raw data buffer for saving the data
		daqData[devNo] = new lsampl_t[channels_in_use];
		assert( daqData[devNo] != NULL );
		for(int i=0;i<channels_in_use;i++) {
			daqData[devNo][i]=0;
		}
	}

	setNotchFrequency(f);

	counter = new QTimer( this );
	assert( counter != NULL );
	connect( counter, 
		 SIGNAL(timeout()),
		 this, 
		 SLOT(updateTime()) );
}
Пример #23
0
static long dsetInit_devAoSyncComedi (aoRecord *pao) {
  CONTEXT *p_myContext;
  COMEDIDEV_AO *p_myAnalogOutput;
  int myPinNumber;
  int myMinorOfDeviceFile;
  double myMinimumVoltage;
  double myMaximumVoltage;
  int myDifferentialMode;

  char  p_myWarmstartFilename[BUFLEN];
  FILE *p_myFileHandle;

  
  packageInfo();
  dsetLog(3, __FILE__ "[%d] -> %s(%s)\n", __LINE__, __func__, pao->name );

  p_myAnalogOutput=(COMEDIDEV_AO *)calloc(1, sizeof(COMEDIDEV_AO));

  if ( sscanf(pao->out.value.instio.string, "modf=%d pn=%d dm=%d",
	 &myMinorOfDeviceFile,
	 &myPinNumber,
         &myDifferentialMode) != 3) {
    dsetLog(1, __FILE__ "[%d] Error: %s\n", __LINE__, pao->name);
    dsetLog(1, __FILE__ "[%d] Error: Couldn't parse parameters\n", __LINE__);
    dsetLog(1, __FILE__ "[%d] Error: >%s<\n", 
		   __LINE__,pao->out.value.instio.string);
    sleep(SLEEPTIME_ERROR);
    return(ERROR);
  }

  p_myAnalogOutput->aref=myDifferentialMode+1; /* always 2 ! */
  
  sprintf(p_myAnalogOutput->p_deviceFilename,"/dev/comedi%d",
			myMinorOfDeviceFile);
  p_myAnalogOutput->device=comedi_open(p_myAnalogOutput->p_deviceFilename);
  p_myAnalogOutput->subdevice=0;
  p_myAnalogOutput->channel=(myPinNumber-1)/2;

  /* Get some values from the drivers	*/
  p_myAnalogOutput->maxdata=comedi_get_maxdata(p_myAnalogOutput->device,
                                               p_myAnalogOutput->subdevice,
                                               p_myAnalogOutput->channel);

  myMinimumVoltage=pao->drvl;
  myMaximumVoltage=pao->drvh;
  p_myAnalogOutput->range=getOptimalOperatingRange(pao);
  p_myAnalogOutput->c_range=comedi_get_range(p_myAnalogOutput->device,
                                             p_myAnalogOutput->subdevice,
                                             p_myAnalogOutput->channel,
                                             p_myAnalogOutput->range);	

  dsetLog(5,__FILE__ "[%d] Parsed options >%s<\n", 
		  __LINE__, pao->out.value.instio.string);
  dsetLog(5,__FILE__ "[%d]   p_deviceFilename  = >%s<\n", 
		  __LINE__, p_myAnalogOutput->p_deviceFilename);
  dsetLog(5,__FILE__ "[%d]   subdevice = %d\n", 
		  __LINE__, p_myAnalogOutput->subdevice);
  dsetLog(5,__FILE__ "[%d]   channel   = %d\n", 
		  __LINE__, p_myAnalogOutput->channel);
  dsetLog(5,__FILE__ "[%d]   range     = %d\n", 
		  __LINE__, p_myAnalogOutput->range);
  dsetLog(5,__FILE__ "[%d]   aref      = %d\n", 
		  __LINE__, p_myAnalogOutput->aref);

  p_myContext=(CONTEXT *)calloc(1,sizeof(CONTEXT));
  p_myContext->p_analogOutput=p_myAnalogOutput;
  p_myContext->minimumVoltage=myMinimumVoltage;
  p_myContext->maximumVoltage=myMaximumVoltage;

  sprintf(p_myWarmstartFilename, WARMSTART_FILE_PREFIX "/%s", pao->name);
  p_myFileHandle=fopen(p_myWarmstartFilename, "r");
  if (p_myFileHandle!=NULL) {
    fscanf(p_myFileHandle, "%lg", &pao->val);
    fclose(p_myFileHandle);
    dsetLog(5, __FILE__ "[%d] Warmstart: %lg (File) -> %s\n",
                __LINE__, pao->val, pao->name);
  } else {
    dsetLog(5, __FILE__ "[%d] Warmstart: %lg (Default) -> %s\n",
                __LINE__, pao->val , pao->name);
  }

  pao->pini=menuYesNoYES;

  pao->dpvt=(void *)p_myContext;

  dsetLog(5, __FILE__ "[%d] Calibration algo  : %d\n", __LINE__, pao->linr);
  dsetLog(5, __FILE__ "[%d] Calibration slope : %lg\n", __LINE__, pao->aslo);
  dsetLog(5, __FILE__ "[%d] Calibration offset: %lg\n", __LINE__, pao->aoff);

  dsetLog(3, __FILE__ "[%d] <- %s\n", __LINE__, __func__ );
  /* Convert according to calibration? NO!*/
  /* Convert update val based on rval and in iwarmstart file is stored val*/
  return(DO_NOT_CONVERT);  
}
Пример #24
0
static int configBoard( int board ) {
    MY_BOARD_HARDWARE *pBoardHard = myBoard_getHardwareBoard( board );
    MY_BOARD_SOFTWARE *pBoardSoft = myBoard_getSoftwareBoard( board );

    if (pBoardHard == NULL || pBoardSoft == NULL) return -1;

    comedi_insn insn;
    lsampl_t p_insn_data[3];
    int i;
    int status;

    insn.insn = INSN_CONFIG;
    insn.data = p_insn_data;
    insn.subdev = pBoardHard->subDeviceNumber;
    insn.n = 2;
    insn.data[0] = INSN_CONFIG_BLOCK_SIZE;
    insn.data[1] = 256;
    for(i=0; i < pBoardSoft->numberOfActiveAnalogInputs; i++){
        int indexRange = pBoardHard->channelIndexRange[i];

        insn.chanspec=CR_PACK(
            i,
            indexRange,
            pBoardHard->analogReference
        );
        status = comedi_do_insn(
            pBoardHard->p_comediFileHandle,
            &insn
        );
        if (status<0) {
            fprintf( stderr, "failed do inst for board[%d]\n", board );
            return -1;
        } 
    }

    if (pBoardHard->maxDataIsChannelSpecific ||
    pBoardHard->rangeIsChannelSpecific) {
        for(i=0; i < pBoardSoft->numberOfActiveAnalogInputs; i++){
            const comedi_range *pVoltageRange = comedi_get_range(
                pBoardHard->p_comediFileHandle,
                pBoardHard->subDeviceNumber,
                i,
                pBoardHard->channelIndexRange[i]
            );
            int rawMax = comedi_get_maxdata(
                pBoardHard->p_comediFileHandle,
                pBoardHard->subDeviceNumber,
                i
            );
            pBoardHard->channelRawToVoltA[i] = (pVoltageRange->max - pVoltageRange->min) / rawMax;
            pBoardHard->channelRawToVoltB[i] = pVoltageRange->min;
            fprintf( stderr, "set convert CONST for board[%d] channel[%d] a=%lf b=%lf\n",
                board, i,
                pBoardHard->channelRawToVoltA[i],
                pBoardHard->channelRawToVoltB[i]
            );
        }/* for channel */
    } else {
        const comedi_range *pVoltageRange = comedi_get_range(
            pBoardHard->p_comediFileHandle,
            pBoardHard->subDeviceNumber,
            0,
            pBoardHard->channelIndexRange[0]
        );
        int rawMax = comedi_get_maxdata(
            pBoardHard->p_comediFileHandle,
            pBoardHard->subDeviceNumber,
            0
        );
        double rawToVoltA = (pVoltageRange->max - pVoltageRange->min) / rawMax;
        double rawToVoltB = pVoltageRange->min;
        fprintf( stderr, "set convert CONST for all channel on board[%d] a=%lf b=%lf\n", board,
            rawToVoltA,
            rawToVoltB
        );
        for(i=0; i < pBoardSoft->numberOfActiveAnalogInputs; i++){
            pBoardHard->channelRawToVoltA[i] = rawToVoltA;
            pBoardHard->channelRawToVoltB[i] = rawToVoltB;
        }
    }

    return 0;
}
Пример #25
0
static PyObject*
comediModule(PyObject* self, PyObject* args)
{
	char *device;
	int subdevice;
	int channel;
	int range;
	int aref;
	int n_chan;
	int n_scan;
	float freq;
    if (!PyArg_ParseTuple(args, "siiiiiif", &device, &subdevice, &channel, &range, &aref, &n_chan, &n_scan, &freq))
        return NULL;
    
	comedi_t *dev;
	comedi_cmd c,*cmd=&c;
	int ret;
	int total=0;
	int i;
	struct timeval start,end;
	int subdev_flags;
	lsampl_t raw;
	struct parsed_options options;

	init_parsed_options(&options);
	options.filename = device;
	options.subdevice = subdevice;
	options.channel = channel;
	options.range = range;
	options.aref = aref;
	options.n_chan = n_chan;
	options.n_scan = n_scan;
	options.freq = freq;

	/* open the device */
	dev = comedi_open(options.filename);
	if(!dev){
		comedi_perror(options.filename);
		exit(1);
	}

	// Print numbers for clipped inputs
	comedi_set_global_oor_behavior(COMEDI_OOR_NUMBER);

	/* Set up channel list */
	for(i = 0; i < options.n_chan; i++){
		chanlist[i] = CR_PACK(options.channel + i, options.range, options.aref);
		range_info[i] = comedi_get_range(dev, options.subdevice, options.channel, options.range);
		maxdata[i] = comedi_get_maxdata(dev, options.subdevice, options.channel);
	}
	prepare_cmd_lib(dev, options.subdevice, options.n_scan, options.n_chan, 1e9 / options.freq, cmd);

	fprintf(stderr, "command before testing:\n");
	dump_cmd(stderr, cmd);

	ret = comedi_command_test(dev, cmd);
	if(ret < 0){
		comedi_perror("comedi_command_test");
		if(errno == EIO){
			fprintf(stderr,"Ummm... this subdevice doesn't support commands\n");
		}
		exit(1);
	}
	fprintf(stderr,"first test returned %d (%s)\n", ret,
			cmdtest_messages[ret]);
	dump_cmd(stderr, cmd);

	ret = comedi_command_test(dev, cmd);
	if(ret < 0){
		comedi_perror("comedi_command_test");
		exit(1);
	}
	fprintf(stderr,"second test returned %d (%s)\n", ret,
			cmdtest_messages[ret]);
	if(ret!=0){
		dump_cmd(stderr, cmd);
		fprintf(stderr, "Error preparing command\n");
		exit(1);
	}

	/* this is only for informational purposes */
	gettimeofday(&start, NULL);
	fprintf(stderr,"start time: %ld.%06ld\n", start.tv_sec, start.tv_usec);

	/* start the command */
	ret = comedi_command(dev, cmd);
	if(ret < 0){
		comedi_perror("comedi_command");
		exit(1);
	}
	subdev_flags = comedi_get_subdevice_flags(dev, options.subdevice);

	const int ndim = 2;
	npy_intp nd[2] = {n_scan, n_chan};
	
	PyObject *myarray;
	double *array_buffer;
	myarray = PyArray_SimpleNew(ndim, nd, NPY_DOUBLE);
	Py_INCREF(myarray);
	array_buffer = (double *)PyArray_DATA(myarray);
	
	while(1){
		ret = read(comedi_fileno(dev),buf,BUFSZ);
		if(ret < 0){
			/* some error occurred */
			perror("read");
			break;
		}else if(ret == 0){
			/* reached stop condition */
			break;
		}else{
			static int col = 0;
			double j = 0.0;
			
			int bytes_per_sample;
			total += ret;
			if(options.verbose)fprintf(stderr, "read %d %d\n", ret, total);
			if(subdev_flags & SDF_LSAMPL)
				bytes_per_sample = sizeof(lsampl_t);
			else
				bytes_per_sample = sizeof(sampl_t);
			for(i = 0; i < ret / bytes_per_sample; i++){
				if(subdev_flags & SDF_LSAMPL) {
					raw = ((lsampl_t *)buf)[i];
				} else {
					raw = ((sampl_t *)buf)[i];
				}
				*array_buffer++ = print_datum(raw, col, 1);
				col++;
				if(col == options.n_chan){
					col=0;
					j++;
					printf("\n");
				}
			}
		}
	}

	/* this is only for informational purposes */
	gettimeofday(&end,NULL);
	fprintf(stderr,"end time: %ld.%06ld\n", end.tv_sec, end.tv_usec);

	end.tv_sec -= start.tv_sec;
	if(end.tv_usec < start.tv_usec){
		end.tv_sec--;
		end.tv_usec += 1000000;
	}
	end.tv_usec -= start.tv_usec;
	fprintf(stderr,"time: %ld.%06ld\n", end.tv_sec, end.tv_usec);
    
	return myarray;
}
Пример #26
0
static int getOptimalRangeNumber( int board ) {
    MY_BOARD_HARDWARE *pBoardHard = myBoard_getHardwareBoard( board );
    MY_BOARD_SOFTWARE *pBoardSoft = myBoard_getSoftwareBoard( board );

    if (pBoardHard == NULL || pBoardSoft == NULL) return -1;

    int numRange;
    int indexRange;
    const comedi_range *pVoltageRange;

    if (pBoardHard->rangeIsChannelSpecific) {
        int chan;
        for (chan = 0; chan < pBoardSoft->numberOfActiveAnalogInputs; ++chan) {
            int found = 0;
            numRange = comedi_get_n_ranges(
                pBoardHard->p_comediFileHandle,
                pBoardHard->subDeviceNumber,
                chan
            );
            for (indexRange = numRange - 1; indexRange >= 0; --indexRange) {
                pVoltageRange = comedi_get_range(
                    pBoardHard->p_comediFileHandle,
                    pBoardHard->subDeviceNumber,
                    chan,
                    indexRange
                );
                if (pVoltageRange->min <= pBoardSoft->channelLopr[chan] &&
                pVoltageRange->max >= pBoardSoft->channelHopr[chan]) {
                    pBoardHard->channelIndexRange[chan] = indexRange;
                    fprintf( stderr, "board[%d] chan[%d] set indexRange to %d\n",
                    board, chan, indexRange );
                    found = 1;
                    break;
                }
            }/*for range */
            if (!found) {
                fprintf( stderr, "board[%d] chan[%d] no range good\n",
                board, chan );
                pBoardHard->channelIndexRange[chan] = 0;
            }
        } /* for channel */
        return 0;
    } else {
        numRange = comedi_get_n_ranges(
            pBoardHard->p_comediFileHandle,
            pBoardHard->subDeviceNumber,
            0
        );
        fprintf( stderr, "board[%d] numRange=%d\n", board, numRange );

        for (indexRange = numRange - 1; indexRange >= 0; --indexRange) {
            pVoltageRange = comedi_get_range(
                pBoardHard->p_comediFileHandle,
                pBoardHard->subDeviceNumber,
                0,
                indexRange
            );
            fprintf( stderr, "board[%d] VRange[%d]: min=%lf max=%lf\n", board, indexRange,
                pVoltageRange->min,
                pVoltageRange->max
            );
            if (pVoltageRange->min <= pBoardSoft->lopr &&
            pVoltageRange->max >= pBoardSoft->hopr) {
                fprintf( stderr, "board[%d]  all channel set indexRange to %d\n", board, indexRange );
                int chan;
                for (chan = 0; chan < pBoardSoft->numberOfActiveAnalogInputs; ++chan) {
                    pBoardHard->channelIndexRange[chan] = indexRange;
                }
                return 0;
            }
        }/* for range */
        fprintf( stderr, "failed to find range for lopr=%lf hopr=%lf\n",
            pBoardSoft->lopr,
            pBoardSoft->hopr
        );
        return -1;
    }
}