Editing GRAndWalkthroughUSRP

Jump to: navigation, search

Warning: You are not logged in. Your IP address will be publicly visible if you make any edits. If you log in or create an account, your edits will be attributed to your username, along with other benefits.

The edit can be undone. Please check the comparison below to verify that this is what you want to do, and then save the changes below to finish undoing the edit.
Latest revision Your text
Line 7: Line 7:
 
See the main [[Android]] page for a list of devices that have been tested and work with USRPs.
 
See the main [[Android]] page for a list of devices that have been tested and work with USRPs.
  
I suspect that network-connected USRPs will work pretty easily with Android. The biggest challenge with the B2xx series of USRPs is that they must have their firmware and FPGA images programmed in every time they are powered on. A network-connected USRP like an N200/N210 or X310 is pre-programmed and does not require the same workarounds for permissions issues that we face with USB devices. The only permission for a networked USRP is the "android.permission.INTERNET", which we have been using, anyways, for access to ControlPort.
+
I suspect that network-connected USRPs will work pretty easily with Android. The biggest challenge with the B2xx series of USRPs is that they must have their firmware and FPGA images programmed in every time they are powered on. A network-connected USRP like an N200/N210 or X310 is pre-programmed and does not require the same workarounds for permissions issues that we face with USB devices. The only permission for a networked USRP is the "android.permission.INTERNET", which we have been using, anyways, for access to ControlPort.
  
 
RTL-SDR devices can also work with GNU Radio for Android apps. Like the USRP B2xx devices, these need the USB permissions workaround, but they do not need to be programmed. We build the RTL-SDR library as well as gr-osmosdr support for them into our GR for Android dependency bundle. I suspect, too, that adding support for other USB-based devices like the BladeRF, HackRF, Airspy, etc. will also be fairly straight-forward.
 
RTL-SDR devices can also work with GNU Radio for Android apps. Like the USRP B2xx devices, these need the USB permissions workaround, but they do not need to be programmed. We build the RTL-SDR library as well as gr-osmosdr support for them into our GR for Android dependency bundle. I suspect, too, that adding support for other USB-based devices like the BladeRF, HackRF, Airspy, etc. will also be fairly straight-forward.
Line 19: Line 19:
 
