GRC: Serial Port to Block Diagram Interface

Hello friends…

I’m trying to setup some experiments to utilize the GRC environment. As
a
part of it, I’m reading samples off an ADC connected to a
microcontroller
connected to PC via UART/RS232 Serial, using PySerial module.

I have been trying to write a Source block for GR, where a listening
thread
would read the ADC samples from the Serial port into a global variable,
and
then, another thread wud “probably” pass the data into a
gr.vector_source
(like?) block within a hier2 block.

Well, that was just the idea. But I guess the system doesn’t work this
way.
I’m not sure whether I’m entering the message-blocks domain, which is
expected to support such packetised(?) data. I read in the GRC Wiki -
“add
custom blocks” section that it might be possible to make such “special”
functionality encapsulated in a block-diagram-safe block. Any suitable
examples ?

Conflicting again is the thought that ultimately samples from USRP and
Audio
sources are also probably caught in chunks and assembled into streams.
But
the sources for them look too complex and spread out for me to look into
right now.

I hope someone will make it clear for me and point me in a direction I
can
look for a quick hack.

Cheers,

John

View this message in context:
http://old.nabble.com/GRC%3A-Serial-Port-to-Block-Diagram-Interface-tp27167565p27167565.html
Sent from the GnuRadio mailing list archive at Nabble.com.

You should make a hier2 block that has a gr.message_source inside of it.
You can put data you read from the serial port into a message queue.
(internally) The message sink will pop items off of the queue and into a
gnuradio stream.

Take a look in grc/grc_gnuradio/blks2/* for example. Several of the
blocks in there make use of these message blocks and message queues.
Then, to get the block in grc, you can make an xml file modeled off of
one of the blocks in grc/blocks/*.xml

Hope that points your in the right direction.
-Josh

Thanks for the pointer, Josh! It surely did help… But now I’m stuck up
somewhere else…

I managed to hack up the grc_gnuradio/blks2/probe.py to make the source
block I require. But before that, let me make clear my intention is to
mainly use the Graphical Sinks / Operators in GRC, to be able to wire up
blocks for processing and displaying the signals I acquire from my
serial interface. Right now, I’m using the python random number
generator to shove me samples (in a similar callback function
ref:probe.py).

I wired up the blocks in this fashion in GRC:

[ My Block ] -> [ Throttle ] -> [ Variable Sink ]

and kept a Variable Text Box also in the window, referring to the ID in
Variable Sink. Now I’m able to see the samples from the random number
generator in the Variable Text Box.This works since Variable Sink is
basically just a Message Sink with Callback. I could also use Operator
Blocks like Multiply, Add on the incoming sample stream (placed after
the Throttle block), whose output I’m able to see clearly on the
Variable Text Box.

Now to the issue - when I replace the Variable Sink block with any of
the typical Graphical Sink blocks [Scope, Number, Histo] or even File
sink, nothing seems to come out in the Sink. I suspect this due to the
format of data expected by these traditional Sink blocks to be different
from what is coming out from the Message Queue.

This is the portion of the code I am using (from probe.py) to insert
messages into the queue:

arr = numpy.array(random.random(), numpy.float32)
return gr.message_from_string(arr.tostring(), 0,
gr.sizeof_float, 1)
self._msgq.insert_tail(msg)

I’m not entirely clear about the argument structure for
gr.message_from_string() function, for which I couldn’t find much
documentation. I could understand the second argument represents message
type (0 for all data messages, 1 for End-Of-Message). I’ve no idea what
the third and fourth argument actually conveys.

I do understand that message queues were not exactly built for this
purpose. But I’m sure the mechanism to make the data acceptable to the
traditional Sink blocks would have some good use, let alone this poor
chap’s :wink:

Or am I in the wrong direction using message queues ?

Still Cheering,

John

This is the portion of the code I am using (from probe.py) to insert messages into the queue:

arr = numpy.array(random.random(), numpy.float32)
return gr.message_from_string(arr.tostring(), 0, gr.sizeof_float, 1)
self._msgq.insert_tail(msg)

From the doxygen:
gr_message_sptr gr_make_message_from_string (const std::string s, long
type, double arg1, double arg2)

A message is just a string of bytes, and them some arguments. The
arguments are implementation dependent. In the grc code, those arguments
are not even used, probably copy-pasted from some other code.

Basically, you put binary data into a message, which goes into a message
queue, and then its up to whoever reads from the queue to cast this data
into the correct form.

As a side note: Some of that grc/message passing kludgery needs to be
revisited. But I would hesitate to do so because that PMT work may come
to fruition…

I’m not entirely clear about the argument structure for gr.message_from_string() function, for which I couldn’t find much documentation. I could understand the second argument represents message type (0 for all data messages, 1 for End-Of-Message). I’ve no idea what the third and fourth argument actually conveys.

I do understand that message queues were not exactly built for this purpose. But I’m sure the mechanism to make the data acceptable to the traditional Sink blocks would have some good use, let alone this poor chap’s :wink:

Or am I in the wrong direction using message queues ?

Message source and sinks are designed to get data in and out of gnuradio
streams. Message queues and messages are how you interface with a
message source or sink; by putting or taking messages in and out of a
queue.

Internally in the gr-wxgui stuff, all the blocks actually use message
sinks to take streaming data out of gnuradio and get it into python for
plotting.

If you are having issues with the plotters, make sure that the samples
rates match up, that can cause issues because the plotters try to
decimate to achieve frame rate. Also be aware that the gr runtime passes
around bit chunks of memory at a time, not single numbers, so you may be
seeing an artifact of that.

-josh

Using the same example as a base

This is the portion of the code I am using (from probe.py) to insert
messages into the queue:

arr = numpy.array(random.random(), numpy.float32)
return gr.message_from_string(arr.tostring(), 0,
gr.sizeof_float, 1)
self._msgq.insert_tail(msg)

I was also seeing nothing on the scopes, but

If you are having issues with the plotters, make sure that the samples
rates match up, that can cause issues because the plotters try to decimate
to achieve frame rate.

helped and matching the rates fixed the issue.

I have successfully added a serial connection using the same approach,
but
there are some type casting/wrapping issues: the above approach uses a
numpy
array to convert an int/a float into the binary reprensentation. So to
read
a number from the serial connection involves parsing the ASCII -> number
(int/float) -> binary format.

But what about the other formats available?

Byte/char is easy, as it is just to pass the correct amount of bytes to
the
msg queue, but how do I represent e.g. complex signals in binary?

  • Martin