Receive AM signal with basicRX code

hi, i am new to RF i am trying to receive AM signal from signal generator by using limesdrmini with the basicRX code,which i am attached below…but i am not getting it. should i add any extra logic here.?and should i change the buffer format?

#include “lime/LimeSuite.h”
#include
#include
#ifdef USE_GNU_PLOT
#include “gnuPlotPipe.h”
#endif

using namespace std;

//Device structure, should be initialize to NULL
lms_device_t* device = NULL;

int error()
{
if (device != NULL)
LMS_Close(device);
exit(-1);
}

int main(int argc, char** argv)
{
//Find devices
int n;
lms_info_str_t list[8]; //should be large enough to hold all detected devices
if ((n = LMS_GetDeviceList(list)) < 0) //NULL can be passed to only get number of devices
error();

cout << "Devices found: " << n << endl; //print number of devices
if (n < 1)
    return -1;

//open the first device
if (LMS_Open(&device, list[0], NULL))
    error();

//Initialize device with default configuration
//Do not use if you want to keep existing configuration
//Use LMS_LoadConfig(device, "/path/to/file.ini") to load config from INI
if (LMS_Init(device) != 0)
    error();

//Enable RX channel
//Channels are numbered starting at 0
if (LMS_EnableChannel(device, LMS_CH_RX, 0, true) != 0)
    error();

//Set center frequency to 800 MHz
if (LMS_SetLOFrequency(device, LMS_CH_RX, 0, 800e6) != 0)
    error();

//Set sample rate to 8 MHz, ask to use 2x oversampling in RF
//This set sampling rate for all channels
if (LMS_SetSampleRate(device, 8e6, 2) != 0)
    error();

//Enable test signal generation
//To receive data from RF, remove this line or change signal to LMS_TESTSIG_NONE
if (LMS_SetTestSignal(device, LMS_CH_RX, 0, LMS_TESTSIG_NONE, 0, 0) != 0)
    error();

//Streaming Setup

//Initialize stream
lms_stream_t streamId; //stream structure
streamId.channel = 0; //channel number
streamId.fifoSize = 1024 * 1024; //fifo size in samples
streamId.throughputVsLatency = 1.0; //optimize for max throughput
streamId.isTx = false; //RX channel
streamId.dataFmt = lms_stream_t::LMS_FMT_I12; //12-bit integers
if (LMS_SetupStream(device, &streamId) != 0)
    error();

//Initialize data buffers
const int sampleCnt = 5000; //complex samples per buffer
int16_t buffer[sampleCnt * 2]; //buffer to hold complex values (2*samples))

//Start streaming
LMS_StartStream(&streamId);

//Streaming

#ifdef USE_GNU_PLOT
GNUPlotPipe gp;
gp.write(“set size square\n set xrange[-2050:2050]\n set yrange[-2050:2050]\n”);
#endif
auto t1 = chrono::high_resolution_clock::now();
while (chrono::high_resolution_clock::now() - t1 < chrono::seconds(5)) //run for 5 seconds
{
//Receive samples
int samplesRead = LMS_RecvStream(&streamId, buffer, sampleCnt, NULL, 1000);
//I and Q samples are interleaved in buffer: IQIQIQ…
printf(“Received %d samples\n”, samplesRead);
/*
INSERT CODE FOR PROCESSING RECEIVED SAMPLES
*/
#ifdef USE_GNU_PLOT
//Plot samples
gp.write(“plot ‘-’ with points\n”);
for (int j = 0; j < samplesRead; ++j)
gp.writef("%i %i\n", buffer[2 * j], buffer[2 * j + 1]);
gp.write(“e\n”);
gp.flush();
#endif
}
//Stop streaming
LMS_StopStream(&streamId); //stream is stopped but can be started again with LMS_StartStream()
LMS_DestroyStream(device, &streamId); //stream is deallocated and can no longer be used

//Close device
LMS_Close(device);

return 0;

}

It works if you remove the line -