Second, clone and build the [https://github.com/trondeau/GrHardwareService GrHardwareService application]. Install this app onto your Android device. If you don't have a USRP plugged in when this first starts, it will just crash (not particularly nice, I know, but we'll get there). With this loaded onto your machine, it installs the USRP firmware and FPGA images for the B2xx devices and starts listening for USB connections. And USB device that's plugged in where the vendor and produce IDs match any of the known-working USRPs, this app is launched and starts programming the device. It will have to ask you for permission to use the device twice, once to program the firmware and then again to program the FPGA image. Once that's done, the hardware is programmed and ready to go.
 
Second, clone and build the [https://github.com/trondeau/GrHardwareService GrHardwareService application]. Install this app onto your Android device. If you don't have a USRP plugged in when this first starts, it will just crash (not particularly nice, I know, but we'll get there). With this loaded onto your machine, it installs the USRP firmware and FPGA images for the B2xx devices and starts listening for USB connections. And USB device that's plugged in where the vendor and produce IDs match any of the known-working USRPs, this app is launched and starts programming the device. It will have to ask you for permission to use the device twice, once to program the firmware and then again to program the FPGA image. Once that's done, the hardware is programmed and ready to go.
  
If the program crashes on you when you first plug in a USRP, it's likely a permissions issue. I've noticed that on Marshmallow (Android version 6), I had to go into the App section under Settings, find the GrHardwareService app, go in there to Permissions, and enable the Storage permission. This is a new "feature" in [https://developer.android.com/training/permissions/requesting.html Marshmallow], and there are standard ways to handle it inside of the app. I'm not worrying about that here because I don't want to confuse the code any more than we have to by having version-specific checks.
+
If the program crashes on you when you first plug in a USRP, it's likely a permissions issue. I've noticed that on Marshmallow (Android version 6), I had to go into the App section under Settings, find the GrHardwareService app, go in there to Permissions, and enable the Storage permission. This is a new "feature" in [https://developer.android.com/training/permissions/requesting.html Marshmallow], and there are standard ways to handle it inside of the app. I'm not worrying about that here because I don't want to confuse the code any more than we have to by having version-specific checks.
  
 
== Adding Support for USB Devices ==
 
== Adding Support for USB Devices ==
Line 31: Line 31:
 
First, add these variables to your MainActivity class:
 
First, add these variables to your MainActivity class:
  
<syntaxhighlight lang="Java">    public static Intent intent = null;
+
<pre>    public static Intent intent = null;
 
     private String usbfs_path = null;
 
     private String usbfs_path = null;
 
     private int fd = -1;
 
     private int fd = -1;
     private static final String ACTION_USB_PERMISSION = "com.android.example.USB_PERMISSION";
+
     private static final String ACTION_USB_PERMISSION = &quot;com.android.example.USB_PERMISSION&quot;;
     private static final String DEFAULT_USBFS_PATH = "/dev/bus/usb";
+
     private static final String DEFAULT_USBFS_PATH = &quot;/dev/bus/usb&quot;;
 
     private UsbManager mUsbManager;
 
     private UsbManager mUsbManager;
     private UsbDevice mUsbDevice;</syntaxhighlight>
+
     private UsbDevice mUsbDevice;</pre>
 
We need to make sure we have the USB permissions set before we can launch the radio. So instead of doing everything in '''OnCreate''' like we've been doing, we'll separate into a few different functions. First, in '''OnCreate''', we need to get the USB device, set up a broadcast receiver, and then ask the user for permission to use the device. When the user grants permission, the broadcast receiver is launched. The broadcast receiver finishes up getting access to the USB device, and now we can act on the USB device to get the information out of it we need. This is what our '''OnCreate''' function looks like now:
 
We need to make sure we have the USB permissions set before we can launch the radio. So instead of doing everything in '''OnCreate''' like we've been doing, we'll separate into a few different functions. First, in '''OnCreate''', we need to get the USB device, set up a broadcast receiver, and then ask the user for permission to use the device. When the user grants permission, the broadcast receiver is launched. The broadcast receiver finishes up getting access to the USB device, and now we can act on the USB device to get the information out of it we need. This is what our '''OnCreate''' function looks like now:
  
<syntaxhighlight lang="Java">    @Override
+
<pre>    @Override
 
     protected void onCreate(Bundle savedInstanceState) {
 
     protected void onCreate(Bundle savedInstanceState) {
 
         super.onCreate(savedInstanceState);
 
         super.onCreate(savedInstanceState);
Line 47: Line 47:
 
         // Create the seekBar to move update the amplitude
 
         // Create the seekBar to move update the amplitude
 
         SeekBar ampSeekBar = (SeekBar) findViewById(R.id.seekBar);
 
         SeekBar ampSeekBar = (SeekBar) findViewById(R.id.seekBar);
         ampSeekBar.setMax(100);      // max value -> 1.0
+
         ampSeekBar.setMax(100);      // max value -&gt; 1.0
 
         ampSeekBar.setProgress(50);  // match 0.5 starting value
 
         ampSeekBar.setProgress(50);  // match 0.5 starting value
 
         ampSeekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
 
         ampSeekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
Line 56: Line 56:
 
                         new RPCConnection.KnobInfo(mult_knob_name, amp,
 
                         new RPCConnection.KnobInfo(mult_knob_name, amp,
 
                                 BaseTypes.DOUBLE);
 
                                 BaseTypes.DOUBLE);
                 HashMap _map = new HashMap<>();
+
                 HashMap _map = new HashMap&lt;&gt;();
 
                 _map.put(mult_knob_name, _k);
 
                 _map.put(mult_knob_name, _k);
 
                 postSetKnobMessage(_map);
 
                 postSetKnobMessage(_map);
Line 77: Line 77:
 
         mUsbDevice = intent.getParcelableExtra(UsbManager.EXTRA_DEVICE);
 
         mUsbDevice = intent.getParcelableExtra(UsbManager.EXTRA_DEVICE);
 
         if (mUsbDevice == null) {
 
         if (mUsbDevice == null) {
             Log.d("GrTemplateUSRP", "Didn't get a device; finding it now.");
+
             Log.d(&quot;GrTemplateUSRP&quot;, &quot;Didn't get a device; finding it now.&quot;);
 
             final HashSet allowed_devices = getAllowedDevices(this);
 
             final HashSet allowed_devices = getAllowedDevices(this);
 
             final HashMap usb_device_list = mUsbManager.getDeviceList();
 
             final HashMap usb_device_list = mUsbManager.getDeviceList();
 
             for (UsbDevice candidate : usb_device_list.values()) {
 
             for (UsbDevice candidate : usb_device_list.values()) {
                 String candstr = "v" + candidate.getVendorId() + "p" + candidate.getProductId();
+
                 String candstr = &quot;v&quot; + candidate.getVendorId() + &quot;p&quot; + candidate.getProductId();
 
                 if (allowed_devices.contains(candstr)) {
 
                 if (allowed_devices.contains(candstr)) {
 
                     // Need to handle case where we have more than one device connected
 
                     // Need to handle case where we have more than one device connected
Line 88: Line 88:
 
             }
 
             }
 
         }
 
         }
         Log.d("GrTemplateUSRP", "Selected Device: " + mUsbDevice);
+
         Log.d(&quot;GrTemplateUSRP&quot;, &quot;Selected Device: &quot; + mUsbDevice);
 
         PendingIntent permissionIntent = PendingIntent.getBroadcast(this, 0,
 
         PendingIntent permissionIntent = PendingIntent.getBroadcast(this, 0,
 
                 new Intent(ACTION_USB_PERMISSION), 0);
 
                 new Intent(ACTION_USB_PERMISSION), 0);
Line 95: Line 95:
 
         // If use hits OK, the broadcast receiver will be launched.
 
         // If use hits OK, the broadcast receiver will be launched.
 
         mUsbManager.requestPermission(mUsbDevice, permissionIntent);
 
         mUsbManager.requestPermission(mUsbDevice, permissionIntent);
     }</syntaxhighlight>
+
     }</pre>
 
Notice that we're still creating the Seek Bar here as the GUI setup.
 
Notice that we're still creating the Seek Bar here as the GUI setup.
  
Line 103: Line 103:
  
 
<pre>
 
<pre>
<resources>
+
     
    <usb-device vendor-id="3034" product-id="10296" />  <!-- RTL-SDR -->
+
         
    <usb-device vendor-id="9472" product-id="2" />      <!-- USRP B100 -->
+
       
    <usb-device vendor-id="9472" product-id="32" />    <!-- USRP B200/B210 -->
+
       
    <usb-device vendor-id="9472" product-id="33" />    <!-- USRP B200/B210 -->
+
       
    <usb-device vendor-id="9472" product-id="34" />    <!-- USRP B200mini -->
+
   
    <usb-device vendor-id="14627" product-id="30739" /> <!-- NI B200/B210 -->
+
   
    <usb-device vendor-id="14627" product-id="30740" /> <!-- NI B200/B210 -->
 
</resources>
 
 
</pre>
 
</pre>
 
We may have to add more devices here for other hardware support in the future.
 
We may have to add more devices here for other hardware support in the future.
Line 117: Line 115:
 
And this is what '''getAllowedDevices''' looks like:
 
And this is what '''getAllowedDevices''' looks like:
  
<syntaxhighlight lang="Java">    private static HashSet getAllowedDevices(final Context ctx) {
+
<pre>    private static HashSet getAllowedDevices(final Context ctx) {
 
         final HashSet ans = new HashSet();
 
         final HashSet ans = new HashSet();
 
         try {
 
         try {
Line 128: Line 126:
 
                 switch (eventType) {
 
                 switch (eventType) {
 
                     case XmlPullParser.START_TAG:
 
                     case XmlPullParser.START_TAG:
                         if (xml.getName().equals("usb-device")) {
+
                         if (xml.getName().equals(&quot;usb-device&quot;)) {
 
                             final AttributeSet as = Xml.asAttributeSet(xml);
 
                             final AttributeSet as = Xml.asAttributeSet(xml);
                             final Integer vendorId = Integer.valueOf(as.getAttributeValue(null, "vendor-id"), 10);
+
                             final Integer vendorId = Integer.valueOf(as.getAttributeValue(null, &quot;vendor-id&quot;), 10);
                             final Integer productId = Integer.valueOf(as.getAttributeValue(null, "product-id"), 10);
+
                             final Integer productId = Integer.valueOf(as.getAttributeValue(null, &quot;product-id&quot;), 10);
                             ans.add("v" + vendorId + "p" + productId);
+
                             ans.add(&quot;v&quot; + vendorId + &quot;p&quot; + productId);
 
                         }
 
                         }
 
                         break;
 
                         break;
Line 143: Line 141:
  
 
         return ans;
 
         return ans;
     }</syntaxhighlight>
+
     }</pre>
 
The broadcast receiver (See the main [http://developer.android.com/guide/topics/connectivity/usb/host.html Android USB Page] for more in this) that we registered, '''mUsbReceiver''', looks like this:
 
The broadcast receiver (See the main [http://developer.android.com/guide/topics/connectivity/usb/host.html Android USB Page] for more in this) that we registered, '''mUsbReceiver''', looks like this:
  
<syntaxhighlight lang="Java">
+
<pre>
 
     private final BroadcastReceiver mUsbReceiver = new BroadcastReceiver() {
 
     private final BroadcastReceiver mUsbReceiver = new BroadcastReceiver() {
 
         public void onReceive(Context context, Intent intent) {
 
         public void onReceive(Context context, Intent intent) {
Line 161: Line 159:
 
                     }
 
                     }
 
                     else {
 
                     else {
                         Log.d("GrTemplateUSRP", "Permission denied for device " + device);
+
                         Log.d(&quot;GrTemplateUSRP&quot;, &quot;Permission denied for device &quot; + device);
 
                     }
 
                     }
 
                 }
 
                 }
 
             }
 
             }
 
         }
 
         }
     };</syntaxhighlight>
+
     };</pre>
 
If the device registers and looks good, we assign it to our class object '''mUsbDevice''' and launch the next stage of starting up our application by calling '''SetupUSB'''.
 
If the device registers and looks good, we assign it to our class object '''mUsbDevice''' and launch the next stage of starting up our application by calling '''SetupUSB'''.
  
<syntaxhighlight lang="Java">    private void SetupUSB() {
+
<pre>    private void SetupUSB() {
 
         final UsbDeviceConnection connection = mUsbManager.openDevice(mUsbDevice);
 
         final UsbDeviceConnection connection = mUsbManager.openDevice(mUsbDevice);
  
Line 175: Line 173:
 
             fd = connection.getFileDescriptor();
 
             fd = connection.getFileDescriptor();
 
         } else {
 
         } else {
             Log.d("GrTemplateUSRP", "Didn't get a USB Device Connection");
+
             Log.d(&quot;GrTemplateUSRP&quot;, &quot;Didn't get a USB Device Connection&quot;);
 
             finish();
 
             finish();
 
         }
 
         }
Line 182: Line 180:
 
             usbfs_path = properDeviceName(mUsbDevice.getDeviceName());
 
             usbfs_path = properDeviceName(mUsbDevice.getDeviceName());
 
         } else {
 
         } else {
             Log.d("GrTemplateUSRP", "Didn't get a USB Device");
+
             Log.d(&quot;GrTemplateUSRP&quot;, &quot;Didn't get a USB Device&quot;);
 
             finish();
 
             finish();
 
         }
 
         }
Line 189: Line 187:
 
         int pid = mUsbDevice.getProductId();
 
         int pid = mUsbDevice.getProductId();
  
         Log.d("GrTemplateUSRP", "Found fd: " + fd + " usbfs_path: " + usbfs_path);
+
         Log.d(&quot;GrTemplateUSRP&quot;, &quot;Found fd: &quot; + fd + &quot; usbfs_path: &quot; + usbfs_path);
         Log.d("GrTemplateUSRP", "Found vid: " + vid + " pid: " + pid);
+
         Log.d(&quot;GrTemplateUSRP&quot;, &quot;Found vid: &quot; + vid + &quot; pid: &quot; + pid);
  
 
         StartRadio();
 
         StartRadio();
     }</syntaxhighlight>
+
     }</pre>
 
This function gets information from the USB device, prints it to logcat, and then calls '''StartRadio'''. We use a parsing function called '''properDeviceName''' to extract the USB device path from the device itself:
 
This function gets information from the USB device, prints it to logcat, and then calls '''StartRadio'''. We use a parsing function called '''properDeviceName''' to extract the USB device path from the device itself:
  
<syntaxhighlight lang="Java">    public final static String properDeviceName(String deviceName) {
+
<pre>    public final static String properDeviceName(String deviceName) {
 
         if (deviceName == null) return DEFAULT_USBFS_PATH;
 
         if (deviceName == null) return DEFAULT_USBFS_PATH;
 
         deviceName = deviceName.trim();
 
         deviceName = deviceName.trim();
 
         if (deviceName.isEmpty()) return DEFAULT_USBFS_PATH;
 
         if (deviceName.isEmpty()) return DEFAULT_USBFS_PATH;
  
         final String[] paths = deviceName.split("/");
+
         final String[] paths = deviceName.split(&quot;/&quot;);
 
         final StringBuilder sb = new StringBuilder();
 
         final StringBuilder sb = new StringBuilder();
         for (int i = 0; i < paths.length - 2; i++)
+
         for (int i = 0; i &lt; paths.length - 2; i++)
 
             if (i == 0)
 
             if (i == 0)
 
                 sb.append(paths[i]);
 
                 sb.append(paths[i]);
 
             else
 
             else
                 sb.append("/").append(paths[i]);
+
                 sb.append(&quot;/&quot;).append(paths[i]);
 
         final String stripped_name = sb.toString().trim();
 
         final String stripped_name = sb.toString().trim();
 
         if (stripped_name.isEmpty())
 
         if (stripped_name.isEmpty())
Line 213: Line 211:
 
         else
 
         else
 
             return stripped_name;
 
             return stripped_name;
     }</syntaxhighlight>
+
     }</pre>
This always seems to be "/dev/bus/usb", but we get it here each time in case something else changes.
+
This always seems to be &quot;/dev/bus/usb&quot;, but we get it here each time in case something else changes.
  
 
Finally, we call '''StartRadio''', which is really the rest of the '''OnCreate''' stuff we have done previously, but now we're waiting until the USB device is properly assigned.
 
Finally, we call '''StartRadio''', which is really the rest of the '''OnCreate''' stuff we have done previously, but now we're waiting until the USB device is properly assigned.
Line 243: Line 241:
 
First, we need to pass the '''fd''' and '''usrpfs_path''' values to the flowgraph. Change the function signature in '''fg.cpp''' to this:
 
First, we need to pass the '''fd''' and '''usrpfs_path''' values to the flowgraph. Change the function signature in '''fg.cpp''' to this:
  
<syntaxhighlight lang="Java">JNIEXPORT void JNICALL
+
<pre>JNIEXPORT void JNICALL
 
Java_org_gnuradio_grtemplateusrp_MainActivity_FgInit(JNIEnv* env,
 
Java_org_gnuradio_grtemplateusrp_MainActivity_FgInit(JNIEnv* env,
 
                                                     jobject thiz,
 
                                                     jobject thiz,
                                                     int fd, jstring devname)</syntaxhighlight>
+
                                                     int fd, jstring devname)</pre>
 
And in '''MainActivity.java''' where we declare the JNI functions, we need to add the two arguments:
 
And in '''MainActivity.java''' where we declare the JNI functions, we need to add the two arguments:
  
<syntaxhighlight lang="Java">public native void FgInit(int fd, String usbfs_path);</syntaxhighlight>
+
<pre>public native void FgInit(int fd, String usbfs_path);</pre>
And in '''SetupRadio''', make sure to pass this information as "FgInit(fd, usbfs_path)".
+
And in '''SetupRadio''', make sure to pass this information as &quot;FgInit(fd, usbfs_path)&quot;.
  
 
We then extract the information and format a device argument string for the usrp_source block:
 
We then extract the information and format a device argument string for the usrp_source block:
  
<syntaxhighlight lang="Java">
+
<pre>#include  
#include <gnuradio/uhd/usrp_source.h>
 
  
 
....
 
....
  
   const char *usbfs_path = env->GetStringUTFChars(devname, NULL);
+
   const char *usbfs_path = env-&gt;GetStringUTFChars(devname, NULL);
 
   std::stringstream args;
 
   std::stringstream args;
   args << "uhd,fd=" << fd << ",usbfs_path=" << usbfs_path;
+
   args &lt;&lt; &quot;uhd,fd=&quot; &lt;&lt; fd &lt;&lt; &quot;,usbfs_path=&quot; &lt;&lt; usbfs_path;
   GR_INFO("fg", boost::str(boost::format("Using UHD args=%1%") % args.str()));
+
   GR_INFO(&quot;fg&quot;, boost::str(boost::format(&quot;Using UHD args=%1%&quot;) % args.str()));
  
 
   uhd::stream_args_t stream_args;
 
   uhd::stream_args_t stream_args;
   stream_args.cpu_format = "fc32";
+
   stream_args.cpu_format = &quot;fc32&quot;;
   stream_args.otw_format = "sc16";
+
   stream_args.otw_format = &quot;sc16&quot;;
  
 
   ....
 
   ....
Line 276: Line 273:
 
   src = gr::uhd::usrp_source::make(args.str(), stream_args);
 
   src = gr::uhd::usrp_source::make(args.str(), stream_args);
  
   src->set_samp_rate(200e3);
+
   src-&gt;set_samp_rate(200e3);
   src->set_center_freq(101.1e6);
+
   src-&gt;set_center_freq(101.1e6);
   src->set_gain(20); // adjust as needed</syntaxhighlight>
+
   src-&gt;set_gain(20); // adjust as needed</pre>
 
The '''src''' is now a complex source. So what I'll do is create a simple flowgraph that looks like:
 
The '''src''' is now a complex source. So what I'll do is create a simple flowgraph that looks like:
  
<syntaxhighlight lang="Java">usrp_source -> complex_to_real -> multiply_const_ff -> opensl_sink</syntaxhighlight>
+
<pre>usrp_source -&gt; complex_to_real -&gt; multiply_const_ff -&gt; opensl_sink</pre>
 
The full flowgraph '''FgInit''' looks like this
 
The full flowgraph '''FgInit''' looks like this
  
<syntaxhighlight lang="Java">// Get any GNU Radio headers
+
<pre>// Get any GNU Radio headers
#include <gnuradio/top_block.h>
+
#include  
#include <gnuradio/uhd/usrp_source.h>
+
#include  
#include <gnuradio/blocks/complex_to_real.h>
+
#include  
#include <gnuradio/blocks/multiply_const_ff.h>
+
#include  
#include <grand/opensl_sink.h>
+
#include  
  
 
// Declare the global virtual machine and top-block objects
 
// Declare the global virtual machine and top-block objects
Line 295: Line 292:
 
gr::top_block_sptr tb;
 
gr::top_block_sptr tb;
  
extern "C" {
+
extern &quot;C&quot; {
  
 
JNIEXPORT void JNICALL
 
JNIEXPORT void JNICALL
Line 302: Line 299:
 
                                                     int fd, jstring devname)
 
                                                     int fd, jstring devname)
 
{
 
{
   GR_INFO("fg", "FgInit Called");
+
   GR_INFO(&quot;fg&quot;, &quot;FgInit Called&quot;);
  
   const char *usbfs_path = env->GetStringUTFChars(devname, NULL);
+
   const char *usbfs_path = env-&gt;GetStringUTFChars(devname, NULL);
 
   std::stringstream args;
 
   std::stringstream args;
   args << "uhd,fd=" << fd << ",usbfs_path=" << usbfs_path;
+
   args &lt;&lt; &quot;uhd,fd=&quot; &lt;&lt; fd &lt;&lt; &quot;,usbfs_path=&quot; &lt;&lt; usbfs_path;
   GR_INFO("fg", boost::str(boost::format("Using UHD args=%1%") % args.str()));
+
   GR_INFO(&quot;fg&quot;, boost::str(boost::format(&quot;Using UHD args=%1%&quot;) % args.str()));
  
 
   uhd::stream_args_t stream_args;
 
   uhd::stream_args_t stream_args;
   stream_args.cpu_format = "fc32";
+
   stream_args.cpu_format = &quot;fc32&quot;;
   stream_args.otw_format = "sc16";
+
   stream_args.otw_format = &quot;sc16&quot;;
  
 
   float samp_rate = 48e3;  // 48 kHz
 
   float samp_rate = 48e3;  // 48 kHz
Line 322: Line 319:
  
 
   // Construct the objects for every block in the flowgraph
 
   // Construct the objects for every block in the flowgraph
   tb = gr::make_top_block("fg");
+
   tb = gr::make_top_block(&quot;fg&quot;);
 
   src = gr::uhd::usrp_source::make(args.str(), stream_args);
 
   src = gr::uhd::usrp_source::make(args.str(), stream_args);
 
   c2r = gr::blocks::complex_to_real::make();
 
   c2r = gr::blocks::complex_to_real::make();
Line 328: Line 325:
 
   snk = gr::grand::opensl_sink::make(int(samp_rate));
 
   snk = gr::grand::opensl_sink::make(int(samp_rate));
  
   src->set_samp_rate(200e3);
+
   src-&gt;set_samp_rate(200e3);
   src->set_center_freq(101.1e6);
+
   src-&gt;set_center_freq(101.1e6);
   src->set_gain(20); // adjust as needed
+
   src-&gt;set_gain(20); // adjust as needed
  
 
   // Connect up the flowgraph
 
   // Connect up the flowgraph
   tb->connect(src, 0, c2r, 0);
+
   tb-&gt;connect(src, 0, c2r, 0);
   tb->connect(c2r, 0, mult, 0);
+
   tb-&gt;connect(c2r, 0, mult, 0);
   tb->connect(mult, 0, snk, 0);
+
   tb-&gt;connect(mult, 0, snk, 0);
 
}
 
}
  
....</syntaxhighlight>
+
....</pre>
 
This flowgraph does nothing particularly useful with the USRP, but we should be able to listen to static. We are not event setting up the sample rate, frequency, or gain values, so the incoming samples have no connection to anything real.
 
This flowgraph does nothing particularly useful with the USRP, but we should be able to listen to static. We are not event setting up the sample rate, frequency, or gain values, so the incoming samples have no connection to anything real.
  
 
For more complex usage of a USRP app, take a look at the [https://github.com/trondeau/GrRxFM GrRxFM], which uses a USRP to receive and demodulate broadcast FM signals. It sets up sliders to adjust the frequency and gain as well as handles sample rates and rate changes within the flowgraph.
 
For more complex usage of a USRP app, take a look at the [https://github.com/trondeau/GrRxFM GrRxFM], which uses a USRP to receive and demodulate broadcast FM signals. It sets up sliders to adjust the frequency and gain as well as handles sample rates and rate changes within the flowgraph.

Please note that all contributions to GNU Radio are considered to be released under the Creative Commons Attribution-ShareAlike (see GNU Radio:Copyrights for details). If you do not want your writing to be edited mercilessly and redistributed at will, then do not submit it here.
You are also promising us that you wrote this yourself, or copied it from a public domain or similar free resource. Do not submit copyrighted work without permission!

To edit this page, please answer the question that appears below (more info):

Cancel | Editing help (opens in new window)