PXI

cancel
Showing results for 
Search instead for 
Did you mean: 

Zero span measurement with RFSA in C

Hi all,
 
I am writing a zero-span measurement program for the NI-5661 RFSA in C for testing purpose. I found following relevent C-codes in the C-example called "RFSA Getting Started IQ.c" provided by NI.
 
...
   checkWarn(niRFSA_ConfigureReferenceLevel (session, "", 0));
...
   checkWarn( niRFSA_ReadIQSingleRecordComplexF64 (session, "", 10.0, dataPtr, numberOfSamples, &wfmInfo));
...
   /* Do something useful with the data */
   /* We will present average power: 10log(((I^2 + Q ^2) / 2R) * 1000), where
    * R = 50 Ohms */
...
 
accumulator += 10.0 * log10((magnitudeSquared / (2.0 * 50.0)) * 1000.0);
....
 
My question is
1. How is the power calculation formular 10log(((I^2 + Q ^2) / 2R) * 1000) related to the reference level setting, in this case, 0 dBm?
2. Does the constant 1000 in the formular above mean a defaualt RF attenuation of 30 dB when setting ReferenceLevel = 0 dBm?
3. Does not the two IF attenuators play a role in the power calculation? If yes, how?
4. Why is there no attributes addressing the IF attenuation in C?
5. What would the power calculation formular look like if I set ReferenceLevel = -10dBm?
 
Cheers, Vedis
 
0 Kudos
Message 1 of 4
(4,238 Views)
Hi Vedis,

Can you post all the programm and say me where you find it because I search and I didn't found that NI send this programm.
I wanted also say you that your question is not on the right forum, it's more a signal processing question and in the example that you find is written
/* Do something useful with the data */
so the programm do something with the data...

Best Regards.

Matthieu
0 Kudos
Message 2 of 4
(4,213 Views)

Hi Matthieu

Let me formulate my question in a simple way. 

How to calculate the RF power from the IQ samples, taking into account of the actual 5661 settings, like e.g. reference level and/or attenuation!

The C code in my original post was extracted from "RFSA Getting Started IQ.c" provided by NI. See below for the complete program list. Maybe I didn't understand the program correctly. I just want to prevent anything nosense in our application, since something is only useful to us if it is correct.   

Please advise which forum is the right one concerning applications of NI PXI-5661 RFSA. I'd like to post my questions there again.

Best regards

Vedis

 

#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include "niRFSA.h"


/* Maximum length of an niRFSA function name */
#define MAX_FUNCTION_NAME_SIZE      55
/* Maximum size of an error message returned from niRFSA_GetError */
#define MAX_ERROR_DESCRIPTION       (IVI_MAX_MESSAGE_BUF_SIZE * 2 + MAX_FUNCTION_NAME_SIZE + 75)


int main (int argc, char *argv[])
{
   ViSession session = VI_NULL;
   NIComplexNumber* dataPtr = NULL;
   niRFSA_wfmInfo wfmInfo;
   ViInt32 numberOfSamples = 1000;
   ViInt32 i;
   ViReal64 magnitudeSquared;
   ViReal64 accumulator = 0.0;
   ViStatus error = VI_SUCCESS;
   ViChar errorMessage[MAX_ERROR_DESCRIPTION];
   ViStatus lastErrorCode;

   /* Initialize a session */
   checkWarn(
      niRFSA_init ("PXI1Slot2", VI_TRUE, VI_FALSE, &session));
  
   /* Configure NI-RFSA for a simple IQ acquisition */
   checkWarn(
      niRFSA_ConfigureRefClock (session, "OnboardClock", 10e6));
   checkWarn(
      niRFSA_ConfigureReferenceLevel (session, "", 0));
   checkWarn(
      niRFSA_ConfigureAcquisitionType (session, NIRFSA_VAL_IQ));
   checkWarn(
      niRFSA_ConfigureIQCarrierFrequency (session, "", 100e6));
   checkWarn(
      niRFSA_ConfigureNumberOfSamples (session, "", VI_TRUE, numberOfSamples));
   checkWarn(
      niRFSA_ConfigureIQRate (session, "", 1e6));

   /* Read the complex interleaved IQ data */
   dataPtr = malloc (sizeof (ViReal64) * 2 * numberOfSamples);
     
   checkWarn(
      niRFSA_ReadIQSingleRecordComplexF64 (
         session,
         "",
         10.0,  /* seconds */
         dataPtr,
         numberOfSamples,
         &wfmInfo));

   /* Do something useful with the data */
   /* We will present average power: 10log(((I^2 + Q ^2) / 2R) * 1000), where
    * R = 50 Ohms */

   if (numberOfSamples > 0)
   {
      for (i = 0; i < numberOfSamples; ++i)
      {
         magnitudeSquared = dataPtr[i].real * dataPtr[i].real + dataPtr[i].imaginary * dataPtr[i].imaginary;

         /* we need to handle this because log(0) return a range error. */
         if (magnitudeSquared == 0.0)
         {
            magnitudeSquared = 0.00000001;
         }

         accumulator += 10.0 * log10((magnitudeSquared / (2.0 * 50.0)) * 1000.0);
      }

      printf("Average power = %0.1lf dBm\n", accumulator / numberOfSamples);
   }

Error:
   if (error < VI_SUCCESS)
   {
      niRFSA_GetError (session, &lastErrorCode, MAX_ERROR_DESCRIPTION, errorMessage);
      printf("ERROR: %s\n", errorMessage);
   }
   else if (error > VI_SUCCESS)
   {
      niRFSA_GetError (session, &lastErrorCode, MAX_ERROR_DESCRIPTION, errorMessage);
      printf("WARNING: %s\n", errorMessage);
   }

   if (session)
      niRFSA_close(session);
   if (dataPtr)
      free (dataPtr);

   return 0;
}

 

0 Kudos
Message 3 of 4
(4,201 Views)
Hi Vedis,
For your questions, the 1000 values on the calculs is because we are converting from dB to dBm. This means our reference is 1 mW and not 1 W. In dB units is only adding (or subtracting) 30 dB.

You have a lot of questions about attenuation, you can refer to the following help file in the section "RF Attenuation and Signals Levels":

Start » All Programs » National Instruments » NI-RFSA»Documentation » NI Signal Vector Analyzer Help.


For other question about RF this would better to post it in the RF Forum: http://forums.ni.com/ni/board?board.id=290


Have a great Day...


Matthieu




0 Kudos
Message 4 of 4
(4,180 Views)