Driver Development Kit (DDK)

cancel
Showing results for 
Search instead for 
Did you mean: 

How to do register-level programming for NI6025E when I want to acquire single scan incuding multiple input channels?

How to do register-level programming for NI6025E when I want to acquire single scan incuding multiple input channels?
0 Kudos
Message 1 of 12
(10,991 Views)
Have you taken a look at the existing E Series Measurement Hardware Driver Development Kit (MHDDK)?  Check out the NI MHDDK page, click the download link.  Download the E Series Examples and Register Objects.  You will probably want a combination of aiex1.cpp and aiex2.cpp.
-Alan A.
0 Kudos
Message 2 of 12
(10,983 Views)
Thanks, Alan, I think I indeed need to combine aiex1.cpp and aiex2.cpp. I made a change to Configure_Board of aiex1.cpp  as follows:
 
//Call this function to configure board options.
void Configure_Board(tSTC *theSTC,tESeries *board)
{
 //Clear configuration memory
 theSTC->Write_Strobe_0.writeRegister(0x0001);
 //Clear ADC FIFO
 theSTC->Write_Strobe_1.writeRegister(0x0001);
 //Writing to Config_Memory_High_Register for channel 1 settings
 board->ConfigFifoHigh.setChannel(0);
 board->ConfigFifoHigh.setBank(0);
 board->ConfigFifoHigh.setChannelType(board->ConfigFifoHigh.kChannelTypeRSE);
 board->ConfigFifoHigh.flush();
 //Writing to Config_Memory_Low_Register for following channel 1 settings
 board->ConfigFifoLow.setLastChannel(0);
 board->ConfigFifoLow.setGeneralTrigger(0);
 board->ConfigFifoLow.setGain(board->ConfigFifoLow.kGain001_0);
 board->ConfigFifoLow.setPolarity(board->ConfigFifoLow.kPolarityBipolar);
 board->ConfigFifoLow.setDither(0);
 board->ConfigFifoLow.flush();
 //Writing to Config_Memory_High_Register for following channel 0 settings
 board->ConfigFifoHigh.setChannel(1);
 board->ConfigFifoHigh.setBank(0);
 board->ConfigFifoHigh.setChannelType(board->ConfigFifoHigh.kChannelTypeRSE);//RSE mode
 board->ConfigFifoHigh.flush();
 //Writing to Config_Memory_Low_Register for following channel 0 settings
 board->ConfigFifoLow.setLastChannel(1);
 board->ConfigFifoLow.setGeneralTrigger(0);
 board->ConfigFifoLow.setGain(board->ConfigFifoLow.kGain001_0);
 board->ConfigFifoLow.setPolarity(board->ConfigFifoLow.kPolarityBipolar);//BIPOLAR
 board->ConfigFifoLow.setDither(0);
 board->ConfigFifoLow.flush(); 
 return;
}
 and a change to test(iBus *bus):
 
 
do
 {
  uStatus = theSTC->AI_Status_1.readRegister();
  if (!((uStatus & 0x1000) == 0x1000))
  { 
    uValue[i] = board->AIFifoData.readRegister();
   i++;
  }
 } while(i<1);
 printf("Value %d is %6.2f\n",0,FindADDouble(uValue[0]));
 printf("Value %d is %6.2f\n",1,FindADDouble(uValue[1]));
 
but it doesn't work, why?
 
How shoud I do?
 
 
 
0 Kudos
Message 3 of 12
(10,980 Views)
Could you be a little more specific when you say it doesn't work.  What happens?  Does the code compile?  Do you get a runtime error?  Does everything compile and run, but you get bad data?  What voltages are you expecting and what voltages are you reading? 
-Alan A.
0 Kudos
Message 4 of 12
(10,974 Views)
I just noticed that the condition of your while loop is  (i < 1).  You increment i every time you read from the FIFO, so you will only do one FIFO read.
-Alan A.
0 Kudos
Message 5 of 12
(10,971 Views)
Alan, I 've got it done as follows:

