Hi,

Sorry for the late reply.

On Wed, Sep 7, 2011 at 9:37 PM, Thomas Krüger
<[email protected]> wrote:
> Dear all,
>
> I am using a DAQ card from national instruments 6071E to measure
> analog values. It works fine but I have some problems changing the
> range:
>
> I found the a4l_find_range function and it works well, seeing the
> range_info changes according to my wishes. But I realise that the only
> function that uses the range information is the a4l_rawtod. It works
> for the range conversion but technically the range is never changed on
> the card itself (switching to another internal gain) and so the value
> I coming out at the end is wrong (mismatch between the setting on the
> io-card and a4l_rawtod).
>

Yes. The only interest of a4l_find_range() is to locate the most
suitable range descriptor according to the min and max value.

> Which function do I have to use or how to pass this information to the card?

You should pass the index of the selected range to thet third argument
of a4l_sync_read: the channel descriptor. Some helper macros are
available so as to make the setting of the channel descriptor (a
little bit) more easier.

Sorry, in the doxygen documentation of a4l_sync_read, there should be
a link to the anchor: "Channel macros".

Here is the quote from the Doxygen documentation.
Channel macros
Specific precompilation macros and constants useful for the channels
descriptors tab located in the command structure

#define         CHAN(a)   ((a) & 0xffff)
        Channel indication macro.
#define         RNG(a)   (((a) & 0xff) << 16)
        Range definition macro.
#define         AREF(a)   (((a) & 0xf) << 24)
        Reference definition macro.
#define         FLAGS(a)   ((a) & CR_FLAGS_MASK)
        Flags definition macro.
#define         PACK(a, b, c)   (CHAN(a) | RNG(b) | AREF(c))
        Channel + range + reference definition macro.
#define         PACK_FLAGS(a, b, c, d)   (CHAN(a) | RNG(b) | AREF(c) | FLAGS(d))
        Channel + range + reference + flags definition macro.
#define         AREF_GROUND   0x00
        Analog reference is analog ground.
#define         AREF_COMMON   0x01
        Analog reference is analog common.
#define         AREF_DIFF   0x02
        Analog reference is differential.
#define         AREF_OTHER   0x03
        Analog reference is undefined.

I think this API should be improved; there is an ugly flaw: with
a4l_find_range() you can retrieve the range descriptor but you have to
pass the index of the range descriptor to a4l_sync_read (..., ...,
PACK(0, range_index, ...), ...). This design problem forces the
developer to use a4l_get_rnginfo() so as to deduce the related index.

I will try to enrich the API so as to make the things easier.

>
> Thanks for your answers in advance.
>
> Cheers,
> Thomas
>
>
> My test program:
>
> // simple build cmd: g++ test-pcimio.c -I/usr/xenomai/include/
> -lxenomai -lnative -lanalogy -lpthread -lrtdm -L/usr/xenomai/lib
> // execute #./a.out
>
>
> #include <time.h>
> #include <stdio.h>
> #include <string.h>
> #include <stdint.h>
> #include <stdlib.h>
> #include <errno.h>
> #include <xenomai/analogy/analogy.h>
>
> /*
>  * Initialization function, activated once by PolyORB (at startup)
> */
> a4l_desc_t      arm_device;
> int             ni_6071e_analog_channels[16] =
> {0,1,2,4,5,6,16,17,18,19,21,23,32,33,34,35};
> int                             range_settings[16] = {-5, -10, -10, 5,
> 5, 5, 5, -5, -5, -5, -5,
> 10, 10, 10, -0.5, 0.5};
> a4l_chinfo_t   *ni_6071e_analog_channel_infos[16];
> a4l_rnginfo_t  *ni_6071e_analog_range_infos[16];
>
> int analog_init = 0;
>
> void init_arm()
> {
>   int          i = 0;
>   int          ret;
>   double       Range_Value;
>   double       Range_Max;
>   double       Range_Min;
>
>   ret = a4l_open (&arm_device, "analogy0");
>
>   if (ret != 0)
>   {
>      printf ("[EXOARM] Error while opening the arm device, return
> code=%d \n", ret);
>      return;
>   }
>     arm_device.sbdata = malloc(arm_device.sbsize);
>
>
>   ret = a4l_fill_desc (&arm_device);
>
>   if (ret != 0)
>   {
>      printf ("[EXOARM] Error while calling fill_desc(), return
> code=%d \n", ret);
>      return;
>   }
>
>
>   for (i=0; i<16; i ++)
>   {
>      ret = a4l_get_chinfo (&arm_device, 0,
> ni_6071e_analog_channels[i], &ni_6071e_analog_channel_infos[i]);
>      if (ret != 0)
>      {
>         printf ("[EXOARM] Error invoking a4l_get_chinfo on channel
> %d, return code=%d \n", ni_6071e_analog_channels[i], ret);
>      }
>      ret = a4l_get_rnginfo (&arm_device, 0,
> ni_6071e_analog_channels[i], 0, &ni_6071e_analog_range_infos[i]);
>      if (ret != 0)
>      {
>         printf ("[EXOARM] Error invoking a4l_get_chinfo on channel
> %d, return code=%d \n", ni_6071e_analog_channels[i], ret);
>      }
>   }
>
>   //setting up the range
>   for(i=0;i <16; i++)
>   {
>      Range_Value = range_settings[i];
>      if (Range_Value < 0)
>      {
>         Range_Min = Range_Value;
>      }
>      else
>      {
>         Range_Min = 0.0;
>      }
>      Range_Max = abs(Range_Value);
>
>      ret = a4l_find_range
>            (  &arm_device,                 //device
>               0,                           //subindex
>               ni_6071e_analog_channels[i], //idx channel
>               A4L_RNG_VOLT_UNIT,                           //unit
>               Range_Min,
>               Range_Max,
>               &ni_6071e_analog_range_infos[i]
>               );
>      if ((ret == -ENOENT) || (ret == -EINVAL))
>      {
>         printf("Error while configuring ranges 6071\n");
>      }
>
>   }//end for loop
>
>   analog_init = 1;
> }
>
> void arm_poll_acquisition_board()
> {
>   int i;
>   double tmp;
>   int ret;
>   uint8_t raw[128];
>
>   if (analog_init == 0) {
>      printf("[arm] Runtime Error - Periodic task activated before
> proper initialization.\n");
>      return;
>   }
>
>
>   for (i=0; i<16; i++)
>   {
>      ret = a4l_sync_read (&arm_device, 0,
> ni_6071e_analog_channels[i], 0, &raw, 128);
>      if (ret <= 0)
>      {
>          printf("[arm] Error while acquiring the data\n");
>      }
>
>      ret = a4l_rawtod (ni_6071e_analog_channel_infos[i],
> ni_6071e_analog_range_infos[i], &tmp, &raw, 1);
>
>      if (ret <= 0)
>      {
>          printf("[arm] Error while converting the data\n");
>      }
>      else
>      {
>        if(i != 0)
> {
> printf(";");
> }
>          printf("%lf", tmp);
>
>        }
>   }
> printf("]\n[");
>   return;
> }
>
>
>
> int main ()
> {
>   init_arm ();
>   while (1)
>   {
>      arm_poll_acquisition_board();
>      sleep (4);
>   }
> }
>
> _______________________________________________
> Xenomai-help mailing list
> [email protected]
> https://mail.gna.org/listinfo/xenomai-help
>

_______________________________________________
Xenomai-help mailing list
[email protected]
https://mail.gna.org/listinfo/xenomai-help

Reply via email to