Multifunction DAQ

cancel
Showing results for 
Search instead for 
Did you mean: 

Configure Quadrature encoder X4 of PCI 6259 in Xenomai

I'm currently working on a project where I must set up PCI 6259 in real-time Linux Xenomai, probably with analogy library. The development environment is C++ in QT. I manage to implement analog output with analogy, however, I find little resources, examples or online help about how to configure or read quadrature X4 encoder through analogy API in Xenomai. Could anyone give me an example code?  
 
FYI: I can make it work in RTAI Linux, with comedi library. The code is extracted and attached below to show how I configured the counter, in case it might help. I just want to do the same thing in Xenomai. Thank you in advance,
 
#include <comedilib.h>
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <math.h>
#include <time.h>
#include <sched.h>
#include <sys/mman.h>
#include <string.h>
#include <time.h>
 
static comedi_t* pDevice = nullptr;
 
/**
 * @brief DAQ_InitDevice initialized the DAQ card PCI-6259
 * @return
 */
int32 DAQ_InitDevice()
{
    // If already created.
    if (pDevice != nullptr) return 0;
 
    // Create device
    char* pDeviceName = "/dev/comedi0";
    pDevice = comedi_open(pDeviceName);
 
    if (pDevice == nullptr) {
        qDebug("comedi_open");
        return -1;
    }
 
    // Set global out of range behavior    
    comedi_set_global_oor_behavior(COMEDI_OOR_NUMBER);    
 
    return 0;
}
 
/**
 * @brief DAQ_InitCounter_Sub
 * @param device: PCI-6259
 * @param subdev: represents counter subdevice
 * @return
 */
int32 DAQ_InitCounter_Sub(comedi_t *device, const int subdev)
{
    lsampl_t    initial_value;
    lsampl_t    data;
    lsampl_t    maxData_c;
    lsampl_t    counter_mode;
    comedi_range    *range_info_c;
 
    int a,b,z;
 
    int stt;
 
    // Reset counter
    stt = comedi_reset(device, subdev);
    if (stt<0) return stt;
 
 
    // Set counter mode
    counter_mode = (NI_GPCT_COUNTING_MODE_QUADRATURE_X4_BITS |
           NI_GPCT_COUNTING_DIRECTION_HW_UP_DOWN_BITS);
 
    range_info_c = comedi_get_range(device, subdev, 0, 0);
    maxData_c = comedi_get_maxdata(device, subdev, 0);
    initial_value = comedi_from_phys(0, range_info_c, maxData_c);
 
    /* set initial counter value by writing to channel 0 */
    stt = comedi_data_write(device, subdev, 0, 0, 0, initial_value);
    if (stt<0) return stt;
 
    /* set "load a" register to initial_value by writing to channel 1 */
    stt = comedi_data_write(device, subdev, 1, 0, 0, initial_value);
    if (stt<0) return stt;
 
    /* set "load b" register to initial_value by writing to channel 2 */
    stt = comedi_data_write(device, subdev, 2, 0, 0, initial_value);
    if (stt<0) return stt;
 
    stt = comedi_set_gate_source(device, subdev, 0, 0, NI_GPCT_DISABLED_GATE_SELECT);
    if (stt<0) return stt;
 
    stt = comedi_set_gate_source(device, subdev, 0, 1, NI_GPCT_DISABLED_GATE_SELECT);
    if (stt<0) return stt;
 
    if (subdev == 12) {
        // Left motor, counter 1
        // Set pin number
        a = NI_GPCT_PFI_OTHER_SELECT(3);
        b = NI_GPCT_PFI_OTHER_SELECT(11);
 
    } else if (subdev == 11) {
        // Right motor, counter 0
        // Set pin number
        a = NI_GPCT_PFI_OTHER_SELECT(8);
        b = NI_GPCT_PFI_OTHER_SELECT(10);
 
    } else {
        qDebug("Error: DAQ_InitCounter_Sub: No such counter %d !! \n", subdev);
        return -1;
    }
 
    z = NI_GPCT_DISABLED_GATE_SELECT;
 
    stt = comedi_set_other_source(device, subdev, 0, NI_GPCT_SOURCE_ENCODER_A, a);
    if (stt<0) return stt;
 
    stt = comedi_set_other_source(device, subdev, 0, NI_GPCT_SOURCE_ENCODER_B, b);
    if (stt<0) return stt;
 
    stt = comedi_set_other_source(device, subdev, 0, NI_GPCT_SOURCE_ENCODER_Z, z);
    if (stt<0) return stt;
 
    stt = comedi_set_counter_mode(device, subdev, 0, counter_mode);
    if (stt<0) return stt;
 
    stt = comedi_arm(device, subdev, NI_GPCT_ARM_IMMEDIATE);
    if (stt<0) return stt;
 
    return stt;
}
 
/**
 * @brief DAQ_InitCounter initializes two counters: the subdevice 11 & 12
 * @param pDevice: PCI-6259 device.
 * @return
 */
int32 DAQ_InitCounter(comedi_t* pDevice)
{
    const int subdev_counter0 = 11;
    const int subdev_counter1 = 12;
 
    int stt = 0;
 
    if(pDevice == nullptr) {
        qDebug("Error: No comedi DAQ device found!! \n");
        return -1;
    }
 
    // Init for counter 0: right motor
    stt = DAQ_InitCounter_Sub(pDevice, subdev_counter0);
    if (stt<0) return stt;
 
    // Init for counter 1: left motor
    stt = DAQ_InitCounter_Sub(pDevice, subdev_counter1);
    if (stt<0) return stt;
 
    return stt;
}
/**
 * @brief DAQ_ReadCounter reads counters' value. The device is defined by
 *        static pDevice; the counters are attached to subdevice 11 & 12.
 * @param data_left: raw data, output for left motor position
 * @param data_right: raw data, output for right motor position
 * @return status
 */
int32 DAQ_ReadCounter(lsampl_t &data_left, lsampl_t &data_right)
{
    const int subdev_counter0 = 11;
    const int subdev_counter1 = 12;
 
    int range = 0;
    int aref = 0;
    int channel = 0;    
    int stt = 0;
 
    if(pDevice == nullptr) {
        qDebug("Error: No comedi DAQ device found!! \n");
        return -1;
    }
 
    //
    // Read right motor position :
    //
    stt = comedi_data_read(pDevice, subdev_counter0, channel, range, aref, &data_right);
    if (stt<0) return stt;
 
 
    //
    // Read left motor position :
    //
    stt = comedi_data_read(Mechanism::mDevice, subdev_counter1, channel, range, aref, &data_left);
    if (stt<0) return stt;
 
    return stt;
}
0 Kudos
Message 1 of 1
(3,822 Views)