Asynchronous Keyboard Input with GUI

Hello GNU Radio community! I am a Midshipman working on PSK31, but I
have a
slightly different approach than Louis B.: I am creating a single
custom
block that will spawn a GUI to take keyboard input and then output the
ASCII bit representation of the keystroke. I used a lot of the code for
the
Logitech transceiver on CGRAN as my starting point.

Right now, the user hits a submit button on the GUI which then writes
any
text to a file. The work function then reads through the file to
determine
if there is a new character to submit. Global variables are used to
index
progress through the file. Eventually, I want to use a better system
than
FIFO, but I am using this a proof of concept.

Testing my block by running it straight into a file sink, I get 32,769
copies of each character. If I add a throttle block, then I don’t get
any
data in my file sink. My work function runs a while loop because I need
something to keep the program in the work function instead of the
MainLoop
function of the GUI. If I call MainLoop in the init function, then I
never get into the work function.

Thanks for any help that you can offer!
-Matt L.
MIDN USN

#Define Global Variables
last_tx = 0
size = 0

################################################################################

GRC Block Class

################################################################################
class keyboard2_b(gr.sync_block):
" Keyboard Source Block "

def __init__(self):
     gr.sync_block.__init__(
         self,
         name = "keyboard_b",
         in_sig = None, # Input signature: n/a
         out_sig = [numpy.int8], # Output signature:  8 digit 

integer
as a byte (-127 to 128)
)
app = wx.App(False)
frame = wx.Frame(None,wx.ID_ANY,title=“Episode IV: A New Hope for
Matt’s
Trident”,size=(850,150))
panel = LanoueGUI(frame)
frame.Center()
frame.Show(True)
#app.MainLoop()

def work(self, input_items, output_items):

while (1 == 1):
#Read from the key_src file
#print “I got to the work function of the block!”
file1 = open(’/tmp/key_src.txt’, ‘r’)
#Find the length of the file
global size
file1.seek(0, os.SEEK_END)
size = file1.tell()
print “Size: %s” % (str(size))

#time.sleep(0.2) #This was used to slow down the spew of terminal output

#Branching statement
global last_tx
print “Last: %s” % (str(last_tx))
if (last_tx < size):
file1.seek(last_tx, 0)
next_char = file1.read(1)
file1.close()
output_items[0][:] = ord(next_char[0])
print “Outputting %s” % (next_char)

last_tx = last_tx + 1

return len(output_items[0])
else:
file1.close()
output_items[0][:] = 95
#print “Outputting ‘_’”
return len(output_items[0])

return len(output_items[0])

On Wed, Nov 27, 2013 at 10:38 AM, Matt L. [email protected]
wrote:

FIFO, but I am using this a proof of concept.
MIDN USN
Hi Matt,

Hopefully you’ve made progress on this. But I think I might see where
the problem is. See the inline below.

def __init__(self):

panel = LanoueGUI(frame)
global size
file1.seek(last_tx, 0)
next_char = file1.read(1)
file1.close()
output_items[0][:] = ord(next_char[0])

When this work function is called, len(output_items[0]) is determined
by the scheduler; equivalent to noutput_items in a C++ block. By using
the call output_items[0][:], you’re actually assigning every item in
that array to the same character. It’s a numpy.array block and you can
experiment with this behavior:

: import scipy
: a = scipy.array(2*[10*[0,],])
: print a

array([[0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0]])

: a[0][:] = 1
: print a

array([[1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0]])

What you really want to do is set:

output_items[0][i] = ord(next_char[0])

And then increment i appropriately as an index into that array. Then,
you’ll only want to return i, since that’s the actual number of
outputs you’ve produced.

This same idea holds true for the other statement below.

return len(output_items[0])

Hope this helps!

Tom