Paul Tagliamonte: Transmitting BPSK symbols (Part 2/5)
This post is part of a series called "PACKRAT". If this is the first post
you've found, it'd be worth reading the
intro post first and then looking over
all posts in the series.
In the last post, we worked through what IQ is,
and different formats that it may be sent or received in. Let s take that
and move on to Transmitting BPSK using IQ data!
When we transmit and receive information through RF using an SDR, data is
traditionally encoded into a stream of
symbols
which are then used by a program to modulate the IQ stream, and sent over
the airwaves.
PACKRAT uses BPSK to
encode Symbols through RF. BPSK is the act of modulating the phase of a
sine wave to carry information. The transmitted wave swaps between two
states in order to convey a 0 or a 1. Our symbols modulate the transmitted
sine wave s phase, so that it moves between in-phase with the SDR s transmitter
and 180 degrees (or radians) out of phase with the SDR s transmitter.
The difference between a Bit and a Symbol in PACKRAT is not incredibly
meaningful, and I ll often find myself slipping up when talking about them.
I ve done my best to try and use the right word at the right stage, but it s
not as obvious where the line between bit and symbol is at least not as
obvious as it would be with QPSK or QAM. The biggest difference is that there
are three meaningful states for PACKRAT over BPSK - a 1 (for In phase ), -1
(for 180 degrees out of phase ) and 0 (for no carrier ). For my
implementation, a stream of all zeros will not transmit data over the airwaves,
a stream of all 1s will transmit all 1 bits over the airwaves, and a stream
of all -1s will transmit all 0 bits over the airwaves.
We re not going to cover turning a byte (or bit) into a symbol yet I m going
to write more about that in a later section. So for now, let s just worry about
symbols in, and symbols out.
Transmitting a Sine wave at 0Hz
If we go back to thinking about IQ data as a precisely timed measurements of
energy over time at some particular specific frequency, we can consider what
a sine wave will look like in IQ. Before we dive into antennas and RF, let s go
to something a bit more visual.
For the first example, you can see an example of a camera who s frame rate (or
Sampling Rate!) matches the exact number of rotations per second (or
Frequency!) of the propeller and it appears to stand exactly
still. Every time the Camera
takes a frame, it s catching the propeller in the exact same place in space,
even though it s made a complete rotation.
The second example is very similar, it s a light strobing (in this case, our
sampling rate, since the darkness is ignored by our brains) at the same rate
(frequency) as water dropping from a
faucet and the video creator
is even nice enough to change the sampling frequency to have the droplets move
both forward and backward (positive and negative frequency) in comparison to the
faucet.
IQ works the same way. If we catch something in perfect frequency alignment
with our radio, we ll wind up with readings that are the same for the entire
stream of data. This means we can transmit a sine wave by setting all of the
IQ samples in our buffer to 1+0i, which will transmit a pure sine wave at
exactly the center frequency of the radio.
var sine []complex
for i := range sine
sine[i] = complex(1.0, 0.0)
Alternatively, we can transmit a Sine wave (but with the opposite phase) by
flipping the real value from 1 to -1. The same Sine wave is transmitted on
the same Frequency, except when the wave goes high in the example above, the
wave will go low in the example below.
var sine []complex
for i := range sine
sine[i] = complex(-1.0, 0.0)
In fact, we can make a carrier wave at any phase angle and amplitude by using a
bit of trig.
// angle is in radians - here we have
// 1.5 Pi (3 Tau) or 270 degrees.
var angle = pi * 1.5
// amplitude controls the transmitted
// strength of the carrier wave.
var amplitude = 1.0
// output buffer as above
var sine []complex
for i := range sine
sine[i] = complex(
amplitude*cos(angle),
amplitude*sin(angle),
)
The amplitude of the transmitted wave is the absolute value of the IQ
sample (sometimes called magnitude), and the phase can be computed as the
angle (or argument). The amplitude remains constant (at 1) in both cases.
Remember back to the airplane propeller or water droplets we re controlling
where we re observing the sine wave. It looks like a consistent value
to us, but in reality it s being transmitted as a pure carrier wave at the
provided frequency. Changing the angle of the number we re transmitting will
control where in the sine wave cycle we re observing it at.
Generating BPSK modulated IQ data
Modulating our carrier wave with our symbols is fairly straightforward to
do we can multiply the symbol by 1 to get the real value to be used
in the IQ stream. Or, more simply - we can just use the symbol directly in
the constructed IQ data.
var sampleRate = 2,621,440
var baudRate = 1024
// This represents the number of IQ samples
// required to send a single symbol at the
// provided baud and sample rate. I picked
// two numbers in order to avoid half samples.
// We will transmit each symbol in blocks of
// this size.
var samplesPerSymbol = sampleRate / baudRate
var samples = make([]complex, samplesPerSymbol)
// symbol is one of 1, -1 or 0.
for each symbol in symbols
for i := range samples
samples[i] = complex(symbol, 0)
// write the samples out to an output file
// or radio.
write(samples)
If you want to check against a baseline capture, here s
10 example packets at 204800 samples per second.
Next Steps
Now that we can transmit data, we ll start working on a receive path in Part 3,
in order to check our work when transmitting the packets, as well as being
able to hear packets we transmit from afar, coming up next in
Part 3!!
var sine []complex
for i := range sine
sine[i] = complex(1.0, 0.0)
var sine []complex
for i := range sine
sine[i] = complex(-1.0, 0.0)
// angle is in radians - here we have
// 1.5 Pi (3 Tau) or 270 degrees.
var angle = pi * 1.5
// amplitude controls the transmitted
// strength of the carrier wave.
var amplitude = 1.0
// output buffer as above
var sine []complex
for i := range sine
sine[i] = complex(
amplitude*cos(angle),
amplitude*sin(angle),
)
var sampleRate = 2,621,440
var baudRate = 1024
// This represents the number of IQ samples
// required to send a single symbol at the
// provided baud and sample rate. I picked
// two numbers in order to avoid half samples.
// We will transmit each symbol in blocks of
// this size.
var samplesPerSymbol = sampleRate / baudRate
var samples = make([]complex, samplesPerSymbol)
// symbol is one of 1, -1 or 0.
for each symbol in symbols
for i := range samples
samples[i] = complex(symbol, 0)
// write the samples out to an output file
// or radio.
write(samples)
Last year I started collecting ideas of things I would like to 3D print
one day, on Twitter. Twitter is fundamentally ephemeral, so I'll collect
it here instead. I got up to 14 items on Twitter, and now I'm up to 25.
I don't own a 3D printer, but I have access to one at the work office.
Perhaps this list is my subconcious trying to convince me to buy one.
What am I missing? What else should I be thinking of printing? Let me
know!
Hindus comprise 83% of Indian couples with more than two child children
If one wants to, one can read a bit more about the Uttar Pradesh Population bill 


