Post Go back to editing

ADALM-PLUTO Output Power Variation

Hello,

I have several ADALM-PLUTOs, all configured the same in terms of output gain, frequency, etc.  Across a group of 8 PLUTOs, I am seeing output power deviations from min-to-max of over 15dB (PLUTO to PLUTO).  Is this to be expected?  If not, any ideas on what would cause this?

  • They should be within a few dB of one another if configured exactly the same way. How are you measuring their output power?

    -Travis

  • Also worth noting is at max TX gain (or what we believe to be max TX gain), we are seeing as high as -11.5dBm and as low as -28.5dBm (peak when measuring with RF analyzer) which seems low as well.  This is using SDR settings of: 1.7GHz output frequency, 5MHz RF BW, 2.6MHz Samp Freq.  May we have an incorrect config?

  • Can you transmit a fullscale tone and measure the output power?

    -Travis

  • Could you double-check the code below and see if you notice any issues?  If it looks OK, how should that be modified to produce the full-scale tone you mention above?

    // SdrGps.cpp : Defines the exported functions for the DLL application.
    // analogdevicesinc.github.io/.../
    //
    
    #define _CRT_SECURE_NO_DEPRECATE
    
    #include <stdio.h>
    #include <stdlib.h>
    #include <iio.h>
    #include <ad9361.h>
    #include <string.h>
    
    #define NUM_SAMPLES 2600000
    #define BUFFER_SIZE (NUM_SAMPLES * sizeof(int))
    
    static bool stopStreaming = false;
    
    struct iio_context *ctx       = NULL;
    struct iio_device  *txDev     = NULL;
    struct iio_device  *sdrDev    = NULL;
    struct iio_channel *phy_chn   = NULL;
    struct iio_channel *tx0_i     = NULL;
    struct iio_channel *tx0_q     = NULL;
    struct iio_buffer  *tx_buffer = NULL;
    
    #define CONTEXTURI "ip:192.168.2.1"
    
    int main(int argc, char** argv)
    {
    	int returnValue = 0;
    	uint cellFreq;
    
    	if (argc != 3) {
    		printf("Invalid Args: Should be ./CellStreamer <CELLFREQ> \"IPADDRESS\",  where CELLFREQ is the frequency in Ghz and ip address is in the form of ip:192.168.x.x\n");
    		return 1;
    	}
    
    	cellFreq = atof(argv[1]) * 1000000000; //Cell Frequency in GHz
    
    	stopStreaming = false;
    
    	ctx = iio_create_context_from_uri(argv[2]); //should be form of ip:192.168.2.1
    
    	if (ctx != NULL)
    	{
    		sdrDev = iio_context_find_device(ctx, "ad9361-phy");
    		if (sdrDev != NULL)
    		{
    			txDev = iio_context_find_device(ctx, "cf-ad9361-dds-core-lpc");
    			if (txDev != NULL)
    			{
    				iio_device_set_kernel_buffers_count(txDev, 8);
    
    				phy_chn = iio_device_find_channel(sdrDev, "voltage0", true);
    				iio_channel_attr_write(phy_chn, "rf_port_select", "A_BALANCED");
    				iio_channel_attr_write_longlong(phy_chn, "rf_bandwidth", 5000000);
    				iio_channel_attr_write_longlong(phy_chn, "sampling_frequency", 2600000);
    				iio_channel_attr_write_double(phy_chn, "hardwaregain", 0);
    
    				iio_channel_attr_write_bool(iio_device_find_channel(sdrDev, "altvoltage0", true), "powerdown", true); // Turn OFF RX LO
    				iio_channel_attr_write_bool(iio_device_find_channel(sdrDev, "altvoltage1", true), "powerdown", true); // Turn OFF TX LO
    				iio_channel_attr_write_longlong(iio_device_find_channel(sdrDev, "altvoltage1", true), "frequency", cellFreq); // Set TX LO frequency - CANect model specific
    
    				tx0_i = iio_device_find_channel(txDev, "voltage0", true);
    				if (!tx0_i)
    					tx0_i = iio_device_find_channel(txDev, "altvoltage0", true);
    
    				tx0_q = iio_device_find_channel(txDev, "voltage1", true);
    				if (!tx0_q)
    					tx0_q = iio_device_find_channel(txDev, "altvoltage1", true);
    
    				iio_channel_enable(tx0_i);
    				iio_channel_enable(tx0_q);
    
    				ad9361_set_bb_rate(sdrDev, 2600000);
    				iio_channel_attr_write_bool(iio_device_find_channel(sdrDev, "altvoltage1", true), "powerdown", false); // Turn ON TX LO
            
            //iio_channel_attr_write_bool(iio_device_find_channel(sdrDev, "out", false), "voltage_filter_fir_en", false);
    
    				tx_buffer = iio_device_create_buffer(txDev, NUM_SAMPLES, true);
    
    				short *ptx_buffer = (short *)iio_buffer_start(tx_buffer);
    
    				memset(ptx_buffer, (short)1, BUFFER_SIZE / sizeof(short));
    				returnValue = iio_buffer_push(tx_buffer);
    
    				//returnValue = 0;
    			}
    			else
    			{
    				//This is an Error. The 'cf-ad9361-dds-core-lpc' device wasn't found in the context
    				printf("Error: cf-ad9361-dds-core-lpc device not found in iio context\n");
    				returnValue = -1;
    			}
    		}
    		else
    		{
    			//This is an Error. The 'ad9361-phy' device wasn't found in the context
    			printf("Error: ad9361-phy device not found in iio context\n");
    			returnValue = -1;
    		}
    	}
    	else
    	{
    		//This is an error.  No Adalm-Pluto Context found at that specified IP address
    		printf("Error: No Adalm_Pluto Context found for %s\n", CONTEXTURI);
    		returnValue = -1;
    	}
    
    	if (tx_buffer != NULL)
    	{
    		iio_buffer_destroy(tx_buffer);
    	}
    
    	if (ctx != NULL)
    	{
    		iio_context_destroy(ctx);
    	}
    	return returnValue;
    }
    
  • Could you please look at the following code to see if anything jumps out?  If it looks OK, what would need to be modified to produce the full-scale tone you mention above?

    // SdrGps.cpp : Defines the exported functions for the DLL application.
    // https://analogdevicesinc.github.io/libiio/
    //
    
    #define _CRT_SECURE_NO_DEPRECATE
    
    #include <stdio.h>
    #include <stdlib.h>
    #include <iio.h>
    #include <ad9361.h>
    #include <string.h>
    
    #define NUM_SAMPLES 2600000
    #define BUFFER_SIZE (NUM_SAMPLES * sizeof(int))
    
    static bool stopStreaming = false;
    
    struct iio_context *ctx       = NULL;
    struct iio_device  *txDev     = NULL;
    struct iio_device  *sdrDev    = NULL;
    struct iio_channel *phy_chn   = NULL;
    struct iio_channel *tx0_i     = NULL;
    struct iio_channel *tx0_q     = NULL;
    struct iio_buffer  *tx_buffer = NULL;
    
    #define CONTEXTURI "ip:192.168.2.1"
    
    int main(int argc, char** argv)
    {
    	int returnValue = 0;
    	uint cellFreq;
    
    	if (argc != 3) {
    		printf("Invalid Args: Should be ./CellStreamer <CELLFREQ> \"IPADDRESS\",  where CELLFREQ is the frequency in Ghz and ip address is in the form of ip:192.168.x.x\n");
    		return 1;
    	}
    
    	cellFreq = atof(argv[1]) * 1000000000; //Cell Frequency in GHz
    
    	stopStreaming = false;
    
    	ctx = iio_create_context_from_uri(argv[2]); //should be form of ip:192.168.2.1
    
    	if (ctx != NULL)
    	{
    		sdrDev = iio_context_find_device(ctx, "ad9361-phy");
    		if (sdrDev != NULL)
    		{
    			txDev = iio_context_find_device(ctx, "cf-ad9361-dds-core-lpc");
    			if (txDev != NULL)
    			{
    				iio_device_set_kernel_buffers_count(txDev, 8);
    
    				phy_chn = iio_device_find_channel(sdrDev, "voltage0", true);
    				iio_channel_attr_write(phy_chn, "rf_port_select", "A_BALANCED");
    				iio_channel_attr_write_longlong(phy_chn, "rf_bandwidth", 5000000);
    				iio_channel_attr_write_longlong(phy_chn, "sampling_frequency", 2600000);
    				iio_channel_attr_write_double(phy_chn, "hardwaregain", 0);
    
    				iio_channel_attr_write_bool(iio_device_find_channel(sdrDev, "altvoltage0", true), "powerdown", true); // Turn OFF RX LO
    				iio_channel_attr_write_bool(iio_device_find_channel(sdrDev, "altvoltage1", true), "powerdown", true); // Turn OFF TX LO
    				iio_channel_attr_write_longlong(iio_device_find_channel(sdrDev, "altvoltage1", true), "frequency", cellFreq); // Set TX LO frequency - CANect model specific
    
    				tx0_i = iio_device_find_channel(txDev, "voltage0", true);
    				if (!tx0_i)
    					tx0_i = iio_device_find_channel(txDev, "altvoltage0", true);
    
    				tx0_q = iio_device_find_channel(txDev, "voltage1", true);
    				if (!tx0_q)
    					tx0_q = iio_device_find_channel(txDev, "altvoltage1", true);
    
    				iio_channel_enable(tx0_i);
    				iio_channel_enable(tx0_q);
    
    				ad9361_set_bb_rate(sdrDev, 2600000);
    				iio_channel_attr_write_bool(iio_device_find_channel(sdrDev, "altvoltage1", true), "powerdown", false); // Turn ON TX LO
            
            //iio_channel_attr_write_bool(iio_device_find_channel(sdrDev, "out", false), "voltage_filter_fir_en", false);
    
    				tx_buffer = iio_device_create_buffer(txDev, NUM_SAMPLES, true);
    
    				short *ptx_buffer = (short *)iio_buffer_start(tx_buffer);
    
    				memset(ptx_buffer, (short)1, BUFFER_SIZE / sizeof(short));
    				returnValue = iio_buffer_push(tx_buffer);
    
    				//returnValue = 0;
    			}
    			else
    			{
    				//This is an Error. The 'cf-ad9361-dds-core-lpc' device wasn't found in the context
    				printf("Error: cf-ad9361-dds-core-lpc device not found in iio context\n");
    				returnValue = -1;
    			}
    		}
    		else
    		{
    			//This is an Error. The 'ad9361-phy' device wasn't found in the context
    			printf("Error: ad9361-phy device not found in iio context\n");
    			returnValue = -1;
    		}
    	}
    	else
    	{
    		//This is an error.  No Adalm-Pluto Context found at that specified IP address
    		printf("Error: No Adalm_Pluto Context found for %s\n", CONTEXTURI);
    		returnValue = -1;
    	}
    
    	if (tx_buffer != NULL)
    	{
    		iio_buffer_destroy(tx_buffer);
    	}
    
    	if (ctx != NULL)
    	{
    		iio_context_destroy(ctx);
    	}
    	return returnValue;
    }

  • So, I was trying to insert C-code into this reply for your review to see if anything jumped out, but it gets flagged as "spam or abuse" and won't post.  Is there a better way to do this?  I am not sure what we should be adjusting to produce the full-scale tone you reference above.

  • I would just load up IIO-Scope and turn on the DDSs at max scale (0 dBFS) and lower the attenuation to 0dB on TX.

    -Travis

  • Hi to all in thread.
    I have seen this also. We are not using IIOscope BUT have the SAME firmware flashed into each board and the SAME application code loaded into each board.

    Baseband signal is radius 24000 (-2.7dB full scale) and Tx atten is set to 0dB.

    Tx power (a CW signal at 500MHz and again at 2.4GHz) measured on a spectrum analyser shows that generally the power falls into 2 camps; good (about +6dBm out) and bad (about -16dBm).

    We have seen this in 2 separate purchases over the last 18 months from Mouser UK. About 3 out of 8 boards are bad.

    I can dig for serial numbers if this is a suspected production batch issue.