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; }
static int init_board(void) { dev = comedi_open("/dev/comedi0"); printf("Comedi device (6071) handle: %p.\n", dev); if (!dev){ printf("Unable to open (6071) %s.\n", "/dev/comedi0"); return 1; } subdevai = comedi_find_subdevice_by_type(dev, COMEDI_SUBD_AI, 0); if (subdevai < 0) { comedi_close(dev); printf("AI subdev (6071) %d not found.\n", COMEDI_SUBD_AI); return 1; } comedi_get_krange(dev, subdevai, 0, AI_RANGE, &krangeai); maxdatai = comedi_get_maxdata(dev, subdevai, 0); subdevao = comedi_find_subdevice_by_type(dev, COMEDI_SUBD_AO, 0); if (subdevao < 0) { comedi_close(dev); printf("AO subdev (6071) %d not found.\n", COMEDI_SUBD_AO); return 1; } comedi_get_krange(dev, subdevao, 0, AO_RANGE, &krangeao); maxdatao = comedi_get_maxdata(dev, subdevao, 0); return 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; }
/** * @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); }
/** * @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; }
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 = ""; }
int init_dio(void) { int i = 0; if (!DEV_OPEN) { it = comedi_open(comedi_dev); if (it == NULL) { comedi_perror("comedi_open"); DIO_OPEN = FALSE; DEV_OPEN = FALSE; return -1; } DEV_OPEN = TRUE; } subdev_dio = comedi_find_subdevice_by_type(it, COMEDI_SUBD_DIO, subdev_dio); if (subdev_dio < 0) { return -1; DIO_OPEN = FALSE; } printf("Subdev %i ", subdev_dio); channels_dio = comedi_get_n_channels(it, subdev_dio); printf("Digital Channels %i ", channels_dio); maxdata_dio = comedi_get_maxdata(it, subdev_dio, i); printf("Maxdata %i ", maxdata_dio); ranges_dio = comedi_get_n_ranges(it, subdev_dio, i); printf("Ranges %i \n", ranges_dio); DIO_OPEN = TRUE; return 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); }
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; }
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; }
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; }
static void mdlOutputs(SimStruct *S, int_T tid) { double *y = ssGetOutputPortRealSignal(S,0); #ifndef MATLAB_MEX_FILE unsigned int channel = (unsigned int)COMEDI_CHANNEL; unsigned int range = (unsigned int)COMEDI_RANGE; unsigned int aref = (unsigned int)COMEDI_REFERENCE - 1; void *dev = (void *)ssGetPWork(S)[0]; int subdev = ssGetIWork(S)[0]; double range_min = ssGetRWork(S)[0]; double range_max = ssGetRWork(S)[1]; lsampl_t data, maxdata = comedi_get_maxdata(dev, subdev, COMEDI_CHANNEL); double x; comedi_data_read(dev, subdev, channel, range, aref, &data); x = data; x /= maxdata; x *= (range_max - range_min); x += range_min; *y = x; #endif }
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); }
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); }
int main(int argc, char *argv[]) { int ret; comedi_insn insn; lsampl_t d[5]; comedi_t *device; int freq; struct parsed_options options; init_parsed_options(&options); options.freq = -1; // we hijack this option to switch it on or off options.n_scan = -1; options.value = -1; parse_options(&options, argc, argv); if ((options.value==-1)&&(options.n_scan==-1)&&(options.freq==-1)) { fprintf(stderr, "Usage: %s OPTIONS duty_cycle\n" "options: \n" " -N 0 switches PWM off\n" " -N 1 switches PWM on\n" " -N 2 enquires the max value for the duty cycle\n" " -F FREQ sets the PWM frequency\n", argv[0]); } device = comedi_open(options.filename); if(!device){ comedi_perror(options.filename); exit(-1); } options.subdevice = comedi_find_subdevice_by_type(device,COMEDI_SUBD_PWM,0); if (options.verbose) printf("PWM subdevice autodetection gave subdevice number %d\n", options.subdevice); if(options.n_scan==2) { printf("%d\n",comedi_get_maxdata(device,options.subdevice,0)); comedi_close(device); exit(0); } insn.insn=INSN_CONFIG; insn.data=d; insn.subdev=options.subdevice; insn.chanspec=CR_PACK(0,0,0); if(options.n_scan==1) { d[0] = INSN_CONFIG_ARM; d[1] = 0; insn.n=2; ret=comedi_do_insn(device,&insn); if(ret < 0){ fprintf(stderr,"Could not switch on:%d\n",ret); comedi_perror(options.filename); exit(-1); } } if(options.n_scan==0) { d[0] = INSN_CONFIG_DISARM; d[1] = 0; insn.n=1; ret=comedi_do_insn(device,&insn); if(ret < 0){ fprintf(stderr,"Could not switch off:%d\n",ret); comedi_perror(options.filename); exit(-1); } } if(options.freq>0) { freq = options.freq; d[0] = INSN_CONFIG_PWM_SET_PERIOD; d[1] = 1E9/freq; insn.n=2; ret=comedi_do_insn(device,&insn); if(ret < 0){ fprintf(stderr,"Could set frequ:%d\n",ret); comedi_perror(options.filename); exit(-1); } } d[0] = INSN_CONFIG_GET_PWM_STATUS; insn.n=2; ret=comedi_do_insn(device,&insn); if(ret < 0){ fprintf(stderr,"Could not get status:%d insn=%d\n", ret, d[0]); comedi_perror(options.filename); exit(-1); } if (options.verbose) { if (d[1]) fprintf(stderr, "PWM is on.\n"); else fprintf(stderr, "PWM is off.\n"); } d[0] = INSN_CONFIG_PWM_GET_PERIOD; insn.n=2; ret=comedi_do_insn(device,&insn); if(ret < 0){ fprintf(stderr,"Could get frequ:%d\n",ret); comedi_perror(options.filename); exit(-1); } freq = 1E9 / d[1]; if (options.verbose) fprintf(stderr,"PWM frequency is %d\n", freq); if (options.value>=0) if(comedi_data_write(device, options.subdevice, options.channel, 0, 0, options.value)<0) { fprintf(stderr,"error setting the pwm duty cycle on "); comedi_perror(options.filename); exit(1); } return 0; }
static void init(scicos_block *block) { struct ADCOMDev * comdev = (struct ADCOMDev *) malloc(sizeof(struct ADCOMDev)); *block->work = (void *)comdev; char devName[15]; char board[50]; comedi_krange krange; comdev->channel = block->ipar[0]; comdev->range = block->ipar[1]; comdev->aref = block->ipar[2]; comdev->index = block->ipar[3]; sprintf(devName,"/dev/comedi%d", comdev->index); if (!ComediDev[comdev->index]) { comdev->dev = comedi_open(devName); if (!(comdev->dev)) { fprintf(stderr, "COMEDI %s open failed\n", devName); exit_on_error(); return; } rt_comedi_get_board_name(comdev->dev, board); printf("COMEDI %s (%s) opened.\n\n", devName, board); ComediDev[comdev->index] = comdev->dev; } else comdev->dev = ComediDev[comdev->index]; if ((comdev->subdev = comedi_find_subdevice_by_type(comdev->dev, COMEDI_SUBD_AI, 0)) < 0) { fprintf(stderr, "Comedi find_subdevice failed (No analog input)\n"); comedi_close(comdev->dev); exit_on_error(); return; } if (!ComediDev_AIInUse[comdev->index] && comedi_lock(comdev->dev, comdev->subdev) < 0) { fprintf(stderr, "Comedi lock failed for subdevice %d\n", comdev->subdev); comedi_close(comdev->dev); exit_on_error(); return; } if (comdev->channel >= comedi_get_n_channels(comdev->dev, comdev->subdev)) { fprintf(stderr, "Comedi channel not available for subdevice %d\n", comdev->subdev); comedi_unlock(comdev->dev, comdev->subdev); comedi_close(comdev->dev); exit_on_error(); return; } if ((comedi_get_krange(comdev->dev, comdev->subdev, comdev->channel, comdev->range, &krange)) < 0) { fprintf(stderr, "Comedi get_range failed for subdevice %d\n", comdev->subdev); comedi_unlock(comdev->dev, comdev->subdev); comedi_close(comdev->dev); exit_on_error(); return; } #ifdef SOFTCALIB int flags; if ((flags = comedi_get_subdevice_flags(comdev->dev, comdev->subdev)) < 0) { fprintf(stderr, "Comedi get_subdevice_flags failed for subdevice %d\n", comdev->subdev); } else { if (flags & SDF_SOFT_CALIBRATED) {/* board uses software calibration */ if ((comdev->use_softcal = get_softcal_coef(devName, comdev->subdev, comdev->channel, comdev->range, 0, comdev->coefficients)) == 0) fprintf(stderr, "No software calibration found for AI Channel %d\n",comdev->channel); } } #endif ComediDev_InUse[comdev->index]++; ComediDev_AIInUse[comdev->index]++; comdev->maxdata = comedi_get_maxdata(comdev->dev, comdev->subdev, comdev->channel); comdev->range_min = (double)(krange.min)*1.e-6; comdev->range_max = (double)(krange.max)*1.e-6; printf("AI Channel %d - Range : %1.2f [V] - %1.2f [V]%s\n\n", comdev->channel, comdev->range_min, comdev->range_max, (comdev->use_softcal)?" Software calibration used":""); }
/* -------------------------------------------------------------------- */ 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); */ }
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()) ); }
/** * @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; }
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; }
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); }
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; }
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; }
static long dsetInit_devDoSyncComedi (boRecord *pbo) { CONTEXT *p_myContext; comediSupport *p_myBinaryOutput; #ifdef DEBUG1 packageInfo(); printf( __FILE__ "[%d] -> %s \n", __LINE__, __func__ ); #endif #ifdef DEBUG2 printf( __FILE__ "[%d] Initializing %s\n", __LINE__, pbo->name); #endif p_myBinaryOutput=(comediSupport *)calloc(1,sizeof(comediSupport)); /* Get the options from the db file */ sscanf(pbo->out.value.instio.string, "d=%s s=%d c=%d", p_myBinaryOutput->filename, &p_myBinaryOutput->subdevice, &p_myBinaryOutput->channel); #ifdef DEBUG2 printf(__FILE__ "[%d] Parsed options >%s<\n", __LINE__, pbo->out.value.instio.string); printf(__FILE__ "[%d] filename = >%s<\n", __LINE__, p_myBinaryOutput->filename); printf(__FILE__ "[%d] subdevice = %d\n", __LINE__, p_myBinaryOutput->subdevice); printf(__FILE__ "[%d] channel = %d\n", __LINE__, p_myBinaryOutput->channel); #endif p_myBinaryOutput->device=comedi_open(p_myBinaryOutput->filename); p_myBinaryOutput->maxdata=comedi_get_maxdata( p_myBinaryOutput->device, p_myBinaryOutput->subdevice, p_myBinaryOutput->channel); /* p_myBinaryOutput->c_range=comedi_get_range( p_myBinaryOutput->device, p_myBinaryOutput->subdevice, p_myBinaryOutput->channel, p_myBinaryOutput->range); */ if (initComediDO(p_myBinaryOutput) <= ERROR ) { printf(__FILE__ "[%d] Error: Couldn't intialize %s\n", __LINE__, pbo->name); sleep(SLEEPTIME_ERROR); return(ERROR); } /* Save the context */ p_myContext=(CONTEXT *)calloc(1,sizeof(CONTEXT)); p_myContext->p_binaryOutput=p_myBinaryOutput; #ifdef WARMSTART p_myContext->operatingMode=WARMSTART_MODE; pbo->pini=menuYesNoYES; #endif pbo->dpvt=(void *)p_myContext; #ifdef DEBUG1 printf( __FILE__ "[%d] <- %s\n", __LINE__, __func__ ); #endif return(SUCCESS); }
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; }
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; }
int PLLReferenceGeneration() { //Initial test function to try out Real time stuff. int m, i=0, err, n; lsampl_t data_to_card; static comedi_t * dev; static int OutputFIFOBufferSize; static int PLLGenerationBufferSize; unsigned int maxdata; unsigned int chanlist[16]; int ret; static lsampl_t data[PLLGenerationBufferNPoints]; //this is the buffer used to send data points out comedi_cmd cmd; dev = comedi_open(device_names[PLLReferenceGenerationChannel.board_number]); //Check the size of the output buffer OutputFIFOBufferSize = comedi_get_buffer_size(dev, PLLReferenceGenerationChannel.subdevice); rt_printk("OutputFIFO Buffer size is %i\n", OutputFIFOBufferSize); //Set the actual buffer size that we will be using to half this and the number of data points to one fourth //Now configure the output channel using a Comedi instruction //BufferSize is initially set to be double the number of PLLGenerationBufferNPoints PLLGenerationBufferSize = 2*PLLGenerationBufferNPoints; maxdata = comedi_get_maxdata(dev, PLLReferenceGenerationChannel.subdevice, PLLReferenceGenerationChannel.channel); rt_printk("PLL Reference channel max data is %i\n", maxdata); offset = maxdata / 2; amplitude = maxdata - offset; memset(&cmd,0,sizeof(cmd)); cmd.subdev = PLLReferenceGenerationChannel.subdevice; cmd.flags = CMDF_WRITE; cmd.start_src = TRIG_INT; cmd.start_arg = 0; cmd.scan_begin_src = TRIG_TIMER; cmd.scan_begin_arg = PLLGenMinPulseTime; //minimum update time for the cmd.convert_src = TRIG_NOW; cmd.convert_arg = 0; cmd.scan_end_src = TRIG_COUNT; cmd.scan_end_arg = NCHAN; //only one channel cmd.stop_src = TRIG_NONE; cmd.stop_arg = 0; cmd.chanlist = chanlist; cmd.chanlist_len = NCHAN; chanlist[0] = CR_PACK(PLLReferenceGenerationChannel.channel, AO_RANGE, AREF_GROUND); dds_init(PLLWaveformFrequency, PLLUpdateFrequency); err = comedi_command_test(dev, &cmd); if (err < 0) { comedi_perror("comedi_command_test"); exit(1); } err = comedi_command_test(dev, &cmd); if (err < 0) { comedi_perror("comedi_command_test"); exit(1); } if ((err = comedi_command(dev, &cmd)) < 0) { comedi_perror("comedi_command"); exit(1); } dds_output(data,PLLGenerationBufferNPoints); n = PLLGenerationBufferNPoints * sizeof(sampl_t); m = write(comedi_fileno(dev), (void *)data, n); if(m < 0){ perror("write"); exit(1); }else if(m < n) { fprintf(stderr, "failed to preload output buffer with %i bytes, is it too small?\n" "See the --write-buffer option of comedi_config\n", n); exit(1); } if(!(PLLRefGen_Task = rt_task_init_schmod(nam2num( "PLLReferenceGeneration" ), // Name 2, // Priority 0, // Stack Size 0, //, // max_msg_size SCHED_FIFO, // Policy CPUMAP ))) // cpus_allowed { printf("ERROR: Cannot initialize pll reference generation task\n"); exit(1); } //specify that this is to run on one CPU rt_set_runnable_on_cpuid(PLLRefGen_Task, 1); //Convert samp_time, which is in nanoseconds, to tick time //sampling_interval = nano2count(SAMP_TIME); //Converts a value from //nanoseconds to internal count units. mlockall(MCL_CURRENT|MCL_FUTURE); rt_make_hard_real_time(); PLLUpdateTime = nano2count(PLLGenerationLoopTime); rt_printk("PLL generation update time is %f12 \n",count2nano((float) PLLUpdateTime)); // Let's make this task periodic.. expected = rt_get_time() + 100*PLLUpdateTime; rt_task_make_periodic(PLLRefGen_Task, expected, PLLUpdateTime); //period in counts //rt_task_resume(Sinewaveloop_Task); PLLGenerationOn = TRUE; // Concurrent function Loop //rt_printk("SineWaveAmplitude is is %f \n",SineWaveAmplitude); //rt_printk("SineWaveFrequency is %f \n",SineWaveFrequency); //rt_printk("sine_loop_running is %d \n",sine_loop_running); //rt_printk("SAMP_TIME is %d \n",SAMP_TIME); start_time = (float)rt_get_time_ns()/1E9; //in seconds old_time = start_time; rt_printk("PLLReferenceGenerationChannel board_it is %p \n",PLLReferenceGenerationChannel.board_id); rt_printk("PLLReferenceGenerationChannel devicename is %p \n",*(PLLReferenceGenerationChannel.devicename)); rt_printk("PLLReferenceGenerationChannel boardname is %p \n",*(PLLReferenceGenerationChannel.boardname)); rt_printk("PLLReferenceGenerationChannel subdevice is %d \n",PLLReferenceGenerationChannel.subdevice); rt_printk("PLLReferenceGenerationChannel channel is %d \n",PLLReferenceGenerationChannel.channel); OutputValue = 1; PLLGenerationBufferSize = comedi_get_buffer_size(dev, PLLReferenceGenerationChannel.subdevice); //sine_loop_running = 0; //set this to 0 for testing while(PLLGenerationOn) { i++; // Count Loops. current_time = (float)rt_get_time_ns()/1E9; //rt_printk("LOOP %d,-- Period time: %f12 %f12\n",i, current_time - old_time,count2nano((float)sampling_interval)/1E9); OutputValue = SineWaveAmplitude*sin(2*PI*SineWaveFrequency*(current_time-start_time)); //OutputValue = -1*OutputValue; //rt_printk("OutputValue is %f12 \n",OutputValue); data_to_card = (lsampl_t) nearbyint(((OutputValue - MinOutputVoltage)/OutputRange)*MaxOutputBits); //m=rt_comedi_command_data_write(AnalogOutputChannel.board_id, AnalogOutputChannel.subdevice, NCHAN, data_to_card); comedi_lock(dev, AnalogOutputChannel.subdevice); m=comedi_data_write(dev, AnalogOutputChannel.subdevice, AnalogOutputChannel.channel, AO_RANGE, AREF_DIFF, data_to_card); comedi_unlock(dev, AnalogOutputChannel.subdevice); // m=comedi_data_write(AnalogOutputChannel.board_id, AnalogOutputChannel.subdevice, // AnalogOutputChannel.channel, AO_RANGE, AREF_GROUND, data_to_card); //rt_printk("Data_to_card is %d; result from rt_comedi_command_data_write is %d \n",data_to_card, m); //rt_printk("LOOP %d,-- AO Out time: %f12 \n",i, (float)rt_get_time_ns()/1E9 - current_time); //rt_printk("Data_to_card is %d \n",data_to_card); //old_time = current_time; /* if (i== 100000) { sine_loop_running = 0; //printf("LOOP -- run: %d %d\n ",keep_on_running,&keep_on_running); //printf("RTAI LOOP -- run: %d \n ",i); break; } */ rt_task_wait_period(); // And waits until the end of the period. } rt_make_soft_real_time(); comedi_close(dev); rt_task_delete(Sinewaveloop_Task); //Self termination at end. pthread_exit(NULL); return 0; }
int32 ATIDAQHardwareInterface::ConfigSingleSampleTask( float64 sampleRate, int averaging, const std::string & deviceName, int firstChannel, int numChannels, int minVoltage, int maxVoltage ) { int32 retVal = 0; /*the return value <0 is err >0 is warning, 0 ok*/ /*we have to use unmanaged c-style strings in here because that's what the NI-DAQmx C Library uses*/ char channelString[WHOLE_LOTTA_CHARACTERS]; /*the channel string, of format "Dev1/ai0:5"*/ /*set up member data*/ m_f64SamplingFrequency = sampleRate; m_uiAveragingSize = ( averaging > 0 )? averaging : 1; /*averaging must be at least 1*/ m_sDeviceName = deviceName; m_uiFirstChannel = firstChannel; m_uiNumChannels = numChannels; //for this we are using bipolar so do the reverse... // if ( m_Calibration->BiPolar ) // { // m_iMinVoltage += ( m_Calibration->VoltageRange / 2 ); // m_dLowerSaturationVoltage = m_iMinVoltage * GAUGE_SATURATION_LEVEL; // m_iMaxVoltage += ( m_Calibration->VoltageRange / 2 ); // m_dUpperSaturationVoltage = m_iMaxVoltage * GAUGE_SATURATION_LEVEL; // } // //make sure the out of range is returned as a number comedi_set_global_oor_behavior(COMEDI_OOR_NUMBER); m_iMinVoltage = minVoltage; m_iMaxVoltage = maxVoltage; range.max= m_iMaxVoltage; range.min= m_iMinVoltage; range.unit = UNIT_volt; // comediDev = comedi_open(m_sDeviceName.c_str()); //error; if (comediDev == NULL) { comedi_perror(m_sDeviceName.c_str()); return -1; } maxdata = comedi_get_maxdata(comediDev, 0,0); //create an instruction set to grab readings one by one. insn = new comedi_insn[m_uiNumChannels]; dataArray = new lsampl_t[m_uiNumChannels]; /* Set up a the "instruction list", which is just a pointer * to the array of instructions and the number of instructions. */ il.n_insns = m_uiNumChannels; il.insns = insn; for (int chan = 0 ; chan < m_uiNumChannels ; chan ++){ /* Instruction 1: do 10 analog input reads */ insn[chan].insn = INSN_READ; insn[chan].n = 1; insn[chan].data = &(dataArray[chan]); insn[chan].subdev = 0; insn[chan].chanspec = CR_PACK(chan,0,AREF_DIFF); } // unsigned int numSamplesPerChannel = m_uiAveragingSize; /*the number of samples per channel that daqmx is configured with*/ // /*in a perfect world, NI-DAQmx would allow us to set up single scan acquisitions, but they don't. // even if we were to make the single sample task a finite sample task, they still require you to use // at least 2 samples per channel. Therefore, we pass daqmx a number of samples per channel that it // will accept, and then set up our task to only read the most recent samples*/ // if ( MIN_SAMPLES_PER_CHANNEL > numSamplesPerChannel ) numSamplesPerChannel = MIN_SAMPLES_PER_CHANNEL; // // ati_Channel_Name_Format( channelString, m_sDeviceName ); /* Format the channel name for niDAQmx */ // // /*if the following confuses you, I suggest you read the NI-DAQmx C Reference Help, included // with NI-DAQmx*/ // StopCollection(); /*stop currently running task*/ // /*if any function fails (returns non-zero), don't execute any more daqmx functions*/ // /*create the daqmx task*/ // if( !( retVal = DAQmxCreateTask( "", m_thDAQTask ) ) ) // /*add the analog input channels to the task - july.22.2005 - ss - now uses m_iConnectionMode*/ // if( !( retVal = DAQmxCreateAIVoltageChan( *m_thDAQTask, channelString, "", m_iConnectionMode, // m_iMinVoltage, m_iMaxVoltage, DAQmx_Val_Volts, NULL ) ) ) // /*set up timing for the task*/ // if( !( retVal = DAQmxCfgSampClkTiming( *m_thDAQTask, NULL, m_f64SamplingFrequency, // DAQmx_Val_Rising, DAQmx_Val_ContSamps, numSamplesPerChannel ) ) ) // /*set read position relative to next sample to be read*/ // if( !( retVal = DAQmxSetReadRelativeTo( *m_thDAQTask, DAQmx_Val_MostRecentSamp ) ) ) // /*offset of -1 from the next sample, meaning we read the most recent sample*/ // if( !( retVal = DAQmxSetReadOffset( *m_thDAQTask, 0 ) ) ) // /*start the task*/ // retVal = DAQmxStartTask( *m_thDAQTask ); return retVal; }