Category: Software
Product Number: ADALM-PLUTO- Rev.C
Software Version: v0.39
Hi,
I try to setup a OOK (On-Off Keying) modulation with my PlutoSDR but I face some issues.
I want to generate a signal with a carrier of 868 MHz and a datarate of 2Mbaud.
I finally succed to generate a signal but i'm a bit disturbing by the rise/fall time between bit.
- The carrier frequency is OK (868 MHz)
- My 100 bits paquet take 50us to be send at 2Mbits/s which is also OK
- The time between each bit i have 500ns wich is also ok (2Mbits/s)
- The rise/fall time is about 250ns
I find that the rise/fall time are very long.
I expected something much shorter.
I use the following C code with libiio and libad9361 to drive the device.
Right now this code only generate a sequence of 100 bit "01010101..." and convert it to IQ sample data to send it every ms.
There is a better way to generate the signal to have a much shorter rise/fall time ?
#include <math.h>
#include <stdbool.h>
#include <stdint.h>
#include <string.h>
#include <signal.h>
#include <stdio.h>
#include <iio.h>
#include <ad9361.h>
#define SAMPLES_CNT 100 // Number of bit in my bitstream
#define TX_LO_FREQ 868000000 // 868 MHz
#define TX_SAMPLERATE 2000000 // 2 MHz
#define TX_GAIN -1 // -1 dB
#define TX_RF_BANDWIDTH 2000000 // 2 MHz
int main(int argc, char **argv)
{
// Create context and search phy device
struct iio_context* ctx = iio_create_context_from_uri("ip:pluto.local");
struct iio_device* dev_phy = iio_context_find_device(ctx, "ad9361-phy");
// Search TX device
struct iio_device* dev_tx = iio_context_find_device(ctx, "cf-ad9361-dds-core-lpc");
// Create IQ channels
struct iio_channel* ch_txi = iio_device_find_channel(dev_tx, "voltage0", true);
struct iio_channel* ch_txq = iio_device_find_channel(dev_tx, "voltage1", true);
// Enable channels
iio_channel_enable(ch_txi);
iio_channel_enable(ch_txq);
//Create nonclyclic TX IQ buffer
struct iio_buffer* buf_tx = iio_device_create_buffer(dev_tx, SAMPLES_CNT, false);
// Set TX LO frequency
iio_channel_attr_write_longlong( iio_device_find_channel(dev_phy, "altvoltage1", true), "frequency", TX_LO_FREQ);
// Set TX sample rate
ad9361_set_bb_rate(dev_phy, TX_SAMPLERATE);
// Set TX Gain
iio_channel_attr_write_double( iio_device_find_channel(dev_phy, "voltage0", true), "hardwaregain", TX_GAIN);
// Set TX RF filter bandwidth
iio_channel_attr_write_longlong( iio_device_find_channel(dev_phy, "voltage0", true), "rf_bandwidth", TX_RF_BANDWIDTH);
// Enable TX
iio_channel_attr_write_bool( iio_device_find_channel(dev_phy, "altvoltage1", true), "powerdown", false);
// Delay
sleep(1);
// IQ data buffer init (see buffer init for array size explanation)
int16_t data_iq[SAMPLES_CNT*2];
// Generate simple OOK signal equivalent to '0101010101...' bitstream
for (int i = 0; i < SAMPLES_CNT; i++)
{
if(i % 2 == 0)
{
data_iq[2 * i] = 2047; // I component
data_iq[2 * i + 1] = 2047; // Q component
}
else
{
data_iq[2 * i] = 0; // I component
data_iq[2 * i + 1] = 0; // Q component
}
}
// Send signal periodically
while(1)
{
// Get pointer to iio buffer start
int16_t* samples = (int16_t*) iio_buffer_start(buf_tx);
// Copy IQ data to IIO buffer
for (size_t i = 0; i < SAMPLES_CNT*2; i++)
samples[i] = data_iq[i] << 4;
// Send data
iio_buffer_push(buf_tx);
// Sleep 1ms
usleep(1000);
}
return EXIT_SUCCESS;
}