# Receive AM signal with basicRX code

**URL:** <https://discourse.myriadrf.org/t/receive-am-signal-with-basicrx-code/6463>\
**Category:** Lime Suite\
**Created:** [25 August 2020 13:25 UTC](https://discourse.myriadrf.org/t/receive-am-signal-with-basicrx-code/6463 "2020-08-25T13:25:42Z")\
**Posts on this page:** 8\
**Page:** 1

<div class="post-metadata">

**Author:** ![vetri](https://avatars.discourse-cdn.com/v4/letter/v/3ab097/32.png) [@vetri](https://discourse.myriadrf.org/u/vetri)\
**Post date:** [25 August 2020 13:25 UTC](https://discourse.myriadrf.org/t/receive-am-signal-with-basicrx-code/6463/1 "2020-08-25T13:25:42Z")

</div>

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;

```

}

---

<div class="post-metadata">

**Author:** ![RightHalfPlane](https://avatars.discourse-cdn.com/v4/letter/r/46a35a/32.png) [@RightHalfPlane](https://discourse.myriadrf.org/u/RightHalfPlane)\
**Post date:** [29 August 2020 14:41 UTC](https://discourse.myriadrf.org/t/receive-am-signal-with-basicrx-code/6463/2 "2020-08-29T14:41:34Z")

</div>

> [@vetri](#):
>
> ```auto
> if (LMS_SetTestSignal(device, LMS_CH_RX, 0, LMS_TESTSIG_NONE, 0, 0) != 0)
> error();
> 
> ```

It works if you remove the line -

if (LMS\_SetTestSignal(device, LMS\_CH\_RX, 0, LMS\_TESTSIG\_NONE, 0, 0) != 0)  
error();

---

<div class="post-metadata">

**Author:** ![vetri](https://avatars.discourse-cdn.com/v4/letter/v/3ab097/32.png) [@vetri](https://discourse.myriadrf.org/u/vetri)\
**Post date:** [29 August 2020 14:56 UTC](https://discourse.myriadrf.org/t/receive-am-signal-with-basicrx-code/6463/3 "2020-08-29T14:56:39Z")

</div>

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?

---

<div class="post-metadata">

**Author:** ![RightHalfPlane](https://avatars.discourse-cdn.com/v4/letter/r/46a35a/32.png) [@RightHalfPlane](https://discourse.myriadrf.org/u/RightHalfPlane)\
**Post date:** [30 August 2020 15:40 UTC](https://discourse.myriadrf.org/t/receive-am-signal-with-basicrx-code/6463/4 "2020-08-30T15:40:02Z")

</div>

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.

---

<div class="post-metadata">

**Author:** ![vetri](https://avatars.discourse-cdn.com/v4/letter/v/3ab097/32.png) [@vetri](https://discourse.myriadrf.org/u/vetri)\
**Post date:** [31 August 2020 10:38 UTC](https://discourse.myriadrf.org/t/receive-am-signal-with-basicrx-code/6463/5 "2020-08-31T10:38:11Z")

</div>

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](http://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 = 1024_8;  
// float tx\_buffer[2_buffer\_size]; //buffer to hold complex values (2_samples))  
// for (int i = 0; i \<buffer\_size; i++) { //generate TX tone  
// const double pi = acos(-1);  
// double w = 2_pi_i_f\_ratio;  
// tx\_buffer[2_i] = cos(w);  
// tx\_buffer[2_i+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?.

---

<div class="post-metadata">

**Author:** ![RightHalfPlane](https://avatars.discourse-cdn.com/v4/letter/r/46a35a/32.png) [@RightHalfPlane](https://discourse.myriadrf.org/u/RightHalfPlane)\
**Post date:** [31 August 2020 17:02 UTC](https://discourse.myriadrf.org/t/receive-am-signal-with-basicrx-code/6463/6 "2020-08-31T17:02:16Z")

</div>

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.

> **[righthalfplane/SdrGlut](https://github.com/righthalfplane/SdrGlut)**
>
> SdrGlut is a simple software defined radio - using glut and glui for its interface - righthalfplane/SdrGlut

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.

---

<div class="post-metadata">

**Author:** ![vetri](https://avatars.discourse-cdn.com/v4/letter/v/3ab097/32.png) [@vetri](https://discourse.myriadrf.org/u/vetri)\
**Post date:** [1 September 2020 11:13 UTC](https://discourse.myriadrf.org/t/receive-am-signal-with-basicrx-code/6463/7 "2020-09-01T11:13:08Z")

</div>

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 ?.

---

<div class="post-metadata">

**Author:** ![RightHalfPlane](https://avatars.discourse-cdn.com/v4/letter/r/46a35a/32.png) [@RightHalfPlane](https://discourse.myriadrf.org/u/RightHalfPlane)\
**Post date:** [2 September 2020 04:32 UTC](https://discourse.myriadrf.org/t/receive-am-signal-with-basicrx-code/6463/8 "2020-09-02T04:32:37Z")

</div>

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.
