Forum
Please or Register to create posts and topics.

Transmitter in stream mode

I tried using the spectran in transmitter mode using the api dll similar to the example code.

The example code results in a short noise burst in the output, but not in the -500kHz to 500kHz frequency sweep.

Somehow i can not get it working despite getting no errors or anything with the code example or my code.

I understand it like this:
1) Initialize api etc. open device in transmitter mode
2) Set up center frequency, span and transgain for device
3) Set up Packet ONLY with start frequency, step frequency, size, stride, num, fp32, start&end time
4) Send Packet on channel 0

But then nothing happens (i.e. device transmitts at center frequency without iq-modulation) expect a very quick noise burst.

I initially thought it might be dut to my choice of parameters, but as mentioned above it also happens with the code example.

 

 

Working on it.

We will soon publish a new doc with more information on how to use the DLL in this case.

This is fixed/optimized from build 10183 on including some more sample codes.

I still have the same problem.

Please send the code so we can have a look at it.

Thank you! sadly i am not allowed to upload my source files to this forum so:

#include <thread>
#include <iostream>
#define WIN32_LEAN_AND_MEAN
#include <Windows.h>
#include <aaroniartsaapi.h>
#pragma comment(lib, "aaroniartsaapi.lib")

int main(int argc, char** argv)
{
HMODULE mod = ::LoadLibraryEx(L"C:\\Program Files\\Aaronia AG\\Aaronia RTSA-Suite PRO\\AaroniaRTSAAPI.dll", NULL, LOAD_LIBRARY_SEARCH_DEFAULT_DIRS | LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR);
if (mod == NULL)
{
DWORD err = GetLastError();
if (AllocConsole() != NULL)
{
std::cerr << "Unable to load dll : " << err << std::endl;
return 1;
}
}

//variables used for transmitter
const double zeroDBm = sqrt(1.0 / 20.0);
const double centerFrequency = 2e9; // 2GHz
const double spanFrequency = 50e6; // 50MHz
const double shiftFrequency = 4e6; // 4MHz
const double stepFrequency = 1e6; // 1MHz
const double transmitterGainDB = 0;
const size_t numberOfPackets = 100;
const int numberOfSamples = 16384;
std::chrono::steady_clock::time_point begin = std::chrono::steady_clock::now();
std::chrono::steady_clock::time_point end = std::chrono::steady_clock::now();
char controllString[5];

//declaration of api variables
AARTSAAPI_Handle h = {nullptr};
AARTSAAPI_Device d = {nullptr};
AARTSAAPI_Result res;
AARTSAAPI_DeviceInfo dInfo = { sizeof(AARTSAAPI_DeviceInfo) };
AARTSAAPI_Config root;
AARTSAAPI_Config elm;

//population of api variables
AARTSAAPI_Init(AARTSAAPI_MEMORY_LARGE);
if ((res = AARTSAAPI_Open(&h)) != AARTSAAPI_OK)
{
std::cerr << "Error open api: " << std::hex << res << std::endl;
AARTSAAPI_Shutdown();
return 1;
}
while ((res = AARTSAAPI_RescanDevices(&h, 2000)) == AARTSAAPI_RETRY)
{
std::cout << "Retry rescan? (y/n):" << std::flush;
std::cin.getline(controllString, 5);
if (controllString[0] != 'y')
{
AARTSAAPI_Close(&h);
AARTSAAPI_Shutdown();
return 1;
}
}
if (res != AARTSAAPI_OK)
{
std::cerr << "Error RescanDevices : " << std::hex << res << std::endl;
AARTSAAPI_Close(&h);
AARTSAAPI_Shutdown();
return 1;
}
if ((res = AARTSAAPI_EnumDevice(&h, L"spectranv6", 0, &dInfo)) != AARTSAAPI_OK)
{
std::cerr << "Error EnumDevices : " << std::hex << res << std::endl;
AARTSAAPI_Close(&h);
AARTSAAPI_Shutdown();
return 1;
}
if ((res = AARTSAAPI_OpenDevice(&h, &d, L"spectranv6/iqtransmitter", dInfo.serialNumber)) != AARTSAAPI_OK)
{
std::cerr << "Error OpenDevice : " << std::hex << res << std::endl;
AARTSAAPI_Close(&h);
AARTSAAPI_Shutdown();
return 1;
}

//configuration
if ((res = AARTSAAPI_ConfigRoot(&d, &root)) != AARTSAAPI_OK)
{
std::cerr << "Error ConfigRoot " << std::hex << res << std::endl;
AARTSAAPI_CloseDevice(&h, &d);
AARTSAAPI_Close(&h);
AARTSAAPI_Shutdown();
return 1;
}
if ((res = AARTSAAPI_ConfigFind(&d, &root, &elm, L"main/centerfreq")) != AARTSAAPI_OK)
{
std::cerr << "Error setting centerfreq " << std::hex << res << std::endl;
AARTSAAPI_CloseDevice(&h, &d);
AARTSAAPI_Close(&h);
AARTSAAPI_Shutdown();
return 1;
}
AARTSAAPI_ConfigSetFloat(&d, &elm, centerFrequency);

if ((res = AARTSAAPI_ConfigFind(&d, &root, &elm, L"main/spanfreq")) != AARTSAAPI_OK)
{
std::cerr << "Error setting spanfreq " << std::hex << res << std::endl;
AARTSAAPI_CloseDevice(&h, &d);
AARTSAAPI_Close(&h);
AARTSAAPI_Shutdown();
return 1;
}
AARTSAAPI_ConfigSetFloat(&d, &elm, spanFrequency);

if ((res = AARTSAAPI_ConfigFind(&d, &root, &elm, L"main/transgain")) != AARTSAAPI_OK)
{
std::cerr << "Error setting transgain " << std::hex << res << std::endl;
AARTSAAPI_CloseDevice(&h, &d);
AARTSAAPI_Close(&h);
AARTSAAPI_Shutdown();
return 1;
}
AARTSAAPI_ConfigSetFloat(&d, &elm, transmitterGainDB);

//setup of iq buffer
float* buffer = new float[2 * numberOfSamples];
const double pi = 355.f / 113;
const double delWt = 2 * pi * shiftFrequency / stepFrequency;
double wt = 0.0;
for (int idx = 0; idx < (2 * numberOfSamples); idx+=2)
{
buffer[idx] = (float)(zeroDBm * std::cos(wt));
buffer[idx + 1] = (float)(zeroDBm * std::sin(wt));
wt += delWt;

//buffer[idx] = 0;
//buffer[idx + 1] = 0;
}

//start iq transmitter
if ((res = AARTSAAPI_ConnectDevice(&d)) != AARTSAAPI_OK)
{
std::cerr << "Error ConnectDevice : " << std::hex << res << std::endl;
}
AARTSAAPI_StartDevice(&d);
std::cout << "Waiting for device (";
while (AARTSAAPI_GetDeviceState(&d) != AARTSAAPI_RUNNING)
{
std::cout << '#' << std::flush;
std::this_thread::sleep_for(std::chrono::milliseconds(100));
}
std::cout << ')' << std::endl;

//preset constant packet parameters
const double packetTime = numberOfSamples / stepFrequency;
AARTSAAPI_Packet P = { sizeof(AARTSAAPI_Packet) };
P.num = numberOfSamples;
P.startFrequency = centerFrequency - 0.5 * spanFrequency;
P.stepFrequency = stepFrequency;
P.size = 2;
P.stride = 2;

//wait for user intput
std::cout << "Packet time is: " << packetTime << std::endl;
std::cout << "Device is set up!\ntotal transmission time : " << numberOfPackets * numberOfSamples / stepFrequency <<
"s\npress ENTER to start transmission!" << std::endl;
std::cin.getline(controllString, 5);

//start stream
begin = std::chrono::steady_clock::now();
double masterStreamTime;
res = AARTSAAPI_GetMasterStreamTime(&d, masterStreamTime);
P.startTime = masterStreamTime + 0.1; // 100ms offset from NOW
P.endTime = P.startTime + packetTime;
P.fp32 = buffer;

//Send initial packet containing the correct flags for stream- & segment start
P.flags = AARTSAAPI_PACKET_SEGMENT_START | AARTSAAPI_PACKET_STREAM_START;
res = AARTSAAPI_SendPacket(&d, 0, &P);
if (res != AARTSAAPI_OK)
{
std::cerr << "Error sending first packet! : " << std::hex << res << std::endl;
}
P.flags = NULL;
P.startTime = P.endTime;
for (size_t packetIdx = 2; packetIdx < numberOfPackets; packetIdx++)
{
P.endTime = P.startTime + packetTime;
P.fp32 = buffer;

res = AARTSAAPI_GetMasterStreamTime(&d, masterStreamTime);
if (res != AARTSAAPI_OK)
{
std::cerr << "Error getting current master stream time : " << std::hex << res << std::endl;
}

//wait if the packet queue contains 3 or more packets
if (P.startTime > (masterStreamTime + 3 * packetTime))
{
//wait for time difference minus one packetTime
std::this_thread::sleep_for(std::chrono::milliseconds((int)(1000 * (P.startTime - masterStreamTime - packetTime)) ));
}

//send packet with stream- & segment end flag
res = AARTSAAPI_SendPacket(&d, 0, &P);
if (res != AARTSAAPI_OK)
{
std::cerr << "Error sending packet! : " << std::hex << res << std::endl;
}
P.startTime = P.endTime;
}

//send final packet
P.flags = AARTSAAPI_PACKET_SEGMENT_END | AARTSAAPI_PACKET_STREAM_END;
P.endTime = P.startTime + packetTime;
res = AARTSAAPI_GetMasterStreamTime(&d, masterStreamTime);
if (res != AARTSAAPI_OK)
{
std::cerr << "Error getting current master stream time : " << std::hex << res << std::endl;
}
res = AARTSAAPI_SendPacket(&d, 0, &P);
if (res != AARTSAAPI_OK)
{
std::cerr << "Error sending final packet! : " << std::hex << res << std::endl;
}

//wait for final packet to end
if (P.endTime > masterStreamTime)
{
std::this_thread::sleep_for(std::chrono::milliseconds((int)(1000 * (P.endTime - P.endTime))));
}
std::cout << "Transmission finished! " << std::endl;
end = std::chrono::steady_clock::now();
std::cout << "Elapsed time : " << std::chrono::duration_cast<std::chrono::milliseconds>(end - begin).count() << "ms" << std::endl;

//close api handles and iq buffer
delete[] buffer;
AARTSAAPI_DisconnectDevice(&d);
AARTSAAPI_CloseDevice(&h, &d);
AARTSAAPI_Close(&h);
AARTSAAPI_Shutdown();
return 0;
}

 

