Exemple #1
0
 def __call__(self, device, insn):
     insn.insn = _comedi.INSN_READ
     insn.n = self.n_scan
     data = _comedi.lsampl_array(self.n_scan)
     data.thisown = False
     insn.data = data.cast()
     insn.subdev = self._get_subdevice(device)
     insn.chanspec = _comedi.cr_pack(self.channel, self.range, self.aref)
     return insn
Exemple #2
0
def make_chlist(chans):
    # list containing the chans, gains and referencing
    nchans = len(chans) #number of channels

    #wrappers include a "chanlist" object (just an Unsigned Int array) for holding the chanlist information
    mylist = c.chanlist(nchans) #create a chanlist of length nchans

    #now pack the channel, gain and reference information into the chanlist object
    #N.B. the CR_PACK and other comedi macros are now python functions
    for index in range(nchans):
        mylist[index]=c.cr_pack(chans[index].no, chans[index].devrange, chans[index].aref)

    return mylist
Exemple #3
0
def make_chlist(chans):
    # list containing the chans, gains and referencing
    nchans = len(chans)  #number of channels

    #wrappers include a "chanlist" object (just an Unsigned Int array) for holding the chanlist information
    mylist = c.chanlist(nchans)  #create a chanlist of length nchans

    #now pack the channel, gain and reference information into the chanlist object
    #N.B. the CR_PACK and other comedi macros are now python functions
    for index in range(nchans):
        mylist[index] = c.cr_pack(chans[index].no, chans[index].devrange,
                                  chans[index].aref)

    return mylist
    def prepare_cmd(self,channels,gains,aref,freq):
        #First create the channel setup
        nchans = size(channels)
        channel_config = c.chanlist(nchans) #create a chanlist of length nchans

        print channel_config
        print channels
        
        for index in range(nchans):
            channel_config[index]=c.cr_pack(channels[index], gains[index], aref[index])
        
       #Then create the command
        cmd = c.comedi_cmd_struct()
        
        cmd.subdev = self.subdevice
        cmd.flags = 0
        cmd.start_src = c.TRIG_NOW
        cmd.start_arg = 0
        cmd.scan_begin_src = c.TRIG_TIMER
        cmd.scan_begin_arg = int(1e9/freq)
        cmd.convert_src = c.TRIG_TIMER
        cmd.convert_arg = 0
        cmd.scan_end_src = c.TRIG_COUNT
        cmd.scan_end_arg = nchans
        cmd.stop_src = c.TRIG_NONE
        cmd.stop_arg = 0
        cmd.chanlist = channel_config
        cmd.chanlist_len = nchans

        ret = self.test_cmd(cmd)

        if ret !=0:
            self.logger.error("Error preparing command")
            return -1

        return cmd
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..."
cmdtest_messages = [
    "success",
    "invalid source",
    "source conflict",
    "invalid argument",
    "argument conflict",
    "invalid chanlist"]


#wrappers include a "chanlist" object (just an Unsigned Int array) for holding the chanlist information
mylist = c.chanlist(nchans) #create a chanlist of length nchans

#now pack the channel, gain and reference information into the chanlist object
#N.B. the CR_PACK and other comedi macros are now python functions
for index in range(nchans):
    mylist[index]=c.cr_pack(chans[index], gains[index], aref[index])

size = c.comedi_get_buffer_size(dev, subdevice)
print "buffer size is ", size

map = mmap.mmap(fd, size, mmap.MAP_SHARED, mmap.PROT_READ)
print "map = ", map

def dump_cmd(cmd):
    print "---------------------------"
    print "command structure contains:"
    print "cmd.subdev : ", cmd.subdev
    print "cmd.flags : ", cmd.flags
    print "cmd.start :\t", cmd.start_src, "\t", cmd.start_arg
    print "cmd.scan_beg :\t", cmd.scan_begin_src, "\t", cmd.scan_begin_arg
    print "cmd.convert :\t", cmd.convert_src, "\t", cmd.convert_arg
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..."
Exemple #8
0
aref = [c.AREF_GROUND, c.AREF_GROUND, c.AREF_GROUND, c.AREF_GROUND]

