Thanks for the answer. Now it works like expected.
The solution to set the channels in a loop...
cannel_desc[i] = PACK(ni_6071e_analog_channels[i], ret, AREF_GROUND);
while the 'ret' argument is needed and used from the a4l_find_range function: .
Just for info in case somebody faces similar issues, here the code
from the updated initialisation funciton ...
a4l_desc_t arm_device;
unsigned ni_6071e_analog_channels[16] =
{0,1,2,4,5,6,16,17,18,19,21,23,32,33,34,35};
unsigned channel_desc[16];
double range_settings[16] = {5, 5, 2, 5, 5, 5, 5, 5, 5, 5, 5,
5, 5,
10, 10, 10, };
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");
}
else
{
//set the range on the board
channel_desc[i] = PACK(ni_6071e_analog_channels[i], ret,
AREF_GROUND);
}
printf("Ch: %d Rng set: %.1lf Calc val: %d \n",
ni_6071e_analog_channels[i], range_settings[i], ret);//,
ni_6071e_analog_range_infos[i].min,
ni_6071e_analog_range_infos[i].max);
}//end for loop
analog_init = 1;
}
2011/9/14 Alexis Berlemont <[email protected]>:
> 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