DSP Basics Tutorial
Jump to navigation
Jump to search
Note that this tutorial purposefully does not have screenshots of the flowgraphs, to encourage you to assemble them without just copying what you see.
- Open the attached .grc file. This is the starting point that you will work off of, it just includes a special source I made, and a time and frequency sink (GUI).
- Run the flowgraph and use the time sink to figure out what this special source is outputting. What it's doing is creating 1's and 0's randomly (the 1's and 0's repeat for 15 samples), for the real part of the IQ signal (I), and then zeros for the imaginary part of the IQ signal (Q). This is called "On Off Keying" because we're just turning the I part of the signal on and off randomly (and we are leaving Q at zero).
- When we receive anything in the real world there will be noise added. So lets add some noise. Add a "noise source" block with amplitude 0.1. The amplitude adjusts how strong the noise is.
- Lets add this noise to our sinusoid to see what it looks like in the time and frequency domain. Use the "add" block, the inputs should be the signal source and the noise source. Reconnect the time and frequency sink to the output of the add block.
- Run the flowgraph and note what changed in both time and frequency.
- One issue with transmiting 1's and 0's directly is that the frequency domain of our signal is VERY "wide", i.e. the signal takes up a huge amount of spectrum/bandwidth.
- Lets filter the signal to reduce the amount of bandwidth it uses. Add a "Low Pass Filter" block right after the On Off Keying source. Use Cutoff Freq of 2500 and transition width of 500.
- Run the flowgraph. Notice how the spikes in the frequency domain stop around 2500. That's what setting a cutoff frequency of 2500 did. The transition width just tells it how quickly the passband (frequencies we pass) transitions to a stopband (frequencies we block).
- Now look at the time sink. It doesn't go immediately from on-to-off anymore does it? By limiting the frequencies our signal can be composed of, we prevent ourselves from being able to create a steep edge of a square wave.
- You may have noticed that there is a lot of energy at "DC" (a spike at 0 Hz in the frequency sink). This is because our signal goes between 0 and # So the average value of our signal (in the time domain) is definitely not zero. Lets try to make it zero (you will soon see why we want to).
- Add an "Add Const" block right after the On Off Keying source. This block lets us add a constant value to our signal. Use a "constant" of -0.5 So this is more of a subtract constant block.
- Run the flowgraph and look at the signal in the time domain. It should be centered around zero now. In the frequency domain we should see no more spike at DC. Good job, we are finally transmitting a "decent" signal!
- If you haven't realized it by now, we are essentially simulating a wireless transmitter. The chain of blocks going into the top port of the Add block is like our transmitter. The Add block combined with the Noise Source is like a simulated wireless channel that adds noise. The Time and Frequency sink show us what we might see at a receiver.
- Right now this signal is centered around DC (in the frequency domain). The center of the signal is at 0 Hz. Also, there are negative frequencies. This is all because we generated the signal at "baseband". This may or may not be a problem. When we transmit a signal with an SDR we typically tell the SDR what frequency to tune to, then we send the SDR a baseband signal (in the form of IQ samples). But for now lets simulate the process of "upconverting" the baseband signal to a high frequency.
- Our goal is to shift the signal UP in frequency, so that it's transmitted on a "carrier". Lets use a carrier of 10 kHz. To do this we need to multiply our signal by a 10 kHz sinusoid (i.e. a 10 kHz carrier).
- Create a Signal Source block, using a cosine waveform, with a 10k frequency. Also add a "Multiply" block. The output of the Low Pass Filter should connect to one input of the Multiply block. The new signal source (our carrier) should be connected to the other input of the multiply block.
- Reconnect it so the output of the multiply block goes into the input of the Add block.
- Run the flow graph and spend some time observing the time and frequency domain changes, and think about what has happened here. Remember our Fourier transform pairs.
- When we have signals on a high frequency like this (i.e., NOT baseband), the time domain starts being less useful.
- Alright we are done with the transmit side. Now what if we want to receive and decode this signal? From this point on we will be simulating a receiver, which means we have to add a chain of blocks AFTER the Add block
- To shift the signal back to DC, redo the process of multiplying it by a -10k carrier. You can just copy and paste the two blocks we just made (the new Signal Source and the multiply block). Edit the frequency and change it from 10k to -10k. And we must connect the output of the Add block to the input of the new Multiply block. Reconnect the Time/Frequency sinks to the output of the new Multiply block
- Run the flowgraph and your signal should be back at baseband!
- Typically in a receiver we use a "matched filter", and we aren't going to get into the details here, but just know that we call it a matched filter because it's a filter that matches the filter at the transmitter. So lets copy and paste the Low Pass Filter we made earlier, and connect it after the new Multiply block
- Lets shift the signal back to 0 and 1, so add a "Add Const" block with a constant of 0.5 (between the multiply and the sinks)
- Run the flowgraph to verify these last two steps worked
- If you recall, the On Off Keying transmitter created the 1's and 0's but there was 15 samples for every 1 and 15 for every 0. So lets save only 1 out of every 15 samples. Add a "Keep 1 in N" block and set N to 15.
- At this point we want to recover the 1's and 0's so lets disable the Frequency Sink (it won't show us anything useful at this point) by clicking it and hitting D, or right clicking and clicking disable.
- The imaginary (Q) portion does not contain our 1's and 0's so lets get rid of it for now, using the "Complex to Real" block. That also means we have to modify our Time Sink block to show Floats instead of complex numbers, so double click it and choose Float for the type.
- Make sure your flowgraph runs, you should just see the Time Sink and there should only be 1 line showing, and it switches between 1 and 0 really fast because each sample is a bit now
- To make things easier to see, open your Time Sink and change number of points shown from 200 to 20. Also in the config tab change marker to circle and line style to none. Run the flowgraph to see what we changed.
- At this point we are done with the tutorial, we have recovered the 1's and 0's! In a real system there are some more steps, that you will learn about over time.