How are you meant to write about an unfinished emancipation? Bodies of Light is a 2014 book by Glasgow-born Sarah Moss on the stirrings of women's suffrage in an arty clique in nineteenth-century England. Set in the intellectually smoggy cities of Manchester and London, we follow the studious and intelligent Alethia 'Ally' Moberly, who is struggling to gain the acceptance of herself, her mother and the General Medical Council.
'Alethia' may be the Greek goddess of truth, but our Ally is really searching for wisdom. Her strengths are her patience and bookish learning, and she acquires Latin as soon as she learns male doctors will use it to keep women away from the operating theatre. In fact, Ally's acquisition of language becomes a recurring leitmotif: replaying a suggestive dream involving a love interest, for instance, Ally thinks of 'dark, tumbling dreams for which she has a perfectly adequate vocabulary'. There are very few moments of sensuality in the book, and pairing it with Ally's understated wit achieves a wonderful effect.
The amount we learn about a character is adapted for effect as well. There are few psychological insights about Ally's sister, for example, and she thus becomes a fey, mysterious and almost Pre-Raphaelite figure 
This blog post is about my observations of some of the plants in my home garden.
While still a n00b on the subject, these notes are my observations and experiences over days, weeks and months. Thankfully, with the capability to take frequent pictures, it has been easy to do an assessment and generate a report of some of these amazing behaviors of plants, in an easy timeline order; all thanks to the EXIF data embedded.
This has very helpfully allowed me to record my, otherwise minor observations, into great detail; and make some sense out of it by correlating the data over time.
It is an emotional experience. You see, plants are amazing. When I sow a sapling, water it, feed it, watch it grow, prune it, medicate it, and what not; I build up affection towards it.
Though, at the same time, to me it is a strict relationship, not too attached; as in it doesn t hurt to uproot a plant if there is a good reason. But still, I find some sort of association to it.
With plants around, it feels I have a lot of lives around me. All prospering, communicating, sharing. And communicate they do. What is needed is just the right language to observe and absorb their signals and decipher what they are trying to say.
A few days ago, a friend and I were riffing about the wonderful stability of R and (subsets of) R packages. The rigorous ASAN/UBSAN/Valgrind/ checks, while at times frustrating for us package maintainers when we do not have easily replicable setups [1], really help in ensuring code quality. As do of course all other layers of quality control at CRAN, and for R. In passing, I mentioned there was an
The remainder of the code also runs. I just added one
The subtitle highlighting the then-most-recent releases is a little quaint now given that R has had eighten major.minor releases, and over sixty total releases, since then.
Stable and rigourously maintained interfaces are a fantastic resource that is dramatically under-appreciated. Efforts such as the