08-16-2012 05:38 PM
I have written a c++ program that generate a GPS signal in the PC ram and then transfer it to NI-5672 signal generator, but there is a confusing situation! I have written two programs to debug the problem, one of them generate signal in ram and then save it in a file in HDD on my PC, second read the file from HDD and stream it to RFSG, in this situation everything works perfectly and GPS receiver can extract data from signal! But when I try to write data from PC ram to RFSG memory without saving to HDD, it seams that signal overwriting during generation and GPS receiver can't extract data from signal!
The Code I used for write signal to HDD :
FILE * stream = fopen(filePath, "wb"); NIComplexI16 * data_IQ = (NIComplexI16 *) malloc(1000000*sizeof(NIComplexI16)); // bool generateSignal(NIComplexI16 * data_IQ) => generates 1000000 I/Q samples of gps signal! while(generateSignal(data_IQ)) { fwrite(data_IQ , sizeof(NIComplexI16), 1000000 , stream); } fclose(stream);
The Code I used for read from HDD and generating signal:
// other configs trimed ! niRFSG_AllocateArbWaveform(session, "waveformName", 4 * 1000000); FILE * stream = fopen(filePath, "rb"); NIComplexI16 * data_IQ = (NIComplexI16 *) malloc(1000000*sizeof(NIComplexI16)); // fill RFSG memory before starting signal generation : int size = fread(data_IQ, sizeof(NIComplexI16), 1000000, stream); status = niRFSG_WriteArbWaveformComplexI16(session, "waveformName", 1000000, data_IQ); size = fread(data_IQ, sizeof(NIComplexI16), 1000000, stream); status = niRFSG_WriteArbWaveformComplexI16(session, "waveformName", 1000000, data_IQ); size = fread(data_IQ, sizeof(NIComplexI16), 1000000, stream); status = niRFSG_WriteArbWaveformComplexI16(session, "waveformName", 1000000, data_IQ); size = fread(data_IQ, sizeof(NIComplexI16), 1000000, stream); status = niRFSG_WriteArbWaveformComplexI16(session, "waveformName", 1000000, data_IQ); if(status !=0 ) exit(1); // Start signal generation : status = niRFSG_Initiate(session); if(status !=0 ) exit(1); ViBoolean ended = false; // Read signal from file and write to RFSG memory to generate: while(size>0) { size = fread(data_IQ, sizeof(NIComplexI16), 1000000, stream); status = niRFSG_WriteArbWaveformComplexI16(session, "waveformName", 1000000, data_IQ); if(status !=0 ) break; status = niRFSG_CheckGenerationStatus(session, &ended); if(ended) exit(1); } // signal generation ended!
Above code works perfectly! but when I try to remove saving to HDD part, results are different!
The Code I used for generation signal on the fly and write to RFSG:
// other configs trimed ! niRFSG_AllocateArbWaveform(session, "waveformName", 4 * 1000000); NIComplexI16 * data_IQ = (NIComplexI16 *) malloc(1000000*sizeof(NIComplexI16)); // fill RFSG memory before starting signal generation : if(generateSignal(data_IQ)) status = niRFSG_WriteArbWaveformComplexI16(session, "waveformName", 1000000, data_IQ); else exit(1); if(generateSignal(data_IQ)) status = niRFSG_WriteArbWaveformComplexI16(session, "waveformName", 1000000, data_IQ); else exit(1); if(generateSignal(data_IQ)) status = niRFSG_WriteArbWaveformComplexI16(session, "waveformName", 1000000, data_IQ); else exit(1); if(generateSignal(data_IQ)) status = niRFSG_WriteArbWaveformComplexI16(session, "waveformName", 1000000, data_IQ); else exit(1); if(status !=0 ) exit(1); // Start signal generation : status = niRFSG_Initiate(session); if(status !=0 ) exit(1); ViBoolean ended = false; // Read signal from file and write to RFSG memory to generate: while(generateSignal(data_IQ)) { status = niRFSG_WriteArbWaveformComplexI16(session, "waveformName", 1000000, data_IQ); if(status !=0 ) break; status = niRFSG_CheckGenerationStatus(session, &ended); if(ended) exit(1); } // signal generation ended!
Please help me to figure out my problem!
I think that last code I wrote, overwrite signal before generation by RFSG!
08-17-2012 06:58 PM
Hello HTALA,
There are two other ways I would troubleshoot this (assuming that RFSG configuration steps like center frequency, output power, IQ rate, are not provided in the code you posted).
To do the benchmark test, I would use a for loop around the functions in question to run a specified number of times, and call GetTickCount() before and after the loop to get the difference in milliseconds. I suspect that reading from the disk is a much faster operation than the signal generation function.
Here is a bit of psuedo-code, you will still need to open the file and create the stream, etc. Remember to choose enough iterations such that the time it takes the loop to complete is much greater than 50 ms.
#define iterations 10 int i; int StartTime; int DiskReadTime; int OnTheFlyTime; startTime = GetTickCount(); for (i = 0; i< iterations; i++) { while(size>0) { size = fread(data_IQ, sizeof(NIComplexI16), 1000000, stream); //status = niRFSG_WriteArbWaveformComplexI16(session, "waveformName", 1000000, data_IQ); //if(status !=0 ) break; //status = niRFSG_CheckGenerationStatus(session, &ended); //if(ended) exit(1); } } DiskReadTime = GetTickCount() - startTime; startTime = GetTickCount(); for (i = 0; i< iterations; i++) { while(generateSignal(data_IQ)) { //status = niRFSG_WriteArbWaveformComplexI16(session, "waveformName", 1000000, data_IQ); //if(status !=0 ) break; //status = niRFSG_CheckGenerationStatus(session, &ended); //if(ended) exit(1); } } OnTheFlyTime = GetTickCount() - startTime;
I have some additional questions as well:
08-17-2012 08:04 PM
My IQ-Rate : 2,000,000
Using NI-5672 with external controller => A PC with following spec:
CPU: Intel 980X => 6 cores, 12 threads, 3.4 GHz, 12MB cache
RAM: 12GB ram
Motherboard: Intel DX58SO2
OS: Win 7 Ultimate x64
PCIe-PXIe link: NI PXIe-8388
------------------------------------------
Benchmark of signal generation on the fly is only 6 secs for 60 secs of signal, it means => 1/10 of time!
Also, if signal generation rate in PC became slower from IQ rate, RFSG returns error and stops generation, so there is no problem with signal generation speed.
For example when I increase IQ-Rate to 40,000,000 (40 MS/s), signal generation stops after few milliseconds and RFSG returns "The data being written to the streaming waveform cannot keep up with the output. Decrease the sample rate or write data to the streaming waveform more frequently.";
------------------------------------------
I use a Garmin Quest GPS receiver for testing of my signal, by on the fly signal generation it can't extract signal data, but can figure out which satellites are visible, in this case it shows that signal corrupted or some of it overwritten.
08-20-2012 04:26 PM
Hello Htata,
You are correct. I was trying to determine if there was an underflow happening, but it appears that you have already checked for that condition.
Have you been able to check the output waveform when streaming from file or generating on the fly? If you believe that you are overwriting memory on the device you can query the property NIRFSG_ATTR_STREAMING_SPACE_AVAILABLE_IN_WAVEFORM for the number of samples that are free on the arbitrary waveform generator and wait until enough samples become available before writing more data.
08-20-2012 04:48 PM
I already tried, after posting the problem to this board, I added this to my code, but there is no diffrence!
Is there any way to dump full data transfer to the signal generator !?
08-21-2012 04:05 PM
Hello HTALA,
I am a little confused, have you looked at the spectrum output of the RFSG or have you added the property for the get available samples in memory to the program?
As far as dumping the full transfer log, you can use the NI I/O Trace program to capture all of the interaction with the device and your program. It is located in the Start menu, All Programs, National Instruments
08-21-2012 09:13 PM
I have no vector signal analyzer, and I used NI IO Trace before, but IO trace can't dump data transferred to rfsg, it only show api calls and values of arguments of these calls, like address of memory data stored for transferring to RFSG.
Thanks for your responses. But it seams that there is a logical error in my code, and I'm really confused, because I use same code for generating signal! and transferring data to RFSG, in fact I use one program with a condition in writing signal part like below:
/// signal generation procedure trimmed ! //..... //..... while(running){ if(useRFSG){ ViInt64 spaceAvailableInStreamingWfm; status = niRFSG_GetAttributeViInt64(session, "", NIRFSG_ATTR_STREAMING_SPACE_AVAILABLE_IN_WAVEFORM, &spaceAvailableInStreamingWfm); if(status<0) return false; while(spaceAvailableInStreamingWfm<samples_count) { status = niRFSG_GetAttributeViInt64(session, "", NIRFSG_ATTR_STREAMING_SPACE_AVAILABLE_IN_WAVEFORM, &spaceAvailableInStreamingWfm); if(status<0) return false; } status = niRFSG_WriteArbWaveformComplexI16(session, waveformName, samples_count, SignalBuffer); if(status<0) return false; ViBoolean ended = false; status = niRFSG_CheckGenerationStatus(session, &ended); if(ended) return true; // ended! }else{ fwrite(SignalBuffer , sizeof(NIComplexI16), samples_count , Data ); } }
I created a buffer of 100 milliseconds of signal to optimize signal transfer blocks, and fill this buffer and transfer it to RFSG, or write it in a File using fwrite(...).
So why "useRFSG" is "true" and my program generate signal on the fly, there is problem, but when I save signal to HDD and read saved signal and transfer it to RFSG with a second program I wrote with completely same strategy for transferring signal to RFSG, there is no problem!?
08-23-2012 12:18 PM
Hello HTALA,
It looks like you are checking for errors but can you also check for warnings to see if status > 0 at any point in code?
Can you also post your C files so that I can troubleshoot your code as well? It is hard to hypothesize what might be wrong without seeing the full code.
08-24-2012 05:03 PM
I faced a problem that may cause this situation,
I set my IQ Rate to a value like 1500000.0000 (15e6) by code like below:
status = niRFSG_SetAttributeViReal64(session, "", NIRFSG_ATTR_IQ_RATE, iq_rate); if(status!=0) return false;
But when re-read IQ-Rate with following code, it returns "1500000.00000014" ?!!!
status = niRFSG_GetAttributeViReal64(session, "", NIRFSG_ATTR_IQ_RATE, &iq_rate); if(status!=0) return false; printf("%f",iq_rate);
08-27-2012 06:15 PM
Can you ensure that you are really setting 15e6 and not 15e5? On the return value "1500000.00000014", it is actually closer to 15e5.
Did you check for warning in your code? Does the function work if you start from an example that was built for CVI?