//Call test function for the required functionality
void test(iBus *bus)
{
 int i=0;
 tAddressSpace  Bar1;
 tESeries *board;
 tSTC *theSTC;
 unsigned  uStatus; //Flag to indicate FIFO not empty
 unsigned  uValue[3];  //Binary voltage acquired
 Bar1 = bus->createAddressSpace(kPCI_BAR1);
 board = new tESeries(Bar1);
 theSTC = new tSTC(Bar1);
 //Configure the board with the channel settings
 Configure_Board(theSTC,board);
 //Now Program the DAQ-STC
 //Configure the timebase options for DAQ-STC  
 MSC_Clock_Configure(theSTC);
 //Clear ADC FIFO
 Clear_FIFO(theSTC);
 //Stop any activities in progress
 AI_Reset_All(theSTC);
 //Set DAQ STC for E-series board
 AI_Board_Personalize(theSTC);
 //Access the first value in the configuration FIFO
 AI_Initialize_Configuration_Memory_Output(theSTC);
 //Setup for any external multiplexer
 AI_Board_Environmentalize(theSTC);
 //Set triggering options
 AI_Trigger_Signals(theSTC);
 //Select the scan start event
 AI_Scan_Start(theSTC);
 //Select the end of scan event
 AI_End_of_Scan(theSTC);
    Convert_Signal(theSTC);
 //Clear ADC FIFO
 Clear_FIFO(theSTC);
    AI_Arming(theSTC);
 //Start the acquistion
 AI_Start_The_Acquisition(theSTC);
 //Poll the FIFO not empty flag to determine if
 //data is available.  If FIFO not empty then
 //read the data.
 //The Data has to be scaled to get the
 //value in voltage. For Example PCI-6024 if used in
 //Bipolar mode has range of +-5 Volts, the corresponding
 //ADC levels are form -2048 to 2047. Thus a value of 2047
 //represents +5 volts.

do
 {
  uStatus = theSTC->AI_Status_1.readRegister();
  if (!((uStatus & 0x1000) == 0x1000))
  { 
    uValue[i] = board->AIFifoData.readRegister();
   i++;
  }
 } while(i<3);
 printf("Value %d is %6.2f\n",0,FindADDouble(uValue[0]));
 printf("Value %d is %6.2f\n",1,FindADDouble(uValue[1]));
 printf("Value %d is %6.2f\n",2,FindADDouble(uValue[2]));
 delete theSTC;
 delete board;
 bus->destroyAddressSpace(Bar1);
}
 
 
although it is not perfect.
0 Kudos
Message 6 of 12
(10,964 Views)
So is it working or do you still have problems?  If so, what specifically is the problem/error?
-Alan A.
0 Kudos
Message 7 of 12
(10,957 Views)

Hi, Alan, My problem is:   This following acquistion loop takes too much time.

do
 {
  uStatus = theSTC_0->AI_Status_1.readRegister();
  if (!((uStatus & 0x1000) == 0x1000))
  { 
    uValue[i] = board_0->AIFifoData.readRegister();
  //  if(NBit==12) uValue[i]=uValue[i] & 0x0FFF;
   i++;
  }
 } while(i<3);

No matter how to set the values of SI and SI2 , it takes at least almost 80 us for sampling only 3 channels.

but PCI-6025E is rated for a speed of 200KHz. Can I aspect for a time of 30 us or so  for the last loop? How to set SI and SI2 ?

 

0 Kudos
Message 8 of 12
(10,949 Views)
Sorry , should be "expect for " 
0 Kudos
Message 9 of 12
(10,949 Views)

Ok, hopefully I can clarify some things here.  SI, or scan interval, allows you to set the sample rate.  SI2 allows you to set the convert clock rate.  The convert clock is what controlls the switching of the ADC between different analog input channels.  The max rate of the convert clock for your board is 200kHz.  The max sample rate (or scan interval) is dependent on the number of channels in your scan list.  If you have three channels, then the max sample rate for your device is 200kHz/3, or about 67kHz.  Another important thing to mention is that the number you write to the SI and SI2 registers is the timebase divisor.  This number is calculated with this formula:  timebase divisor = timebase/rate.  The timebase for all E Series is 20MHz.  So if you want to set the convert clock rate at 200k, then you need to set the timebase divisor to 100.

Also, because you are really loading a counter here, you need to subtract one from the actual number you want to set.

So, I believe you want to write 299 to SI and 99 to SI2.

Now, having said all that.  These settings will ensure that three samples will be acquired at 200Hz.  This does not mean that your loop will execute at 3*(1/200k).  There are other factors to mention here.  First, anything you do in the loop will take time.  You are doing two register reads in every iteration.  Really, at that point, everythign is system dependent.  It will depend on how long will it take your system to perform a register read.  So I really can't tell you what to expect as far as how fast your loop will execute.

Hope this helps.

-Alan A.

0 Kudos
Message 10 of 12
(10,935 Views)