class ComediIO(): def __init__(self): dev = rospy.get_param('~comedi_dev', '/dev/comedi0') chan_out = rospy.get_param('~comedi_out_chan', 0) chan_in = rospy.get_param('~comedi_in_chan', 0) self.device = Device(dev) self.device.open() subdev_out = self.device.find_subdevice_by_type(SUBDEVICE_TYPE.ao) subdev_in = self.device.find_subdevice_by_type(SUBDEVICE_TYPE.ai) self.channel_out = subdev_out.channel(chan_out, factory=AnalogChannel, aref=AREF.ground) self.channel_in = subdev_in.channel(chan_in, factory=AnalogChannel, aref=AREF.ground) self.channel_out.range = self.channel_out.find_range(unit=UNIT.volt, min=0, max=10) self.channel_in.range = self.channel_in.find_range(unit=UNIT.volt, min=1, max=5) self.max = self.channel_in.get_maxdata() self.conv_out = self.channel_out.get_converter() self.conv_in = self.channel_in.get_converter() def send(self, v_out): self.channel_out.data_write(self.conv_out.from_physical(v_out)) def read(self): #print(self.channel_in.data_read_delayed(nano_sec=10e3)) return self.conv_in.to_physical( self.channel_in.data_read_delayed(nano_sec=10e3))
def generateDevices(self): for i in xrange(self.instrument['main']['devices']): devconf = { 'board': None, 'analog':{ 'in' : None, 'out':None}, 'digital':{ 'in': None, 'out': None, 'io': None}, 'counter': None} device = Device(self.parser.get('Device'+str(i),'path')) device.open() devconf['board'] = device try: devconf['analog']['in'] = device.find_subdevice_by_type( CONSTANTS.SUBDEVICE_TYPE.ai) except PyComediError: pass try: devconf['analog']['out'] = device.find_subdevice_by_type( CONSTANTS.SUBDEVICE_TYPE.ao, factory = StreamingSubdevice) except PyComediError: pass try: devconf['digital']['in'] = device.find_subdevice_by_type( CONSTANTS.SUBDEVICE_TYPE.di) except PyComediError: pass try: devconf['digital']['out'] = device.find_subdevice_by_type( CONSTANTS.SUBDEVICE_TYPE.do) except PyComediError: pass try: devconf['digital']['io'] = device.find_subdevice_by_type( CONSTANTS.SUBDEVICE_TYPE.dio) except PyComediError: pass try: devconf['counter'] = device.find_subdevice_by_type( CONSTANTS.SUBDEVICE_TYPE.counter) except PyComediError: pass self.instrument['devices'][i] = devconf
def __init__(self, start_t): self.start_t = start_t # Connect to DAQ board self.daq_s = Device('/dev/comedi0') self.daq_s.open() subdev = self.daq_s.find_subdevice_by_type(SUBDEVICE_TYPE.dio) # Create 6 channels: 4 pinch valves and 2 3-way valves # Right/Left from perspective of the fly's face looking straight # Chan 0: Left odor pinch valve 1 # Chan 1 Left odor pinch valve 2 # Chan 2: Right odor pinch valve 1 # Chan 3: Right odor pinch valve 2 # Chan 4: Left 3-way # Chan 5: Right 3-way # Chan 6: 2p external trigger # Chan 7: 2p wide field olfactometer trigger self.dio_chans = [] for i in range(8): chan = subdev.channel(i, factory=DigitalChannel) chan.dio_config(IO_DIRECTION.output) self.dio_chans.append( chan ) self.pv_s = [ 0, 0, 0, 0 ] self.SIMPLE_ODOR_VALVE_CHANNEL = 0 self.reset_all()
class ComediIO(): def __init__(self): dev=rospy.get_param('~comedi_dev','/dev/comedi0') chan_out=rospy.get_param('~comedi_out_chan',0) chan_in=rospy.get_param('~comedi_in_chan',0) self.device=Device(dev) self.device.open() subdev_out = self.device.find_subdevice_by_type(SUBDEVICE_TYPE.ao) subdev_in = self.device.find_subdevice_by_type(SUBDEVICE_TYPE.ai) self.channel_out=subdev_out.channel(chan_out, factory=AnalogChannel, aref=AREF.ground) self.channel_in=subdev_in.channel(chan_in, factory=AnalogChannel, aref=AREF.ground) self.channel_out.range=self.channel_out.find_range(unit=UNIT.volt,min=0,max=10) self.channel_in.range=self.channel_in.find_range(unit=UNIT.volt,min=1,max=5) self.max=self.channel_in.get_maxdata() self.conv_out=self.channel_out.get_converter() self.conv_in=self.channel_in.get_converter() def send(self,v_out): self.channel_out.data_write(self.conv_out.from_physical(v_out)) def read(self): #print(self.channel_in.data_read_delayed(nano_sec=10e3)) return self.conv_in.to_physical(self.channel_in.data_read_delayed(nano_sec=10e3))
def __init__(self): dev = rospy.get_param('~comedi_dev', '/dev/comedi0') chan_out = rospy.get_param('~comedi_out_chan', 0) chan_in = rospy.get_param('~comedi_in_chan', 0) self.device = Device(dev) self.device.open() subdev_out = self.device.find_subdevice_by_type(SUBDEVICE_TYPE.ao) subdev_in = self.device.find_subdevice_by_type(SUBDEVICE_TYPE.ai) self.channel_out = subdev_out.channel(chan_out, factory=AnalogChannel, aref=AREF.ground) self.channel_in = subdev_in.channel(chan_in, factory=AnalogChannel, aref=AREF.ground) self.channel_out.range = self.channel_out.find_range(unit=UNIT.volt, min=0, max=10) self.channel_in.range = self.channel_in.find_range(unit=UNIT.volt, min=1, max=5) self.max = self.channel_in.get_maxdata() self.conv_out = self.channel_out.get_converter() self.conv_in = self.channel_in.get_converter()
def initialize(self, streamhandler = None): info = self.device_info = get_info(self.device_path) if self.subdevices is None: self.subdevices = info['subdevices'] sub0 = self.subdevices[0] assert sub0['type'] == 'AnalogInput', 'deal only with AnalogInput at the moment' sel = sub0['by_channel_params']['channel_selection'] self.nb_channel = np.sum(sel) channel_indexes = [e for e, s in zip(sub0['by_channel_params']['channel_indexes'], sel) if s] channel_names = [e for e, s in zip(sub0['by_channel_params']['channel_names'], sel) if s] self.packet_size = int(info['device_packet_size']/self.nb_channel) # compute the real sampling rate print 'sampling_rate wanted:', self.sampling_rate dev = Device(self.device_path) dev.open() ai_subdevice, ai_channels, internal_size = prepare_device(dev, channel_indexes, self.sampling_rate) self.sampling_rate = 1.e9/ai_subdevice.cmd.convert_arg/len(ai_channels) dev.close() print 'sampling_rate real:', self.sampling_rate l = int(self.sampling_rate*self.buffer_length) #~ print l, l - l%self.packet_size, (l - l%self.packet_size)/self.sampling_rate self.buffer_length = (l - l%self.packet_size)/self.sampling_rate self.name = '{} #{}'.format(info['board_name'], info['device_path'].replace('/dev/comedi', '')) s = self.streamhandler.new_AnalogSignalSharedMemStream(name = self.name+' Analog', sampling_rate = self.sampling_rate, nb_channel = self.nb_channel, buffer_length = self.buffer_length, packet_size = self.packet_size, dtype = np.float64, channel_names = channel_names, channel_indexes = channel_indexes, ) self.streams = [s, ]
def __init__(self): dev=rospy.get_param('~comedi_dev','/dev/comedi0') chan_out=rospy.get_param('~comedi_out_chan',0) chan_in=rospy.get_param('~comedi_in_chan',0) self.device=Device(dev) self.device.open() subdev_out = self.device.find_subdevice_by_type(SUBDEVICE_TYPE.ao) subdev_in = self.device.find_subdevice_by_type(SUBDEVICE_TYPE.ai) self.channel_out=subdev_out.channel(chan_out, factory=AnalogChannel, aref=AREF.ground) self.channel_in=subdev_in.channel(chan_in, factory=AnalogChannel, aref=AREF.ground) self.channel_out.range=self.channel_out.find_range(unit=UNIT.volt,min=0,max=10) self.channel_in.range=self.channel_in.find_range(unit=UNIT.volt,min=1,max=5) self.max=self.channel_in.get_maxdata() self.conv_out=self.channel_out.get_converter() self.conv_in=self.channel_in.get_converter()
def get_info(device_path): info = { } dev = Device(device_path) dev.open() info['class'] = 'ComediMultiSignals' info['device_path'] = device_path info['board_name'] = dev.get_board_name() info['global_params'] = { 'sampling_rate' : 4000., 'buffer_length' : 60., } info['subdevices'] = [ ] for sub in dev.subdevices(): if sub.get_type() == SUBDEVICE_TYPE.ai: n = sub.get_n_channels() info_sub = create_analog_subdevice_param(n) info['subdevices'].append(info_sub) #~ elif sub.get_type() == SUBDEVICE_TYPE.di: info['device_packet_size'] = 512 dev.close() return info
def __init__(self, start_t): self.start_t = start_t # Connect to DAQ board self.daq_s = Device('/dev/comedi0') self.daq_s.open() subdev = self.daq_s.find_subdevice_by_type(SUBDEVICE_TYPE.dio) # Create 6 channels: 4 pinch valves and 2 3-way valves # Right/Left from perspective of the fly's face looking straight # Chan 0: Right Odor pinch valve 1 # Chan 1: Right Odor pinch valve 2 # Chan 2: Left Odor pinch valve 1 # Chan 3: Left Odor pinch valve 2 # Chan 4: Left 3-way # Chan 5: Right 3-way # Behavior room mapping: # Shelf BNC | DAQ BNC # 3 | 4 # 1 | 3 # 2 | 2 # 4 | 1 # 6 | RS # 5 | LS self.dio_chans = [] for i in range(6): chan = subdev.channel(i, factory=DigitalChannel) chan.dio_config(IO_DIRECTION.output) self.dio_chans.append( chan ) self.pv_s = [ 0, 0, 0, 0 ] self.reset_all()
def __init__(self): self.device = Device('/dev/comedi0') self.device.open()
class IO_Dev(object): def __init__(self): self.device = Device('/dev/comedi0') self.device.open() def close(self): # Close the device when you're done. self.device.close() def configure_ai(self): """ Get your I/O subdevice (alternatively, use `device.subdevice()` to select the subdevice directly by index). """ subdevice = self.device.find_subdevice_by_type(SUBDEVICE_TYPE.ai) # Generate a list of channels you wish to control. channels = [ subdevice.channel(i, factory=AnalogChannel, aref=AREF.diff) for i in (0, 1, 2, 3) ] # Configure the channels. for chan in channels: chan.range = chan.find_range(unit=UNIT.volt, min=0, max=5) self.ai_converters = [c.get_converter() for c in channels] def configure_ao(self): """ Get your I/O subdevice (alternatively, use `device.subdevice()` to select the subdevice directly by index). """ self.ao_subdevice = self.device.find_subdevice_by_type( SUBDEVICE_TYPE.ao) # Generate a list of channels you wish to control. self.ao_channels = [ self.ao_subdevice.channel(i, factory=AnalogChannel, aref=AREF.diff) for i in (0, 1) ] #for chan in channels: print chan # Configure the channels. for chan in self.ao_channels: chan.range = chan.find_range(unit=UNIT.volt, min=0, max=5) def output(self, channel, volt_output_signal): channel = self.ao_channels[channel] ao_converter = channel.get_converter() channel.data_write(ao_converter.from_physical(volt_output_signal)) def input(self, channel): # Read/write sequentially. value = channel.data_read_delayed(nano_sec=1e3) print value # Use a converter to convert these to physical values return self.ai_converters[channel].to_physical(value)
class DAQRider: def __init__(self, start_t): self.start_t = start_t # Connect to DAQ board self.daq_s = Device('/dev/comedi0') self.daq_s.open() subdev = self.daq_s.find_subdevice_by_type(SUBDEVICE_TYPE.dio) # Create 6 channels: 4 pinch valves and 2 3-way valves # Right/Left from perspective of the fly's face looking straight # Chan 0: Left odor pinch valve 1 # Chan 1 Left odor pinch valve 2 # Chan 2: Right odor pinch valve 1 # Chan 3: Right odor pinch valve 2 # Chan 4: Left 3-way # Chan 5: Right 3-way # Chan 6: 2p external trigger # Chan 7: 2p wide field olfactometer trigger self.dio_chans = [] for i in range(8): chan = subdev.channel(i, factory=DigitalChannel) chan.dio_config(IO_DIRECTION.output) self.dio_chans.append( chan ) self.pv_s = [ 0, 0, 0, 0 ] self.SIMPLE_ODOR_VALVE_CHANNEL = 0 self.reset_all() def activate_simple_odor_valve_channel(self): self.dio_chans[ self.SIMPLE_ODOR_VALVE_CHANNEL ].dio_write( 1 ) def deactivate_simple_odor_valve_channel(self): self.dio_chans[ self.SIMPLE_ODOR_VALVE_CHANNEL ].dio_write( 0 ) def activate_2p_olfactometer_trigger(self): self.dio_chans[ 7 ].dio_write( 1 ) def deactivate_2p_olfactometer_trigger(self): self.dio_chans[ 7 ].dio_write( 0 ) def activate_2p_external_trigger(self): self.dio_chans[ 6 ].dio_write( 1 ) def deactivate_2p_external_trigger(self): self.dio_chans[ 6 ].dio_write( 0 ) def deactivate_3way_valves(self): self.dio_chans[ 4 ].dio_write( 0 ) self.dio_chans[ 5 ].dio_write( 0 ) def activate_3way_valve_left(self): self.dio_chans[ 4 ].dio_write( 1 ) def activate_3way_valve_right(self): self.dio_chans[ 5 ].dio_write( 1 ) def activate_3way_valves(self): self.activate_3way_valve_right() self.activate_3way_valve_left() def activate_pinch_valves(self, valve_state_str): # Assumes the 3-way pinch valves # have air by default if valve_state_str == 'Both_Air' or \ valve_state_str == 'Both_Air_Rev' or \ valve_state_str == 'Left_Air' or \ valve_state_str == 'Left_Air_Rev' or \ valve_state_str == 'Right_Air' or \ valve_state_str == 'Right_Air_Rev': self.pv_s = [ 0, 0, 0, 0 ] elif valve_state_str == 'Both_Odor': self.pv_s = [ 1, 1, 1, 1 ] elif valve_state_str == 'Right_Odor': self.pv_s = [ 0, 0, 1, 1 ] elif valve_state_str == 'Left_Odor': self.pv_s = [ 1, 1, 0, 0 ] else: print "ERROR: valve_state_str not recognized: ", valve_state_str # Send signals to daq board for i, s in enumerate(self.pv_s): self.dio_chans[ i ].dio_write( s ) print "(%f): Activated pinch valves to: %s" % (time.time()-self.start_t, valve_state_str) def deactivate_pinch_valves(self): # deactivate dio channels self.pv_s = [ 0, 0, 0, 0 ] for i, s in enumerate(self.pv_s): self.dio_chans[ i ].dio_write( s ) def close(self): self.daq_s.close() def reset_all(self): self.deactivate_2p_external_trigger() self.deactivate_3way_valves() self.deactivate_2p_olfactometer_trigger() self.deactivate_pinch_valves()
class DAQRider: def __init__(self, start_t): self.start_t = start_t # Connect to DAQ board self.daq_s = Device('/dev/comedi0') self.daq_s.open() subdev = self.daq_s.find_subdevice_by_type(SUBDEVICE_TYPE.dio) # Create 6 channels: 4 pinch valves and 2 3-way valves # Right/Left from perspective of the fly's face looking straight # Chan 0: Right Odor pinch valve 1 # Chan 1: Right Odor pinch valve 2 # Chan 2: Left Odor pinch valve 1 # Chan 3: Left Odor pinch valve 2 # Chan 4: Left 3-way # Chan 5: Right 3-way # Behavior room mapping: # Shelf BNC | DAQ BNC # 3 | 4 # 1 | 3 # 2 | 2 # 4 | 1 # 6 | RS # 5 | LS self.dio_chans = [] for i in range(6): chan = subdev.channel(i, factory=DigitalChannel) chan.dio_config(IO_DIRECTION.output) self.dio_chans.append( chan ) self.pv_s = [ 0, 0, 0, 0 ] self.reset_all() def deactivate_3way_valves(self): self.dio_chans[ 4 ].dio_write( 0 ) self.dio_chans[ 5 ].dio_write( 0 ) def activate_3way_valve_left(self): self.dio_chans[ 4 ].dio_write( 1 ) def activate_3way_valve_right(self): self.dio_chans[ 5 ].dio_write( 1 ) def activate_3way_valves(self): self.activate_3way_valve_right() self.activate_3way_valve_left() def activate_pinch_valves(self, valve_state_str): if valve_state_str == 'Both_Air': self.pv_s = [ 0, 0, 0, 0 ] elif valve_state_str == 'Both_Odor': self.pv_s = [ 1, 1, 1, 1 ] elif valve_state_str == 'Right_Odor': self.pv_s = [ 1, 0, 0, 1 ] elif valve_state_str == 'Left_Odor': self.pv_s = [ 0, 1, 1, 0 ] elif valve_state_str == 'Left_Air': self.pv_s = [ 0, 0, 0, 0 ] elif valve_state_str == 'Right_Air': self.pv_s = [ 0, 0, 0, 0 ] else: print "ERROR: valve_state_str not recognized: ", valve_state_str # Send signals to daq board for i, s in enumerate(self.pv_s): self.dio_chans[ i ].dio_write( s ) print "(%f): Activated pinch valves to: %s" % (time.time()-self.start_t, valve_state_str) def close(self): self.daq_s.close() def reset_all(self): self.deactivate_3way_valves() # deactivate dio channels self.pv_s = [ 0, 0, 0, 0 ] for i, s in enumerate(self.pv_s): self.dio_chans[ i ].dio_write( s )
def device_mainLoop(stop_flag, streams, device_path, device_info ): streamAD = streams[0] packet_size = streamAD['packet_size'] sampling_rate = streamAD['sampling_rate'] arr_ad = streamAD['shared_array'].to_numpy_array() ai_channel_indexes = streamAD['channel_indexes'] nb_ai_channel = streamAD['nb_channel'] half_size = arr_ad.shape[1]/2 context = zmq.Context() socketAD = context.socket(zmq.PUB) socketAD.bind("tcp://*:{}".format(streamAD['port'])) dev = Device(device_path) dev.open() ai_subdevice, ai_channels, internal_size = prepare_device(dev, ai_channel_indexes, sampling_rate) converters = [c.get_converter() for c in ai_channels] print 'soft_calibrated', ai_subdevice.get_flags().soft_calibrated print converters[0] dt = ai_subdevice.get_dtype() itemsize = np.dtype(dt).itemsize ai_buffer = np.memmap(dev.file, dtype = dt, mode = 'r', shape = (internal_size, nb_ai_channel)) ai_subdevice.command() pos = abs_pos = 0 last_index = 0 socketAD.send(msgpack.dumps(abs_pos)) sleep_time = 0.02 while True: #~ try: if 1: new_bytes = ai_subdevice.get_buffer_contents() new_bytes = new_bytes - new_bytes%(nb_ai_channel*itemsize) if new_bytes ==0: time.sleep(sleep_time/2.) continue index = last_index + new_bytes/nb_ai_channel/itemsize if index == last_index : time.sleep(sleep_time/2.) continue if index>=internal_size: new_bytes = (internal_size-last_index)*itemsize*nb_ai_channel index = internal_size #~ if index>=internal_size: #~ new_samp = internal_size - last_index #~ new_samp2 = min(new_samp, arr_ad.shape[1]-(pos+half_size)) #~ for i,c in enumerate(converters): #~ arr_ad[i,pos:pos+new_samp] = c.to_physical(ai_buffer[ last_index:internal_size, i ]) #~ arr_ad[i,pos+half_size:pos+new_samp2+half_size] = arr_ad[i,pos:pos+new_samp2] #~ last_index = 0 #~ index = index%internal_size #~ abs_pos += new_samp #~ pos = abs_pos%half_size new_samp = index - last_index new_samp2 = min(new_samp, arr_ad.shape[1]-(pos+half_size)) #Analog for i,c in enumerate(converters): arr_ad[i,pos:pos+new_samp] = c.to_physical(ai_buffer[ last_index:index, i ]) arr_ad[i,pos+half_size:pos+new_samp2+half_size] = arr_ad[i,pos:pos+new_samp2] abs_pos += int(new_samp) pos = abs_pos%half_size last_index = index%internal_size msgpack.dumps(abs_pos) socketAD.send(msgpack.dumps(abs_pos)) ai_subdevice.mark_buffer_read(new_bytes) #~ except : #~ print 'Problem in acquisition loop' #~ break if stop_flag.value: print 'should stop properly' break try: dev.close() print 'has stop properly' except : print 'not able to stop cbStopBackground properly'