if (LMS_SetTestSignal(device, LMS_CH_RX, 0, LMS_TESTSIG_NONE, 0, 0) != 0)
error();

Thanks for the reply @RightHalfPlane
It receives. For tx i am using basicTx code like my RX. I am transmitting the samples from file i am getting my am signal in 200mhz(the TX center frequency which i am given). But in 400mhz, 600 mhz also that same signal is coming.

But it should not happen like that right? And after destroying the stream also i am getting that center spike. What it means? Could you help me please?

I assumed that the harmonics were down many DB - if not then they matter. I complained about this, but amazingly they think that transmitting after the steam has been destroyed is what it should do. To stop it from transmitting, you need to set the transmit gain to zero or call LMS_Close.

thanks for the response @RightHalfPlane

i am transmitting the AM signal (AM samples i have in text file).the center frequency which i given is 200mhz.but unnecessarily in 400mhz,600mhz etc also i am getting some samples(it look like AM).

i am sharing here my code

/**
@file basicTX.cpp
@author Lime Microsystems (www.limemicro.com)
@brief minimal TX example
*/
#include
#include
#include <math.h>
#include “lime/LimeSuite.h”

using namespace std;

//Device structure, should be initialize to NULL
lms_device_t* device = NULL;

int error()
{
if (device != NULL)
LMS_Close(device);
exit(-1);
}

int main(int argc, char** argv)
{
const double frequency = 200e6; //center frequency to 200 MHz
const double sample_rate = 5e6; //sample rate to 5 MHz
const double tone_freq = 1e6; //tone frequency
const double f_ratio = tone_freq/sample_rate;
//Find devices
int n;
lms_info_str_t list[8]; //should be large enough to hold all detected devices
if ((n = LMS_GetDeviceList(list)) < 0) //NULL can be passed to only get number of devices
error();

cout << "Devices found: " << n << endl; //print number of devices
if (n < 1)
    return -1;

//open the first device
if (LMS_Open(&device, list[0], NULL))
    error();

//Initialize device with default configuration
//Do not use if you want to keep existing configuration
//Use LMS_LoadConfig(device, "/path/to/file.ini") to load config from INI
if (LMS_Init(device)!=0)
    error();

//Enable TX channel,Channels are numbered starting at 0
if (LMS_EnableChannel(device, LMS_CH_TX, 0, true)!=0)
    error();

//Set sample rate
if (LMS_SetSampleRate(device, sample_rate, 0)!=0)
    error();
cout << "Sample rate: " << sample_rate/1e6 << " MHz" << endl;

//Set center frequency
if (LMS_SetLOFrequency(device,LMS_CH_TX, 0, frequency)!=0)
    error();
cout << "Center frequency: " << frequency/1e6 << " MHz" << endl;

//select TX1_1 antenna
if (LMS_SetAntenna(device, LMS_CH_TX, 0, LMS_PATH_TX1)!=0)
    error();

//set TX gain

// if (LMS_SetNormalizedGain(device, LMS_CH_TX, 0, 0.7) != 0)
// error();

if(LMS_SetGaindB(device, LMS_CH_TX, 0,60))
    error();

//calibrate Tx, continue on failure
LMS_Calibrate(device, LMS_CH_TX, 0, sample_rate, 0);

//Streaming Setup

lms_stream_t tx_stream;                 //stream structure
tx_stream.channel = 0;                  //channel number
tx_stream.fifoSize = 1024*1024;          //fifo size in samples
tx_stream.throughputVsLatency = 0.5;    //0 min latency, 1 max throughput
tx_stream.dataFmt = lms_stream_t::LMS_FMT_I12; //floating point samples
tx_stream.isTx = true;                  //TX channel
LMS_SetupStream(device, &tx_stream);

// //Initialize data buffers
// /const int buffer_size = 10248;
// float tx_buffer[2buffer_size]; //buffer to hold complex values (2samples))
// for (int i = 0; i <buffer_size; i++) { //generate TX tone
// const double pi = acos(-1);
// double w = 2piif_ratio;
// tx_buffer[2
i] = cos(w);
// tx_buffer[2i+1] = sin(w);
// }
/