cmdtest_messages = [
    "success", "invalid source", "source conflict", "invalid argument",
    "argument conflict", "invalid chanlist"
]

nchans = len(chans)  #number of channels

#wrappers include a "chanlist" object (just an Unsigned Int array) for holding the chanlist information
mylist = c.chanlist(nchans)  #create a chanlist of length nchans

#now pack the channel, gain and reference information into the chanlist object
#N.B. the CR_PACK and other comedi macros are now python functions
for index in range(nchans):
    mylist[index] = c.cr_pack(chans[index], gains[index], aref[index])

size = c.comedi_get_buffer_size(dev, subdevice)
print("buffer size is ", size)
map = mmap.mmap(fd, size, mmap.MAP_SHARED, mmap.PROT_READ)
print("map = ", map)


def dump_cmd(cmd):
    print("---------------------------")
    print("command structure contains:")
    print("cmd.subdev : ", cmd.subdev)
    print("cmd.flags : ", cmd.flags)
    print("cmd.start :\t", cmd.start_src, "\t", cmd.start_arg)
    print("cmd.scan_beg :\t", cmd.scan_begin_src, "\t", cmd.scan_begin_arg)
    print("cmd.convert :\t", cmd.convert_src, "\t", cmd.convert_arg)
print "Num Channels: %d" % nChannels

crange = c.comedi_get_range(dev, 0, 0, 0)
print "Range: %s" % str(crange)

params = c.chanlist(1)
params[0] = 0

# configure the encoder
instr = c.comedi_insn_struct()
instr.insn = c.INSN_CONFIG
instr.n = 1
instr.data = params
instr.subdev = 5
# instr.chanspec = c.cr_pack(0,0,c.AREF_OTHER)
instr.chanspec = c.cr_pack(0,0,0)

ret=c.comedi_do_insn(dev,instr);
print ret

# Encoder read instruction */
instr.insn=c.INSN_READ
instr.n=1
instr.data=params
instr.subdev=5
#instr.chanspec=c.cr_pack(0,0,AREF_OTHER);
instr.chanspec=c.cr_pack(0,0,0);

#read the damn data
for i in range(5):
    ret=c.comedi_do_insn(dev, instr);
    def pci_6033e_init(self, dev_name):
        self.dev = c.comedi_open(dev_name)
        if not(self.dev):
            self.warn_dialog("Unable to open device: " + dev_name)
            return(-1)

        ret = c.comedi_lock(self.dev, SUBDEVICE)
        if (ret < 0):
            self.warn_dialog("Could not lock comedi device")
            return(-1)

        # get a file-descriptor for use later
        self.fd = c.comedi_fileno(self.dev)
        if (self.fd <= 0): 
            self.warn_dialog("Error obtaining Comedi device file descriptor")
            c.comedi_close(self.dev)
            return(-1)

        # Channel range (0-5V)
        if (c.comedi_range_is_chan_specific(self.dev, SUBDEVICE) != 0):
            self.warn_dialog("Comedi range is channel specific!")
            c.comedi_close(self.dev)
            return(-1)

        self.comedi_range = c.comedi_get_range(self.dev, SUBDEVICE, 0, CHAN_RANGE)
        self.comedi_maxdata = c.comedi_get_maxdata(self.dev, SUBDEVICE, 0)

        board_name = c.comedi_get_board_name(self.dev)
        if (board_name != "pci-6033e"):
            print("Opened wrong device!")
        
        # Prepare channels, gains, refs
        self.comedi_num_chans = NUM_CHANNELS
        chans = range(self.comedi_num_chans)
        gains = [0]*self.comedi_num_chans
        aref = [c.AREF_GROUND]*self.comedi_num_chans

        chan_list = c.chanlist(self.comedi_num_chans)

        # Configure all the channels!
        for i in range(self.comedi_num_chans):
            chan_list[i] = c.cr_pack(chans[i], gains[i], aref[i])

        # The comedi command
        self.cmd = c.comedi_cmd_struct()

        # 1.0e9 because this number is in nanoseconds for some reason
        period = int(1.0e9/float(SCAN_FREQ))

        # Init cmd
        ret = c.comedi_get_cmd_generic_timed(self.dev, SUBDEVICE, self.cmd, self.comedi_num_chans, period)
        if (ret):
            self.warn_dialog("Could not initiate command")
            c.comedi_close(self.dev)
            return(-1)

        # Populate command 
        self.cmd.chanlist = chan_list
        self.cmd.chanlist_len = self.comedi_num_chans
        self.cmd.scan_end_arg = self.comedi_num_chans
        self.cmd.stop_src = c.TRIG_NONE
        self.cmd.stop_arg = 0

        print("real timing: %d ns" % self.cmd.convert_arg)
        print("Real scan freq: %d Hz" % (1.0/(float(self.cmd.convert_arg)*32.0*1.0e-9)))
        #print("period: %d ns" % period)
    
        print_cmd(self.cmd)

        # Test command out.
        ret = c.comedi_command_test(self.dev, self.cmd)
        if (ret < 0):
            self.warn_dialog("Comedi command test failed!")
            c.comedi_close(self.dev)
            return(-1)

        print("Command test passed")

        return(0)
