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
