def write_comedi_ao(aochAO, cmdao, waveform, chunksize=1024): data = byte_convert(waveform) # waveform.tobytes() err = c.comedi_command(aochAO.dev, cmdao) if err < 0: comedi_errcheck() m = os.write(aochAO.fd, data[:]) print("Writing", m, "of", len(waveform), "bytes") if m == 0: raise Exception('NICOMEDI: write error') ret = 0 while ret == 0: ret = intn_trig(aochAO) print('NICOMEDI: Internal trigger') if m < len(data): n=m while True: if n < len(data): written = False while not written: try: m = os.write(aochAO.fd, data[n:]) written = True except BrokenPipeError: pass print("Writing ", m, " bytes") n += m if m < 0: raise Exception('NICOMEDI: write error') if m == 0: break else: m = 0 if m == 0: break
def record(aich, cmd, s=None): #execute the command! sys.stdout.write("NICOMEDI: Recording\n") sys.stdout.flush() ret = c.comedi_command(aich.dev, cmd) if ret != 0: comedi_errcheck()
def get_data(self,channels,gains,refs,frequency,period): self.collect_data_stop() self.comedi_reset() self.reset_queues() self.setup_filtering() cmd = self.prepare_cmd(channels, gains,refs,frequency) #Get base timestamp here with tap delay self.adc_time = datetime.datetime.utcnow() ret = c.comedi_command(self.dev,cmd) if ret<0: self.logger.error("Error executing comedi_command") return -1 if self.speed_flag == "ls": self.collector_thread = threading.Thread(target=self.ls_collect_data) self.collector_thread.daemon = True self.collector_thread.start() self.filter_thread = threading.Thread(target=self.filter_data) self.filter_thread.daemon = True self.filter_thread.start() else: self.collector_thread = threading.Thread(target=self.hs_collect_data) self.collector_thread.daemon = True self.collector_thread.start() if period > 0: self.stop_timer = threading.Timer(period,self.collect_data_stop) self.stop_timer.daemon = True self.stop_timer.start()
def acquire_cb(self, state): #print("acq callback") #print(state) if (self.action_acq.get_active()): # This is commented because it seems that comedi_cancel() # clears stale data in the fd and card? #data = os.read(self.fd, BUF_SIZE) #print("LEN DATA: %d" % len(data)) # Start comedi command ret = c.comedi_command(self.dev, self.cmd) if (ret != 0): self.warn_dialog("PCI-6033E cannot collect data! Error: %d" % ret) print(c.comedi_strerror(c.comedi_errno())) return(False) #self.timer_id = GObject.timeout_add(100, self.my_timer) # Make these timeouts configurable... self.plotter_id = GObject.timeout_add(250, self.update_plots) self.plot_id = GObject.timeout_add(500, self.num_data_timer) self.timer_id = GObject.timeout_add(20, self.pci_6033e_get_data) #self.plot_timer.start() self.action_acq.set_label("Halt") else: self.action_acq.set_label("Acquire") if (self.timer_id): if (c.comedi_cancel(self.dev, SUBDEVICE) < 0): print("failed to cancel comedi command...") GObject.source_remove(self.timer_id) if (self.plot_id): GObject.source_remove(self.plot_id) if (self.plotter_id): GObject.source_remove(self.plotter_id) #self.plot_timer.stop() # Empty stale data self.data_buf = ""
def write_comedi_ao(aochAO, cmdao, waveform, chunksize=1024): data = byte_convert(waveform) # waveform.tobytes() err = c.comedi_command(aochAO.dev, cmdao) if err < 0: comedi_errcheck() m = os.write(aochAO.fd, data[:]) print("Writing", m, "of", len(waveform), "bytes") if m == 0: raise Exception('NICOMEDI: write error') ret = 0 while ret == 0: ret = intn_trig(aochAO) print('NICOMEDI: Internal trigger') if m < len(data): n = m while True: if n < len(data): written = False while not written: try: m = os.write(aochAO.fd, data[n:]) written = True except BrokenPipeError: pass print("Writing ", m, " bytes") n += m if m < 0: raise Exception('NICOMEDI: write error') if m == 0: break else: m = 0 if m == 0: break
def streamer(device,subdevice,chans,comedi_range,shared_array): ''' read the channels defined in chans, on the device/subdevice, and streams the values in the shared_array. The shared_array has a lock, to avoid reading and writing at the same time and it's process-proof. device: '/dev/comedi0' subdevice : 0=in, 1=out chans : [0,1,2,3,4....] : BE AWARE the reading is done crescendo, no matter the order given here. It means that [0,1,2] and [2,0,1] will both have [0,1,2] as result, but you can ask for [0,1,5]. comedi_range: same size as chans, with the proper range for each chan. If unknown, try [0,0,0,....]. shared_array: same size as chans, must be defined before with multiprocess.Array: shared_array= Array('f', np.arange(len(chans))) ''' dev=c.comedi_open(device) if not dev: raise "Error openning Comedi device" fd = c.comedi_fileno(dev) #get a file-descriptor for use later BUFSZ = 10000 #buffer size freq=8000# acquisition frequency: if too high, set frequency to maximum. nchans = len(chans) #number of channels aref =[c.AREF_GROUND]*nchans mylist = c.chanlist(nchans) #create a chanlist of length nchans maxdata=[0]*(nchans) range_ds=[0]*(nchans) for index in range(nchans): #pack the channel, gain and reference information into the chanlist object mylist[index]=c.cr_pack(chans[index], comedi_range[index], aref[index]) maxdata[index]=c.comedi_get_maxdata(dev,subdevice,chans[index]) range_ds[index]=c.comedi_get_range(dev,subdevice,chans[index],comedi_range[index]) cmd = c.comedi_cmd_struct() period = int(1.0e9/freq) # in nanoseconds ret = c.comedi_get_cmd_generic_timed(dev,subdevice,cmd,nchans,period) if ret: raise "Error comedi_get_cmd_generic failed" cmd.chanlist = mylist # adjust for our particular context cmd.chanlist_len = nchans cmd.scan_end_arg = nchans cmd.stop_arg=0 cmd.stop_src=c.TRIG_NONE t0 = time.time() j=0 ret = c.comedi_command(dev,cmd) if ret !=0: raise "comedi_command failed..." #Lines below are for initializing the format, depending on the comedi-card. data = os.read(fd,BUFSZ) # read buffer and returns binary data data_length=len(data) #print maxdata #print data_length if maxdata[0]<=65536: # case for usb-dux-D n = data_length/2 # 2 bytes per 'H' format = `n`+'H' elif maxdata[0]>65536: #case for usb-dux-sigma n = data_length/4 # 2 bytes per 'H' format = `n`+'I' #print struct.unpack(format,data) # init is over, start acquisition and stream last_t=time.time() try: while True: #t_now=time.time() #while (t_now-last_t)<(1./frequency): #t_now=time.time() ##print t_now-last_t #last_t=t_now data = os.read(fd,BUFSZ) # read buffer and returns binary data #print len(data), data_length if len(data)==data_length: datastr = struct.unpack(format,data) # convert binary data to digital value if len(datastr)==nchans: #if data not corrupted for some reason #shared_array.acquire() for i in range(nchans): shared_array[i]=c.comedi_to_phys((datastr[i]),range_ds[i],maxdata[i]) #print datastr #shared_array.release() #j+=1 #print j #print "Frequency= ",(j/(time.time()-t0)) #print np.transpose(shared_array[:]) except (KeyboardInterrupt): c.comedi_cancel(dev,subdevice) ret = c.comedi_close(dev) if ret !=0: raise "comedi_close failed..."
front = 0 back = 0 flag = 1 time_limit = nchans*freq*2*secs # stop scan after "secs" seconds print 'time_limit' , time_limit t0 = time.time() pause = float(packetSize)/nchans/freq/4 print 'pause' , pause alldata = numpy.empty((time_limit/2) , dtype = 'i2') ret = c.comedi_command(dev,cmd) if ret<0: raise "error executing comedi_command" while flag: print 'buffer offset', c.comedi_get_buffer_offset(device, subdevice) print ' buffer contents', c.comedi_get_buffer_contents(device, subdevice) front += c.comedi_get_buffer_contents(dev,subdevice) print "front = ", front if front > time_limit: flag = 0 t1 = time.time() # reached "secs" seconds c.comedi_cancel(device, subdevice) c.comedi_poll(device, subdevice)
def streamer(device, subdevice, chans, comedi_range, shared_array): ''' read the channels defined in chans, on the device/subdevice, and streams the values in the shared_array. The shared_array has a lock, to avoid reading and writing at the same time and it's process-proof. device: '/dev/comedi0' subdevice : 0=in, 1=out chans : [0,1,2,3,4....] : BE AWARE the reading is done crescendo, no matter the order given here. It means that [0,1,2] and [2,0,1] will both have [0,1,2] as result, but you can ask for [0,1,5]. comedi_range: same size as chans, with the proper range for each chan. If unknown, try [0,0,0,....]. shared_array: same size as chans, must be defined before with multiprocess.Array: shared_array= Array('f', np.arange(len(chans))) ''' dev = c.comedi_open(device) if not dev: raise "Error openning Comedi device" fd = c.comedi_fileno(dev) #get a file-descriptor for use later BUFSZ = 10000 #buffer size freq = 8000 # acquisition frequency: if too high, set frequency to maximum. nchans = len(chans) #number of channels aref = [c.AREF_GROUND] * nchans mylist = c.chanlist(nchans) #create a chanlist of length nchans maxdata = [0] * (nchans) range_ds = [0] * (nchans) for index in range( nchans ): #pack the channel, gain and reference information into the chanlist object mylist[index] = c.cr_pack(chans[index], comedi_range[index], aref[index]) maxdata[index] = c.comedi_get_maxdata(dev, subdevice, chans[index]) range_ds[index] = c.comedi_get_range(dev, subdevice, chans[index], comedi_range[index]) cmd = c.comedi_cmd_struct() period = int(1.0e9 / freq) # in nanoseconds ret = c.comedi_get_cmd_generic_timed(dev, subdevice, cmd, nchans, period) if ret: raise "Error comedi_get_cmd_generic failed" cmd.chanlist = mylist # adjust for our particular context cmd.chanlist_len = nchans cmd.scan_end_arg = nchans cmd.stop_arg = 0 cmd.stop_src = c.TRIG_NONE t0 = time.time() j = 0 ret = c.comedi_command(dev, cmd) if ret != 0: raise "comedi_command failed..." #Lines below are for initializing the format, depending on the comedi-card. data = os.read(fd, BUFSZ) # read buffer and returns binary data data_length = len(data) #print maxdata #print data_length if maxdata[0] <= 65536: # case for usb-dux-D n = data_length / 2 # 2 bytes per 'H' format = ` n ` + 'H' elif maxdata[0] > 65536: #case for usb-dux-sigma n = data_length / 4 # 2 bytes per 'H' format = ` n ` + 'I' #print struct.unpack(format,data) # init is over, start acquisition and stream last_t = time.time() try: while True: #t_now=time.time() #while (t_now-last_t)<(1./frequency): #t_now=time.time() ##print t_now-last_t #last_t=t_now data = os.read(fd, BUFSZ) # read buffer and returns binary data #print len(data), data_length if len(data) == data_length: datastr = struct.unpack( format, data) # convert binary data to digital value if len(datastr ) == nchans: #if data not corrupted for some reason #shared_array.acquire() for i in range(nchans): shared_array[i] = c.comedi_to_phys( (datastr[i]), range_ds[i], maxdata[i]) #print datastr #shared_array.release() #j+=1 #print j #print "Frequency= ",(j/(time.time()-t0)) #print np.transpose(shared_array[:]) except (KeyboardInterrupt): c.comedi_cancel(dev, subdevice) ret = c.comedi_close(dev) if ret != 0: raise "comedi_close failed..."
ret = c.comedi_command_test(dev, cmd) print "first cmd test returns ", ret, cmdtest_messages[ret] if ret < 0: raise Exception("comedi_command_test failed") dump_cmd(cmd) ret = c.comedi_command_test(dev, cmd) print("second test returns ", ret, cmdtest_messages[ret]) if ret < 0: raise Exception("comedi_command_test failed") if ret != 0: dump_cmd(cmd) raise Exception("ERROR preparing command") dump_cmd(cmd) ret = c.comedi_command(dev, cmd) if ret < 0: raise Exception("error executing comedi_command") front = 0 back = 0 of = open("stream_log.bin", "wb") format = "H" flag = 1 time_limit = nchans * freq * 2 * secs # stop scan after "secs" seconds t0 = time.time()
def acquire_data(config): """ Acquire data from data acquisition device. """ #Open a comedi device dev = c.comedi_open(config['device']) if not dev: err_msg = "%s: error: unable to open openning Comedi device" % ( PROG_NAME, ) sys.stderr.write(err_msg) sys.exit(1) # Get a file-descriptor to access data fd = c.comedi_fileno(dev) # Setup channels nchans = len(config['channels']) aref_str = config['aref'].lower() if aref_str == 'diff': aref = [c.AREF_DIFF] * nchans elif aref_str == 'common': aref = [c.AREF_COMMON] * nchans elif aref_str == 'ground': aref = [c.AREF_GROUND] * nchans else: raise ValueError, 'unknown aref' #nchans = len(config['channels']) #aref =[c.AREF_GROUND]*nchans # Pack the channel, gain and reference information into the chanlist object channel_list = c.chanlist(nchans) for i in range(nchans): channel_list[i] = c.cr_pack(config['channels'][i], config['gains'][i], aref[i]) # Construct a comedi command cmd = c.comedi_cmd_struct() cmd.subdev = config['subdev'] cmd.flags = DEFAULT_CMD_FLAGS cmd.start_src = c.TRIG_NOW cmd.sart_arg = DEFAULT_CMD_SART_ARG cmd.scan_begin_src = c.TRIG_TIMER cmd.scan_begin_arg = int(NANO_SEC / config['sample_freq']) cmd.convert_src = c.TRIG_TIMER cmd.convert_arg = DEFAULT_CMD_CONVERT_ARG cmd.scan_end_src = c.TRIG_COUNT cmd.scan_end_arg = nchans cmd.stop_src = c.TRIG_COUNT cmd.stop_arg = config['sample_num'] cmd.chanlist = channel_list cmd.chanlist_len = nchans # Test comedi command if config['verbose']: print 'Testing comedi command' print for i in range(0, DEFAULT_CMD_TEST_NUM): if config['verbose']: print_cmd(cmd) ret = c.comedi_command_test(dev, cmd) if config['verbose']: print print '\t*** test %d returns %s' % (i, CMD_TEST_MSG[ret]) print if not ret == 0: msg_data = (PROG_NAME, CMD_TEST_MSG[ret]) err_msg = '%s: error: unable to configure daq device - %s' % msg_data sys.stderr.write(err_msg) # Acquire data if config['verbose']: print 'acquiring data' print sys.stdout.flush() ret = c.comedi_command(dev, cmd) # non blocking if not ret == 0: err_msg = '%s: error: unable to execute comedi command' % (PROG_NAME, ) sys.stderr.write(err_msg) sys.exit(1) # Read data from buffer - may want to add a timeout here read_done = False bytes_total = 2 * config['sample_num'] * nchans bytes_read = 0 datastr = '' while not read_done: try: buffstr = os.read(fd, bytes_total) except OSError, err: if err.args[0] == 4: continue raise datastr += buffstr bytes_read += len(buffstr) if config['verbose']: print '\tread:', bytes_read, 'of', 2 * config[ 'sample_num'] * nchans, 'bytes' if bytes_read == bytes_total: read_done = True