Exemple #11
0
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
Exemple #12
0
    def scancommand(self, nscans=1000, chans=None, gains=None, aref=None):
        """Setup a scan
        nscans: total number of scans (int)
        chans: which channels (list)
        gains: which gain adjustments (list)
        aref: analog references (list)
        The lists must all have the same length!

        [sic] I think this will work but it's completely untested!
        --bryan

        I was not able to get this to work with my Vellemen P8061-2
        board -- foley
        """

        if not chans:
            raise RuntimeError("No Channels given in 'chans'")
        if not gains:
            raise RuntimeError("No gains given in 'gains'")
        if not aref:
            raise RuntimeError("No analog references given in 'aref'")
        if not len(chans) == len(gains) == len(aref):
            raise RuntimeError(
                "chans(%d), gains(%d), and aref(%d) not the same size"
                % (len(chans), len(gains), len(aref)))

        nchans = len(chans)  # number of channels

        # wrappers include a "chanlist" object (just an Unsigned Int
        # array) for holding the chanlist information
        mylist = c.chanlist(nchans)  # create a chanlist of length nchans

        # now pack the channel, gain and reference information into
        # the chanlist object
        # N.B. the CR_PACK and other comedi macros are now python functions
        for index in range(nchans):
            mylist[index] = c.cr_pack(
                chans[index], gains[index], aref[index])

        # construct a comedi command manually
        cmd = c.cmd_struct()
        cmd.subdev = 0
        cmd.flags = 0
        cmd.start_src = c.TRIG_NOW
        cmd.sart_arg = 0
        cmd.scan_begin_src = c.TRIG_TIMER
        cmd.scan_begin_arg = int(1.0E9 / 100000)
        cmd.convert_src = c.TRIG_TIMER
        cmd.convert_arg = 1
        cmd.scan_end_src = c.TRIG_COUNT
        cmd.scan_end_arg = nchans
        cmd.stop_src = c.TRIG_COUNT
        cmd.stop_arg = nscans
        cmd.chanlist = mylist
        cmd.chanlist_len = nchans

        dev = self.dev
        # test our comedi command a few times.
        ret = c.command_test(dev, cmd)
        print("first cmd test returns ", ret)
        ret = c.command_test(dev, cmd)
        print("second test returns ", ret)
        ret = c.command_test(dev, cmd)
        if not ret:
            raise RuntimeError("Error testing comedi command")

        ret = c.command(self.dev, cmd)

        chunk = 8
        # chunk: how many bytes to read at a time
        datalist = []
        data = os.read(self.cfd, chunk)
        while len(data) > 0:
            datalist.append(data)
            data = os.read(self.cfd, chunk)

        datastr = string.join(datalist, '')
        print("Data from command:")
        print(datastr)  # Here's your data, as a single string!
        # if you've got Numeric installed you can convert data
        # into a flat Numpy array with:
        # dataarray = Numeric.fromstring(data, Int16)
        return ret