Your provided source runs on our test system without problem.

I have no idea what prevents it from working on your system.  The device has a watchdog timer, and this may be triggered if you run your code from within a debugger (e.g. single stepping).  An easy way to prevent this, is to have the RTSA Suite open, but no mission loaded.

 

fw_dev has reacted to this post.
fw_dev

Doing everything outside of VisualStudio, or while having the RTSA Suite open still has the same behaviour for me.

Again: The Transmitter WORKS for me. It is transmitting at a perfect 2Ghz as set in centerfreq in the configuration. The problem is when sending IQ-Data. The Resulting Signal i see on my spectrum analyzer looks like the same 2GHz signal with some noise peaks sprinkled in.
For example when setting I & Q to zero everywhere, shouldn't the signal dissapear?
Or when setting I = cos(wt) and Q = sin(wt): i expect the signal to shift in frequency with del_f = w / (2*pi).

Might be a problem with non activated streaming buffer?

https://v6-forum.aaronia.de/forum/topic/tx-running-in-stream-mode-is-allways-yellow-usb-underflow/

https://v6-forum.aaronia.de/forum/topic/file-reader-block/#postid-1265

Quote from js@hfac on 02/03/2022, 10:34

For example when setting I & Q to zero everywhere, shouldn't the signal dissapear?

The signal from your packets disappear, the "signal" at the center frequency remains as long as the transmitter is active (it is signifcantly lower than the signal from your packets).

Quote from js@hfac on 02/03/2022, 10:34

Or when setting I = cos(wt) and Q = sin(wt): i expect the signal to shift in frequency with del_f = w / (2*pi).

In your program, you're increasing wt in each loop iteration by a constant 8*pi, so sin and cos will return constant values of 1.0 and 0.0. Which obviously means that the signal remains constant. You need to include numberOfSamples in your calculations to see a shifting signal.