Python Block Message Passing

From GNU Radio
Revision as of 17:09, 24 January 2022 by Mattcarrick (talk | contribs)
Jump to navigation Jump to search

Template:TutorialNavigation

The previous tutorial, Creating Your First Block, demonstrates how to create a Python block using the Embedded Python Block. The next tutorial, Low Pass Filter Example, demonstrates how to use filtering blocks in GNU Radio.

Flowgraph Overview

The following flowgraph will demonstrate how to:

  • Add message sending and receiving ports to Python blocks
  • Transmit messages
  • Receive and handle messages
  • Adapt block behavior in the work() function based on a received messages

Two custom Embedded Python Blocks will be created to:

  • Select, or multiplex, one of two input signals based on a receive message
  • Count the number of samples and send a message to the multiplexing block to switch inputs

This tutorial assumes you have already created at least one Embedded Python Block. If not, please complete the tutorial Creating Your First Block before moving on.

Message Overview

Messages are an asynchronous way to send information between blocks. Messages are good at conveying control data, maintaining a consistent state across blocks and providing some forms of non-data feedback to blocks in a flowgraph.

Messages have a couple unique properties:

  • There is no sample-clock based guarantee when messages will arrive
  • Messages are not associated with a specific sample like a tag
  • Message input and output ports do not have to be connected in GRC
  • Message ports use the Polymorphic Type (PMT)

Message ports are denoted by a grey color and their connections are distinguished by dashed lines:

MessageBlockExample.png

More information on message passing and PMTs can be found here: Message Passing

Create the Multiplexer Python Block

Start by adding the following blocks to the flowgraph and connecting them:

  • Noise Source
  • Signal Source
  • Two Python Block
  • Throttle
  • QT GUI Time Sink
  • Message Debug

StartingFlowgraphMessagePassing.png

Double-click the first Embedded Python Block and open the source in the editor:

EditMultiplexerProperties.png


The example_param is not needed, so remove the variable example_param from the __init()__function:

def __init__(self):  # only default arguments here

and delete the line:

self.example_param = example_param

Change the name of the block to Multiplexer:

name='Multiplexer',

Add a second input to the block:

in_sig=[np.complex64, np.complex64],

AddSecondInputEmbeddedPythonBlock.png


Save the code (CTRL+S) and return back to GRC. The name of the block will have changed and the block will now have two inputs. Connect the Noise Source and Signal Source to the two inputs:

MultiplexerWithTwoInputs.png


Return to the code editor. A input message port needs to be added. Create a variable to name the port,

self.selectPortName = 'selectPort'

and then add a line to create, or register, the input port:

self.message_port_register_in(pmt.intern(self.selectPortName))

and finally, add a line to connect the input port with a message handler.

self.set_msg_handler(pmt.intern(self.selectPortName), self.handle_msg)

AddMessageHandler.png


Save the code (CTRL+S). Notice that syntax errors are listed in the properties of the Embedded Python Block:

CodeEditorErrorExample.png


This error says that the pmt library needs to be imported. Return to the code editor and add the proper import statement:

import pmt

ImportPMT.png

PMT

describe basic PMT types

link against other PMT pages

Creating a Message Output Port

  • saving code 'compiles' the python and error messages are displayed the EPB window



  • message ports do not have to be connected like stream/vector ports






The next tutorial, Low Pass Filter Example, demonstrates how to use filtering blocks in GNU Radio.