Hi. I'm Michael Ossmann of Great Scott Gadgets and this is Software Defined Radio with HackRF, lesson one. Welcome. This is the first in a series of videos that make up a complete course in Software Defined Radio. Software Defined Radio, or SDR, is the use of digital signal processing to implement radio functions. With SDR we can create transmitters or receivers for virtually any radio signal in software with a single piece of hardware and a general purpose computer. This is HackRF One. It's a Software Defined Radio peripheral that connects to your computer over USB and allows you to transmit or receive signals over a very wide range of frequencies. You can think of it kind of like a sound card. A sound card enables your computer to produce or record arbitrary sounds and a Software Defined Radio peripheral like HackRF allows your computer to produce or record arbitrary radio signals using an antenna instead of speaker and microphone. This course is an outgrowth of my training class that I've been teaching for several years. It's a two day class that I teach at information security conferences around the world and it's a very intense course in which I introduce people to Software Defined Radio and teach them the basics that they need to get started implementing digital radio systems and in particular to probe the security of systems that use radio. I came to the field of Software Defined Radio myself because I was doing wireless security research and I found SDR to be an incredibly valuable tool in my research and because I'm used to teaching people in the security community and I come from a security background I'll be taking somewhat of a security angle at times in this course but you don't have to be a security professional to get something out of this course you just have to be somebody who's interested in learning about Software Defined Radio. I take an approach that I call Software Defined Radio for hackers and you may or may not think of yourself as a hacker but if you're someone who enjoys coming up with creative solutions to technical problems then you're a hacker in my book and I think you'll enjoy this course. I assume that everyone has some background in computer programming or that you can learn that elsewhere. We won't do a lot of programming in this course but at times I'll refer to Python or C++ and we might look at a little bit of source code. At times there might be an exercise where I ask you to write a small program that does something but if you're not a computer programmer don't worry as long as you're somebody who's generally good at making computers do things that you want them to do I think you'll get a lot out of this course. I am very excited to be putting this course online. I've been teaching our two-day class, as I mentioned, for some years now and this is an opportunity for me to take that content put it online under an open content license and make it available to the whole world. In addition, it's a chance for me to take my time with the content a little bit more than I'm able to in a two-day class. So as I produce this course in installments over time eventually I hope that it will contain even more content than my in-person training consists of. Of course it's great to be able to come and sit down and devote two whole days to learning SDR with a group of like-minded individuals and it's wonderful to be able to ask questions in person but hopefully I'll be able to over time answer everybody's questions throughout the content of the series as I go from one video to the next. I'm going to keep this pretty informal. I'm doing, I hope, most of these videos in one or two takes and so they may not be as polished as they could be but it allows me to get the videos out faster to people. If I make any terrible errors I will be sure to correct them on the website. Now, there is a website for this course if you happen to find this video by some other means go to greatscottgadgets.com/sdr. That's the website for the course and you'll find a page for each lesson as I post each lesson. Each lesson will have its own page and the video will be on that page and some additional text will be on that page. If there are any errors in the video I'll be sure to spell them out in the text of the page and correct them there and I will also have information about the exercises and homework on the page and then on the subsequent lesson we'll talk about the homework and I'll have some more information on that lesson's page. So I'm gonna keep it pretty informal and try to teach it in the same way that I teach my in-person class as much as possible. I'm going to use some blackboarding and some video of me and quite a bit of screen capture as we go through different demonstrations and exercises and primarily what I'll be using for the exercises is GNU Radio Companion which is a graphical user interface for GNU Radio and this course is called Software Defined Radio with HackRF because it's primarily about Software Defined Radio and we're using HackRF for many of the exercises in the class but a lot of the course is really going to be using GNU Radio and the true nature, the core of the course, is really about the fundamentals of digital signal processing that you need to understand to be able to build flexible software to find radio systems in the future. Now, you might have some hardware other than HackRF and you can probably use that for this course and you might not even have any hardware that is a Software Defined Radio peripheral and that's okay too. You'll still be able to get a lot out of the course learning about GNU Radio and Software Defined Radio and some of the exercises won't require any hardware whatsoever but many of the exercises do require some hardware so I encourage you to pick up a HackRF or some Software Defined Radio platform that you can use to complete the exercises in this course. Now, different platforms have different capabilities and some of them you'll be able to use for one exercise whereas another Software Defined Radio platform would be more appropriate for a different exercise but the one platform that you can use for all the exercises in this course is HackRF. I'm going to now just get started with an exercise let's just build something in GNU Radio Companion and get started by doing what's often called the "Hello World of Software Defined Radio" and that is an FM radio receiver. This is GNU Radio Companion. In this exercise we're going to use GNU Radio Companion to create a software radio that allows us to listen to an FM radio station. Now, GNU Radio Companion is a front end graphical interface to GNU Radio. GNU Radio is a software framework that allows us to create programs in C++ or Python and GNU Radio Companion is a tool that actually automatically creates Python programs that are software radio programs. So what we're going to do is create in this big blank area a visual flow graph of how we want our program to work and then we're going to click this button up here which will generate some Python code and run it for us. So, even if you don't know any computer programming GRC, or GNU Radio Companion, does all that for us. I'm going to start by taking a block from this list of blocks on the right. Underneath sources I'll take an osmocom source and the osmocom source is an abstraction layer that allows us to communicate with different hardware devices for software radio and it's a source which means it produces a digital signal that will be consumed by the next block in our flow graph and so what happens is this source tells the HackRF to turn on in receive mode and then it streams samples over USB from the HackRF and then out this output to the next block in the flow graph. Now, I'm not going to go into great detail about how every block in this flow graph works but what I hope you'll get out of today's exercise is some familiarity with GNU Radio and GNU Radio Companion and just a little bit of comfort in how to manipulate these blocks and put them together and execute a flow graph and actually build something with GNU Radio. In future lessons we'll talk much more about the details of why this flow graph works the way it does or the way it will when we finish it. The next block I'd like to use is under instrumentation WX it's a WX GUI FFT sync and the FFT sync allows us to visualize the frequency components in a signal. I'm going to connect one output to the other's input and that creates this directed line between them, this arrow between them, and you might have noticed that their titles, the titles of these two blocks, just changed from red to black because their inputs and outputs have been satisfied. So we now have a complete flow graph and this could be executed but it wouldn't be very useful yet until we make a couple of changes. I'm going to first of all look at this variable over here, samp rate, 32 000 samples per second isn't very many. So, let's go in here I right click and select properties and in this properties box I'm going to type 10 million but it's hard to get the number of zeros right so I'm going to type 10 e6 which is exponential notation. What this means is 10 times 10 to the sixth power so anytime you see an e6 that means millions e3 is thousands and so forth. So now you can see since I typed 10e6 that value shows 10 million and it also shows over here 10 million and over here in the third block 10 million. The reason those updated to 10 million is because if we look at their properties their sample rate is configured to samp underscore rate which is the name of this variable that I changed. So, the variable allows us to change multiple things in one place. Anything that refers to that sample rate variable can be changed just by changing the variable block over here. Now, some other things I'd like to change in this osmocom source 100 e6 that's 100 megahertz that is in the FM broadcast band but I'd like to tune right to the middle of the FM broadcast band 97.9 e6, and I'd like to change this RF gain to zero, turn off the front end amplifier near the antenna in HackRF we probably don't need it and I generally like to leave that amp off unless I'm in a particular situation where i need to pick up a very weak signal. FM broadcast stations are typically very strong signals unless you live a long way from any transmitters. These two gains are good defaults so we'll leave them, although in the future you may adjust them. Now, one change I'd like to make in the FFT sync is to go into properties and turn averaging on. That just makes it a little easier to see the FM radio stations individually in the FFT plot. Now notice I right clicked and selected properties but there's a handy keyboard shortcut. I encourage you to get get familiar with all the different keyboard shortcuts in GNU Radio Companion although I will try to remember not to use them while I'm recording videos so that it's more clear what I'm doing. You can also get to the properties simply by double clicking on a block. So, at this point we have a complete flow graph and it doesn't let us listen to FM radio but it at least lets us run the flow graph, visualize the signal, see that something is happening, and validate what we've done so far before we complicate our flow graph further. So I'm going to click this execute button up here the gears and the first thing that will happen is that it's going to prompt me for a file name. I'll call it lesson1 and notice it has a .grc extension for GNU Radio Companion. What this file is is a representation of the flow graph so it contains a listing of the different blocks and how they're configured and how they're connected together. This is one file that GNU Radio Companion creates but then as soon as I save this it's automatically going to create a Python program in addition to this .grc file and the generated Python program is going to be executed. So I save that, it creates Python, and executes it and here we have a nice FFT plot that is showing us live radio information coming from the antenna through the HackRF through USB through this osmocom source and into our FFT sync. Now you can see several megahertz of bandwidth being represented here and so each of these major peaks is a different FM radio station. You can see that their frequencies vary from negative five megahertz to positive five megahertz and we'll talk a little bit more about what that means in the future but for now you can think of this zero point as being the center frequency of 97.9 million. Well, it would be nice if it actually displayed 97 98 million and so forth so let's just adjust our flow graph so it does that. I'm going to kill the flow graph by pressing this stop button or clicking this stop button instead of by closing the foreground window because that will make sure to shut things down cleanly so the HackRF is back to its default idle state. So I'd like to set this baseband frequency right here to something other than zero in the FFT sync. I'd like to set it to 97.9 million and if I go into the properties I could just type 97.986 but instead of having multiple blocks that all refer to 97.9 e6 I'd like to use a variable. So, I'm going to create a variable called center freq, for center frequency, and now you can see the FFT sync got angry at me because the center freq variable doesn't exist. So I need to create a variable and I'll call this variable center_freq to agree with the other block and give it a value of 97.9 e6. Now you can see the FFT sync is happy and it agrees with the osmocom source however the osmocom source still says 97.9 and I would like it to say center_freq. That shouldn't have any immediate effect it should still be set to the same default value but now if I change it in this one place it will update in both these other places and I'm less likely to make an error in the future if I ever want to adjust that parameter. So now if we execute the flow graph it should look exactly the same except that the frequencies here show the actual frequency in megahertz that we've tuned the HackRF to and we can see if you hold the mouse over one of these prominent frequencies, in my neighborhood 96.5 is very strong and 98.5 is very strong, and you might notice that the the stations that are strongest in your area may not be the ones that you're familiar with you might be used to listening to one of these over here or there one of these weaker signals but you probably live closer to the antenna that is transmitting the stations that appear more prominently in your FFT plot. So now let's see about actually listening to one of these stations and the first step in doing that, the first step that I'd like to take, is to actually shift one of these frequencies to center. So the center of the plot, or the area what was formerly called zero megahertz or zero hertz, that's where I'd like to say move this 96.5 station over to center. There are a couple of different ways I can do that. Kill the flow graph with the stop button and now you might think "I'll just change my center frequency" but I'd like to show you that I can do this in software instead of actually tuning the hardware to a different frequency and in the future we'll see why that might be valuable to do it that way. I'm going to use a math operator and multiply. This simply does a point-by-point multiplication of one digital signal to the other digital signal. Each of these lines going from one block to another I think of as a signal, or a digital signal, and really a digital signal is just a sequence of numbers it streams from one block to another. Now I'm going to produce a signal from a signal source under waveform generators. This is a synthesized signal that I'm just producing in my CPU and multiplying that signal point by point against the signal that comes from the HackRF. Now the frequency that I want to set this to is actually the amount of shift that I want, or the difference in frequency between the center frequency and my channel frequency that I'm interested in. So I'm going to create a variable called channel_freq. I'll do that by copying and pasting one of these variable blocks and then in the properties I'll change its name to channel_freq and I'll give it 96.5 e6 as a value so that'll tune to 96.5 megahertz. Oops, I think I made an error. I was supposed to say channel_freq. Now over here in the signal source I would like this frequency to be center_freq minus channel_freq. Now you can see I can type an expression here using multiple variables. You can actually type any Python expression which is wonderful and terrifying, but remember that GRC is producing Python code for us so we can influence the way it does that by doing things like using variables and Python expressions and some of the parameters for these different blocks. Now I'd like to verify that this multiply is doing what I want so I'll take this FFT sink and copy and paste it. And, assuming it works properly, the center frequency of this FFT should be channel_freq so I will set this value baseband frequency to channel_freq and that will just change the ruler on the FFT sink to what we think it should be. Now let's execute this and see if it looks the way we want it to. Now we have two FFT plots and the one at the bottom is the one we had before, you can see 96.5 is off to the left, but the one at the top everything's been shifted over 1.4 megahertz to the right and now 96.5 is centered in our display. So if we had set that baseband frequency to zero we should see 96.5 right at zero hertz, which is right where i want it. Now I'm going to do some things to get ready to actually demodulate this station, this signal, and turn it into audio. The first thing I'm going to do is filter it. I'm going to go up to filters, select a low pass filter, it's low pass because i want to pass frequencies in the vicinity of zero hertz. I'll connect my output of my multiply block to the input of the low pass filter and I'm going to give this a cutoff frequency of 75 e3 or 75 kilohertz and a transition width of 25 kilohertz and I'm also going to decimate. Now the amount of decimation that I want is related to the amount of bandwidth of the signal that I'm interested in and obviously we have a lot more bandwidth than we really need, we're picking up multiple radio stations over many megahertz of bandwidth, and I'd like to just pick one out and I don't want to waste my CPU time dealing with a lot more samples than is necessary to describe that more narrow bandwidth. So, I'm going to create a variable here, I'll copy and paste again, called channel width and the width of a FM radio station is 200 kilohertz or 200 e3. So I'll set that channel width to 200 kilohertz and I'm going to set the decimation of my low pass filter based on that channel width. Now decimation is the process of reducing the sample rate so I'm going to start with the high sample rate and then I'm going to divide that sample rate down and the amount that I divide it is the amount of decimation. So I'd like to call this samp_rate divided by channel_width, which should be 10 million divided by 200 thousand. Now if I click OK it actually gets angry at me and the reason it gets angry, is might not be really obvious at first, but it's because this particular block only knows how to decimate by an integer number and in Python I've created some floating point numbers but I can restrict this to integer values by putting it in an int function like so. Now it's happy and of course 10 million divided by 200 thousand is in fact 50. so this value is what we expect. What's going to happen is we'll get 10 million samples per second into the low pass filter it will divide that sample rate by 50 and it will spit out 200 thousand samples per second. Now the next thing I'll do after a filter is a resampler and I'm going to use a rational resampler. Now this might seem a little funny because I'm changing the sample rate again. I just changed the sample rate here, and now I'm going to change the sample rate again and I'm going to change it by a ratio of 12/5. I interpolate by 12 and decimate by 5 and the reason I'm doing that is because twelve fifths is not an integer number the low pass filter was only able to decimate by an integer number and now i want to adjust the frequency or sorry adjust the sample rate to something that is not an integer relation it's a rational relation so i need a separate block to do that for me and then I'm going to feed that into the heart of the flow graph the actual demodulator that turns the radio signal or the the complex baseband signal which is what all these blue things are into an audio signal which is this orange output I'll connect my rational resampler to the wbfm receive block and then i need to configure it a little bit now wbfm stands for wideband FM and that's a name for the type of modulation that FM broadcast stations use this wants to have two parameters filled in one is the quadrature rate and what that's referring to is the sample rate of the input which should be 480 000 and then the audio decimation is the amount that this block is going to decimate further so if you do the math you can see that the most of the flow graph is operating at 10 million samples per second until we get to the low pass filter 10 million divided divided by 50 is 200 000 and then 200 000 times 12 divided by 5 is 480 000. 480 000 divided by 10 is 48 000 and we're actually going to use an audio sample rate of 48 000 samples per second which is a very common sample rate supported by pretty much every sound card so I'm going to go to audio and take an audio sync and you'll see that this can connect directly from there to there everything's happy except we don't want this to be set to sample rate we want it to be set to 48 000. in some ways this is a very complicated flow graph for its size because it has so many different sample rates we have one sample rate two sample rates three sample rates four different sample rates in a single flow graph and that can be very confusing it's one of the most difficult things to to get right or one of the easiest things to make a mistake is in making these rates and ratios not match up with one another although using variables can help with that for example the way i used a variable in the low pass filter divided by another variable now at this point this should actually produce audio and I'm going to disable one of these FFT syncs because i really only need one way to visualize this signal at this point the way i disabled that was by hitting the d key but you can do it by right clicking and selecting enable or disable or using these buttons up here so let's listen to radio see what happens here see if this works there we go I'm listening to a radio station now you might not have been able to hear that and we can adjust the level of the audio the way we can adjust that is simply by multiplying the signal that goes into the audio sync i will use math operators multiply I'm not going to multiply one stream by another I'm going to multiply by a constant so I'll use the multiply const block I'll put it in there between these two and you can see that these arrows are angry because i have a type mismatch see the orange to the blue the blue to the orange and i can fix that by going into the properties of the multiply block and changing it to a float i o type now it's happy but it's going to be multiplying by zero it would be nice to be able to multiply by one or two and what i would like to do is actually be able to adjust my audio level my volume in real time while the flow graph is running so I'm going to go to gui widgets wx and select a wx gui slider I'll call this slider audio gain and I'll give it a default value of 1 which is no gain at all a minimum of 0 and a maximum of oh how about 10 and that's probably more than i would want but let's see what happens here now I'll take this multiply const block and set its constant to audio underscore gain and now i should be able to listen to that radio station and turn its volume up or down there we go so now we can listen to a radio station whichever frequency we tune in here by using this channel freak variable and we can adjust the volume of that rate of that audio in real time now this flow graph you might have problems if you tried to run this flow graph and your computer isn't as fast as mine or maybe you're not using HackRF but you're using something else so one thing you can do if the flow graph is choppy or if you get a lot of o's capital o's showing up down here um that is an overrun indicating that your computer is not keeping up with the stream of information from the HackRF so maybe turn this down 8 million or 4 million and notice if i change that if I change it from 10 million to 4 million it changed here and it changed here and also this decimation right here changed which means that everything to the right of the low-pass filter is still operating at the same sample rates it was operating out before but the low-pass filter is automatically adjusted because of the way that decimation property is based on sample rate so all we have to do is change the sample rate in one place and this should work notice I'm i see a much narrower view i only see this station 96.5 and a few others I'm not seeing a broad view of many stations in the FM broadcast ban if you have hardware that only goes to 2 million samples per second just set this to 2 e6 and you can still again you can run the same exact flow graph except now 96.5 is off to the side and funny things happen so you have to be sure that you set your channel freak to something that's actually within the band that you is displayed here so for the last thing i want to try I'm going to set the sample rate all the way up to 20 million which is about the maximum that you can get with HackRF and this may or may not work on your computer it requires a lot of CPU power and it also requires a very fast USB interface some USB host controllers are faster than others some of them are busy because they have internal USB devices connected to them and so they're not able to give all the traffic or all the throughput available on the bus to the HackRF but I'm going to try it and see what happens here there we go now you notice i got some o's some overruns just when the flow graph first started up and if you see that that's not really a problem what is a problem is if you continue to see o's if overruns continue to happen while the flow graph is running but now you can see I'm running HackRF with a simple telescopic antenna tuned to the FM broadcast band and I'm looking at the entire FM broadcast ban from 88 megahertz to 108 megahertz and I can see every single FM radio station that is in my neighborhood and notice that this all this information is coming from the HackRF into the FFT sync and then in software and software we pick out one particular station so we could actually pick out multiple stations and listen to multiple stations simultaneously that's one of the things I'd like you to do for your homework yes there's homework so here are the things I'd like you to do for homework this lesson number one is try out pen to Linux I'm using pen two Linux for this demo all you have to do is download the Pentoo ISO image install it on a USB stick or a DVD and boot your computer to that USB stick or DVD and then you can run gnu radio companion and have all the software available to you that you need natively on your computer without having to install it yourself and your own operating system once you have pen two running and you've started gnu radio companion try to try to create the same flow graph just like i did and you might go through the whole the whole lesson here and watch the video while you do that and then try and update it in a few ways one thing that i think would be really interesting would be to to take something like this gui slider that we use for audio gain and create a slider for the channel frequency so that you can adjust the channel that you're listening to in real time that's one step that i think would be very interesting for you to try and then the next step I'd like you to try is to actually listen to two radio stations simultaneously and I'll be posting this information a little bit of information about this flow graph what I've made so far and the actual exercise the homework assignment will be spelled out in text on the website for this page for this lesson at greatscottgadgets.com sdr so you'll be able to go to that website and look at what the homework is and get some tips I'll probably put a hint or two in there for for how to accomplish this and in the next lesson we'll take a look at what everyone's created a flow graph that allows us to listen to two different radio stations at the same time well that's a wrap for lesson one I hope you enjoyed building an FM radio receiver in gnu radio FM radio broadcasts are of course analog radio signals and in this course we'll actually be spending more of the time talking about digital radio systems but FM radio is a really easy thing for everybody to tune to the first time because FM radio stations are all over the world they have a very strong signal strength and it's easy to verify that you're picking them up so I hope you'll complete the homework assignment that I gave during the exercise please take a look at the website text at greatscottgadgets.com sdr and if there are any corrections to the video or any additional information that you might need for the exercise I'll be sure to post it there and I hope to see you next time in lesson two.