const int buffer_size = 10000;
int32_t tx_buffer[2*buffer_size];     //buffer to hold complex values (2*samples))

FILE *filename = fopen("/home/ubuntu/build-lime_testing-Desktop-Debug/rx_data.txt","r");
for (int i = 0; i < buffer_size; i++)
{
    fscanf(filename,"%d\n%d\n",(&tx_buffer[2*i]),(&tx_buffer[2*i+1]));
}

fclose(filename);

cout << "Tx tone frequency: " << tone_freq/1e6 << " MHz" << endl;


const int send_cnt = int(buffer_size*f_ratio) / f_ratio;
cout << "sample count per send call: " << send_cnt << std::endl;

LMS_StartStream(&tx_stream);         //Start streaming
//Streaming
auto t1 = chrono::high_resolution_clock::now();
auto t2 = t1;
while (chrono::high_resolution_clock::now() - t1 < chrono::seconds(100)) //run for 10 seconds
{
    //Transmit samples
    int ret = LMS_SendStream(&tx_stream, tx_buffer, send_cnt, nullptr, 1000);
    if (ret != send_cnt)
        cout << "error: samples sent: " << ret << "/" << send_cnt << endl;
    //Print data rate (once per second)
    if (chrono::high_resolution_clock::now() - t2 > chrono::seconds(1))
    {
        t2 = chrono::high_resolution_clock::now();
        lms_stream_status_t status;
        LMS_GetStreamStatus(&tx_stream, &status);  //Get stream status
        cout << "TX data rate: " << status.linkRate / 1e6 << " MB/s\n"; //link data rate
    }
}
//Stop streaming
LMS_StopStream(&tx_stream);
LMS_DestroyStream(device, &tx_stream);

//Disable TX channel
if (LMS_EnableChannel(device, LMS_CH_TX, 0, false)!=0)
    error();

//Close device
if (LMS_Close(device)==0)
    cout << "Closed" << endl;
return 0;

}

what changes should i do.please help me @RightHalfPlane
what is that tone frequency?
should i add any extra logic to transmit the AM signal?.

I do not know what their tone frequency is support to be - I could never detect it. I converted their program to use SoapySDR and set the tone to 2000 hz. When receiving the signal as narrow band FM a tone of 2000 hz is heard.

What I had to do to transmit AM using SoapySDR (the same should work using limesuite)

Down sample the audio from 48,000 hz to 10,000 hz (msresamp_rrrf_execute).

Modulate the audio with 10,000 hz, (modulate or ampmodem_modulate_block )

Upsample the 10,000 hz to 2,000,000 hz (msresamp_crcf_execute)

Transmit the up sampled data.

The msresamp_rrrf_execute, ampmodem_modulate_block and msresamp_crcf_execute routines are from liquidSDR. Modulate is a routine that I wrote because I could not get ampmodem_modulate_block to work with AM (On USB and LSB it works OK).

The “Transmit.cpp” routines in SdrGlut lets you select the microphone, frequency, and mode (AM, NBFM, USB or LSB) to transmit.

The calls to the routines are in SendData. The parameter are set in TransmitThread.
With a week of work - that is the simplest method that I could come up with.

thank you for the response @RightHalfPlane
i am using limesdrmini.
the transmitting samples is coming correctly in sdrangle. but i need to see the output in signal analyzer.so my doubt is already i am having AM modulated samples in my FILE.just i am going to read the file and transmitting the samples.so is is necessary to do down sampling,up sampling and modulation ?.

With AM down sampling, is not necessary unless you what the limit the bandwidth (AM is usually 10,000 hz). With NBFM, USB and LSB the down sampling is required. With AM the modulation is not needed (surprise it seems to work the same with or without the modulation), but I find that the signal strength of microphones varies so much that you need an AGC or code in different values for the different microphones and signal sources. If you are reading from a file, you can build in the up sampling. Using a microphone, I don’t see anyway around doing the up sampling.