├── music48000.raw ├── speech48000.raw ├── images ├── fldigi.png ├── gqrx-am.png ├── grc-am.png ├── grc-nfm.png ├── grc-ssb.png ├── gqrx-nfm.png ├── gqrx-ssb.png ├── bpf-warning.png ├── grc-ssb-bpf.png ├── pavucontrol.png ├── grc-am-running.png ├── grc-ssb-running.png ├── pavucontrol-loop.png └── bpf-warning.svg ├── LICENSE ├── gnuradio ├── nfm-rpitx.grc ├── ssb-rpitx.grc └── am-rpitx.grc └── README.md /music48000.raw: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ha7ilm/rpitx-app-note/HEAD/music48000.raw -------------------------------------------------------------------------------- /speech48000.raw: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ha7ilm/rpitx-app-note/HEAD/speech48000.raw -------------------------------------------------------------------------------- /images/fldigi.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ha7ilm/rpitx-app-note/HEAD/images/fldigi.png -------------------------------------------------------------------------------- /images/gqrx-am.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ha7ilm/rpitx-app-note/HEAD/images/gqrx-am.png -------------------------------------------------------------------------------- /images/grc-am.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ha7ilm/rpitx-app-note/HEAD/images/grc-am.png -------------------------------------------------------------------------------- /images/grc-nfm.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ha7ilm/rpitx-app-note/HEAD/images/grc-nfm.png -------------------------------------------------------------------------------- /images/grc-ssb.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ha7ilm/rpitx-app-note/HEAD/images/grc-ssb.png -------------------------------------------------------------------------------- /images/gqrx-nfm.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ha7ilm/rpitx-app-note/HEAD/images/gqrx-nfm.png -------------------------------------------------------------------------------- /images/gqrx-ssb.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ha7ilm/rpitx-app-note/HEAD/images/gqrx-ssb.png -------------------------------------------------------------------------------- /images/bpf-warning.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ha7ilm/rpitx-app-note/HEAD/images/bpf-warning.png -------------------------------------------------------------------------------- /images/grc-ssb-bpf.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ha7ilm/rpitx-app-note/HEAD/images/grc-ssb-bpf.png -------------------------------------------------------------------------------- /images/pavucontrol.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ha7ilm/rpitx-app-note/HEAD/images/pavucontrol.png -------------------------------------------------------------------------------- /images/grc-am-running.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ha7ilm/rpitx-app-note/HEAD/images/grc-am-running.png -------------------------------------------------------------------------------- /images/grc-ssb-running.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ha7ilm/rpitx-app-note/HEAD/images/grc-ssb-running.png -------------------------------------------------------------------------------- /images/pavucontrol-loop.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ha7ilm/rpitx-app-note/HEAD/images/pavucontrol-loop.png -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015 András Retzler 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | 23 | -------------------------------------------------------------------------------- /gnuradio/nfm-rpitx.grc: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Sun Nov 8 16:32:09 2015 5 | 6 | options 7 | 8 | id 9 | top_block 10 | 11 | 12 | _enabled 13 | True 14 | 15 | 16 | title 17 | 18 | 19 | 20 | author 21 | 22 | 23 | 24 | description 25 | 26 | 27 | 28 | window_size 29 | 1280, 1024 30 | 31 | 32 | generate_options 33 | wx_gui 34 | 35 | 36 | category 37 | Custom 38 | 39 | 40 | run_options 41 | prompt 42 | 43 | 44 | run 45 | True 46 | 47 | 48 | max_nouts 49 | 0 50 | 51 | 52 | realtime_scheduling 53 | 54 | 55 | 56 | alias 57 | 58 | 59 | 60 | _coordinate 61 | (10, 10) 62 | 63 | 64 | _rotation 65 | 0 66 | 67 | 68 | 69 | variable 70 | 71 | id 72 | samp_rate 73 | 74 | 75 | _enabled 76 | True 77 | 78 | 79 | value 80 | 48000 81 | 82 | 83 | alias 84 | 85 | 86 | 87 | _coordinate 88 | (10, 170) 89 | 90 | 91 | _rotation 92 | 0 93 | 94 | 95 | 96 | analog_nbfm_tx 97 | 98 | id 99 | analog_nbfm_tx_0 100 | 101 | 102 | _enabled 103 | True 104 | 105 | 106 | audio_rate 107 | samp_rate 108 | 109 | 110 | quad_rate 111 | samp_rate 112 | 113 | 114 | tau 115 | 75e-6 116 | 117 | 118 | max_dev 119 | 5e3 120 | 121 | 122 | alias 123 | 124 | 125 | 126 | affinity 127 | 128 | 129 | 130 | minoutbuf 131 | 0 132 | 133 | 134 | maxoutbuf 135 | 0 136 | 137 | 138 | _coordinate 139 | (440, 211) 140 | 141 | 142 | _rotation 143 | 0 144 | 145 | 146 | 147 | freq_xlating_fir_filter_xxx 148 | 149 | id 150 | freq_xlating_fir_filter_xxx_0 151 | 152 | 153 | _enabled 154 | True 155 | 156 | 157 | type 158 | ccc 159 | 160 | 161 | decim 162 | 1 163 | 164 | 165 | taps 166 | [1] 167 | 168 | 169 | center_freq 170 | 5000 171 | 172 | 173 | samp_rate 174 | samp_rate 175 | 176 | 177 | alias 178 | 179 | 180 | 181 | affinity 182 | 183 | 184 | 185 | minoutbuf 186 | 0 187 | 188 | 189 | maxoutbuf 190 | 0 191 | 192 | 193 | _coordinate 194 | (672, 227) 195 | 196 | 197 | _rotation 198 | 0 199 | 200 | 201 | 202 | audio_source 203 | 204 | id 205 | audio_source_0 206 | 207 | 208 | _enabled 209 | True 210 | 211 | 212 | samp_rate 213 | samp_rate 214 | 215 | 216 | device_name 217 | 218 | 219 | 220 | ok_to_block 221 | True 222 | 223 | 224 | num_outputs 225 | 1 226 | 227 | 228 | alias 229 | 230 | 231 | 232 | affinity 233 | 234 | 235 | 236 | minoutbuf 237 | 0 238 | 239 | 240 | maxoutbuf 241 | 0 242 | 243 | 244 | _coordinate 245 | (232, 235) 246 | 247 | 248 | _rotation 249 | 0 250 | 251 | 252 | 253 | blks2_tcp_sink 254 | 255 | id 256 | blks2_tcp_sink_0 257 | 258 | 259 | _enabled 260 | True 261 | 262 | 263 | type 264 | complex 265 | 266 | 267 | addr 268 | raspberrypi.local 269 | 270 | 271 | port 272 | 8011 273 | 274 | 275 | server 276 | False 277 | 278 | 279 | vlen 280 | 1 281 | 282 | 283 | alias 284 | 285 | 286 | 287 | affinity 288 | 289 | 290 | 291 | _coordinate 292 | (952, 235) 293 | 294 | 295 | _rotation 296 | 0 297 | 298 | 299 | 300 | audio_source_0 301 | analog_nbfm_tx_0 302 | 0 303 | 0 304 | 305 | 306 | analog_nbfm_tx_0 307 | freq_xlating_fir_filter_xxx_0 308 | 0 309 | 0 310 | 311 | 312 | freq_xlating_fir_filter_xxx_0 313 | blks2_tcp_sink_0 314 | 0 315 | 0 316 | 317 | 318 | -------------------------------------------------------------------------------- /images/bpf-warning.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 18 | 20 | 40 | 44 | 48 | 49 | 51 | 52 | 54 | image/svg+xml 55 | 57 | 58 | 59 | 60 | 61 | 65 | 74 | Warning: ! Never transmit on antenna without a band-pass filter! 143 | 152 | 160 | 168 | 178 | 188 | 189 | 190 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Application note on using rpitx 2 | 3 | The recently released rpitx by Evariste, F5OEO allows us to transmit an RF signal over GPIO18 (pin 12) of a Raspberry Pi. The software can accept an I/Q signal as an input, so now a Pi can be used as a general purpose SDR transmitter. 4 | 5 | This document is about using [GNU Radio](#using-a-raspberry-pi-as-remote-software-defined-radio-peripheral-from-gnu-radio) and [csdr](#using-rpitx-with-csdr-to-modulate-streaming-input) with *rpitx*. 6 | 7 | **Table of contents** 8 | 9 | * [Using a Raspberry Pi as remote software defined radio peripheral from GNU Radio](#using-a-raspberry-pi-as-remote-software-defined-radio-peripheral-from-gnu-radio) 10 | * [NFM modulator example for GNU Radio](#nfm-modulator-example-for-gnu-radio) 11 | * [SSB modulator example for GNU Radio](#ssb-modulator-example-for-gnu-radio) 12 | * [AM modulator example for GNU Radio](#am-modulator-example-for-gnu-radio) 13 | * [Using rpitx with csdr to modulate streaming input](#using-rpitx-with-csdr-to-modulate-streaming-input) 14 | * [Modulate from raw audio file](#modulate-from-raw-audio-file) 15 | * [Modulate from microphone input source](#modulate-from-microphone-input-source) 16 | * [Modulate from audio streamed from remote computer](#modulate-from-audio-streamed-from-remote-computer) 17 | * [Using ADPCM codec to decrease network usage while streaming](#using-adpcm-codec-to-decrease-network-usage-while-streaming) 18 | * [Transmitting amateur radio digital modes from remote computer](#transmitting-amateur-radio-digital-modes-from-remote-computer) 19 |

20 | ![Warning](/images/bpf-warning.png?raw=true) 21 |

22 | The output of the Raspberry Pi GPIO 18 is a square wave, which contains harmonics.
23 | For example, if you transmit on 28 MHz, you will also transmit on: 24 | 25 | * 28 × 3 = 84 MHz 26 | * 28 × 5 = 140 MHz 27 | * 28 × 7 = 196 MHz
... 28 | 29 | ...and actually you may distrub some important radio communication services. Please don't do this! You can get into trouble! You have been warned. 30 | 31 | In addition to the squre wave output, the spectrum is also affected by the PWM-based amplitude modulation implemented in *rpitx*. 32 | * Right now it is more useful to use these examples for e.g. demonstrations on SDR transmitters
(as most of them use the PWM mode). 33 | * If you want to connect this to a real antenna, you should use a **very good band-pass filter**! 34 | * Please check your signal output on a proper spectrum analyzer before ever using this on the air! 35 | * In addition, only transmit if you have a proper license to do so. 36 | 37 | 38 | ## Using a Raspberry Pi as remote software defined radio peripheral from GNU Radio 39 | 40 | To do this, you will need: 41 | * a PC running GNU Radio on Linux, 42 | * a Raspberry Pi with *rpitx* installed, 43 | * both connected to the same network. 44 | 45 | We will stream the I/Q signal from the PC to the Raspberry Pi via TCP. 46 | 47 | On the Raspberry Pi, execute: 48 | 49 | nc -l 8011 | sudo rpitx -i- -m IQFLOAT -f 28400 50 | 51 | * This will listen on TCP port 8011 for the I/Q signal. 52 | * The center frequency of the transmitter will be 28400 kHz. 53 | 54 | If you want it to restart everytime the connection is lost, use this command: 55 | 56 | while true; do (nc -l 8011; dd if=/dev/zero bs=4096 count=30); done | sudo rpitx -i- -m IQFLOAT -f 28400 57 | 58 | ### NFM modulator example for GNU Radio 59 | 60 | On the PC, open GNU Radio Companion, and load the flow graph in this repo at `gnuradio/nfm-rpitx`. 61 | 62 | ![NFM in GNU Radio](/images/grc-nfm.png?raw=true) 63 | 64 | If you execute it, the I/Q signal will be streamed to the Raspberry Pi through the TCP socket. 65 | 66 | * Note that the frequency translation is there on intention. On some unkown reason, the spectrum is quite distorted if our signal is centered at DC. 67 | 68 | Here is the good result if received with an RTL-SDR and GQRX: 69 | 70 | ![NFM in GQRX](/images/gqrx-nfm.png?raw=true) 71 | 72 | ### SSB modulator example for GNU Radio 73 | 74 | Use the flow graph in `gnuradio/ssb-rpitx`. 75 | This will transmit an **USB** signal. 76 | 77 | ![SSB in GNU Radio](/images/grc-ssb.png?raw=true) 78 | 79 | The spectrum of the transmitted I/Q signal looks like this: 80 | 81 | ![SSB in GNU Radio](/images/grc-ssb-running.png?raw=true) 82 | 83 | After receiving it with RTL-SDR and GQRX: 84 | 85 | ![SSB in GQRX](/images/gqrx-ssb.png?raw=true) 86 | 87 | If you want **LSB**, you should double-click the "Band Pass Filter" block, and change: 88 | * *Low Cutoff Freq* to -3000 89 | * *High Cutoff Freq* to -300 90 | 91 | ![SSB in GQRX](/images/grc-ssb-bpf.png?raw=true) 92 | 93 | ### AM modulator example for GNU Radio 94 | 95 | Use the flow graph in `gnuradio/am-rpitx`. 96 | This will transmit an **AM** signal. 97 | 98 | * One thing that can be screwed up is **gain**. I had to play with the AGC to get it right. 99 | 100 | ![AM in GQRX](/images/grc-am.png?raw=true) 101 | 102 | The spectrum of the transmitted I/Q signal looks like this: 103 | 104 | ![AM in GQRX](/images/grc-am-running.png?raw=true) 105 | 106 | After receiving it with RTL-SDR and GQRX: 107 | 108 | ![AM in GQRX](/images/gqrx-am.png?raw=true) 109 | 110 | ## Using rpitx with csdr to modulate streaming input 111 | 112 | csdr is a command line tool for simple DSP tasks. It can be used to build simple AM/FM/SSB receivers, and now transmitters as well, and is quite fast to setup. 113 | 114 | You will need the *dev* branch of *csdr* for doing this.
115 | Setup instructions: 116 | 117 | git clone https://github.com/simonyiszk/csdr.git 118 | cd csdr 119 | git fetch 120 | git checkout dev 121 | make && sudo make install 122 | 123 | Note that it should be already done if you installed *qtcsdr* previously. 124 | 125 | ### Modulate from raw audio file 126 | 127 | These examples will use the raw audio file `music48000.raw` and `speech48000.raw`, which is present in this repo. You can get this file by: 128 | 129 | git clone https://github.com/ha7ilm/rpitx-app-note 130 | cd rpitx-app-note; ls #There are your files. 131 | 132 | We will play these files in a loop, you can stop it with Ctrl+C. 133 | 134 | **Generate AM modulation:** 135 | 136 | (while true; do cat music48000.raw; done) | csdr convert_i16_f | csdr gain_ff 1.0 | csdr dsb_fc | csdr add_dcoffset_cc | sudo rpitx -i- -m IQFLOAT -f 28400 137 | 138 | * The part `csdr gain_ff 1.0` can be changed to increase/decrease modulation. 139 | * The `-f 28400` at the end gives the transmit frequency in kHz. 140 | 141 | **Generate USB modulation:** 142 | 143 | (while true; do cat speech48000.raw; done) | csdr convert_i16_f | csdr dsb_fc | csdr bandpass_fir_fft_cc 0 0.1 0.01 | csdr gain_ff 2.0 | csdr shift_addition_cc 0.2 | sudo rpitx -i- -m IQFLOAT -f 28400 144 | 145 | **Generate LSB modulation:** 146 | 147 | (while true; do cat speech48000.raw; done) | csdr convert_i16_f | csdr dsb_fc | csdr bandpass_fir_fft_cc -0.1 0 0.01 | csdr gain_ff 2.0 | csdr shift_addition_cc 0.2 | sudo rpitx -i- -m IQFLOAT -f 28400 148 | 149 | * It's the matter of the filter which sideband do we select: 150 | * `csdr bandpass_fir_fft_cc -0.1 0` is the lower sideband 151 | * `csdr bandpass_fir_fft_cc 0 0.1` is the upper sideband 152 | * I have experienced that if the SSB signal is in the center of the I/Q signal, then it is not transmitted correctly. The solution was to shift it. So the exact frequency should be around: `rpitx frequency + 48000*0.2 = rpitx frequency + 9600 Hz` 153 | * If you want to get some compression on the speech, you can try `csdr fastagc_ff` instead of `csdr gain_ff 2.0`. 154 | 155 | **Generate NFM modulation:** 156 | 157 | (while true; do cat music48000.raw; done) | csdr convert_i16_f | csdr gain_ff 7000 | csdr convert_f_samplerf 20833 | sudo rpitx -i- -m RF -f 28400 158 | 159 | **Generate WFM modulation:** 160 | 161 | (while true; do cat music48000.raw; done) | csdr convert_i16_f | csdr gain_ff 70000 | csdr convert_f_samplerf 20833 | sudo rpitx -i- -m RF -f 28400 162 | 163 | * Frequency deviation is set much higher with `csdr gain_ff 70000`, that's the only difference between this and NFM. 164 | 165 | ### Modulate from microphone input source 166 | Use this if you have a microphone connected to the Raspberry Pi via external USB audio device.
167 | You will have to get the correct ALSA device ID via `arecord -L`, it will be something like `plughw:CARD=Device,DEV=0`. You should enter as the argument of the `-D` switch of `arecord`. 168 | 169 | #AM: 170 | arecord -c1 -r48000 -D plughw:CARD=Device,DEV=0 -fS16_LE - | csdr convert_i16_f | csdr gain_ff 1.0 | csdr dsb_fc | csdr add_dcoffset_cc | sudo rpitx -i- -m IQFLOAT -f 28400 171 | #USB: 172 | arecord -c1 -r48000 -D plughw:CARD=Device,DEV=0 -fS16_LE - | csdr convert_i16_f | csdr dsb_fc | csdr bandpass_fir_fft_cc 0 0.1 0.01 | csdr gain_ff 2.0 | csdr shift_addition_cc 0.2 | sudo rpitx -i- -m IQFLOAT -f 28400 173 | #LSB: 174 | arecord -c1 -r48000 -D plughw:CARD=Device,DEV=0 -fS16_LE - | csdr convert_i16_f | csdr dsb_fc | csdr bandpass_fir_fft_cc -0.1 0 0.01 | csdr gain_ff 2.0 | csdr shift_addition_cc 0.2 | sudo rpitx -i- -m IQFLOAT -f 28400 175 | #NFM: 176 | arecord -c1 -r48000 -D plughw:CARD=Device,DEV=0 -fS16_LE - | csdr convert_i16_f | csdr gain_ff 7000 | csdr convert_f_samplerf 20833 | sudo rpitx -i- -m RF -f 28400 177 | #WFM: 178 | arecord -c1 -r48000 -D plughw:CARD=Device,DEV=0 -fS16_LE - | csdr convert_i16_f | csdr gain_ff 70000 | csdr convert_f_samplerf 20833 | sudo rpitx -i- -m RF -f 28400 179 | 180 | ### Modulate from audio streamed from remote computer 181 | 182 | First, start the transmitter: 183 | 184 | #AM: 185 | nc -l 8011 | csdr convert_i16_f | csdr gain_ff 1.0 | csdr dsb_fc | csdr add_dcoffset_cc | sudo rpitx -i- -m IQFLOAT -f 28400 186 | #USB: 187 | nc -l 8011 | csdr convert_i16_f | csdr dsb_fc | csdr bandpass_fir_fft_cc 0 0.1 0.01 | csdr gain_ff 2.0 | csdr shift_addition_cc 0.2 | sudo rpitx -i- -m IQFLOAT -f 28400 188 | #LSB: 189 | nc -l 8011 | csdr convert_i16_f | csdr dsb_fc | csdr bandpass_fir_fft_cc -0.1 0 0.01 | csdr gain_ff 2.0 | csdr shift_addition_cc 0.2 | sudo rpitx -i- -m IQFLOAT -f 28400 190 | #NFM: 191 | nc -l 8011 | csdr convert_i16_f | csdr gain_ff 7000 | csdr convert_f_samplerf 20833 | sudo rpitx -i- -m RF -f 28400 192 | #WFM: 193 | nc -l 8011 | csdr convert_i16_f | csdr gain_ff 70000 | csdr convert_f_samplerf 20833 | sudo rpitx -i- -m RF -f 28400 194 | 195 | The Raspberry Pi will listen on TCP port 8011, and wait for connection. 196 | 197 | Then, on the remote computer, execute: 198 | 199 | arecord -fS16_LE -r48000 -c1 - | nc raspberrypi.local 8011 200 | 201 | You should replace `raspberrypi.local` with the IP address of the Raspberry Pi (unless avahi config is the default). 202 | 203 | ### Using ADPCM codec to decrease network usage while streaming 204 | 205 | Let's see an example for this on the NFM modulator. Execute on the Raspberry Pi: 206 | 207 | nc -l 8011 | csdr decode_ima_adpcm_u8_i16 | csdr convert_i16_f | csdr gain_ff 7000 | csdr convert_f_samplerf 20833 | sudo rpitx -i- -m RF -f 28400 208 | 209 | On the PC, execute this: 210 | 211 | arecord -fS16_LE -r48000 -c1 - | csdr encode_ima_adpcm_i16_u8 | nc raspberrypi.local 8011 212 | 213 | ### Transmitting amateur radio digital modes from remote computer 214 | 215 | On the Raspberry Pi, run this to transmit USB: 216 | 217 | nc -l 8011 | csdr convert_i16_f | csdr dsb_fc | csdr bandpass_fir_fft_cc 0 0.1 0.01 | csdr gain_ff 2.0 | csdr shift_addition_cc 0.2 | sudo rpitx -i- -m IQFLOAT -f 28400 218 | 219 | On your PC, run: 220 | 221 | arecord -fS16_LE -r48000 -c1 - | nc raspberrypi.local 8011 222 | 223 | If you have Ubuntu on your PC, you are likely to have PulseAudio. 224 | 225 | Run `pavucontrol` and set the recording source of `arecord` to "Monitor of" your audio output. 226 | 227 | ![pavucontrol](/images/pavucontrol.png?raw=true) 228 | 229 | On the PC, run `fldigi`, and start to transmit: 230 | 231 | ![fldigi](/images/fldigi.png?raw=true) 232 | 233 | If you don't want to listen to the transmitted signal on your PC: 234 | 235 | sudo modprobe snd-aloop 236 | 237 | This will create an ALSA loopback interface. You also have to make the appropriate changes in `pavucontrol`: 238 | 239 | ![pavucontrol](/images/pavucontrol-loop.png?raw=true) 240 | -------------------------------------------------------------------------------- /gnuradio/ssb-rpitx.grc: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Sun Nov 8 20:04:52 2015 5 | 6 | options 7 | 8 | id 9 | top_block 10 | 11 | 12 | _enabled 13 | True 14 | 15 | 16 | title 17 | 18 | 19 | 20 | author 21 | 22 | 23 | 24 | description 25 | 26 | 27 | 28 | window_size 29 | 1280, 1024 30 | 31 | 32 | generate_options 33 | wx_gui 34 | 35 | 36 | category 37 | Custom 38 | 39 | 40 | run_options 41 | prompt 42 | 43 | 44 | run 45 | True 46 | 47 | 48 | max_nouts 49 | 0 50 | 51 | 52 | realtime_scheduling 53 | 54 | 55 | 56 | alias 57 | 58 | 59 | 60 | _coordinate 61 | (10, 10) 62 | 63 | 64 | _rotation 65 | 0 66 | 67 | 68 | 69 | variable 70 | 71 | id 72 | samp_rate 73 | 74 | 75 | _enabled 76 | True 77 | 78 | 79 | value 80 | 48000 81 | 82 | 83 | alias 84 | 85 | 86 | 87 | _coordinate 88 | (8, 83) 89 | 90 | 91 | _rotation 92 | 0 93 | 94 | 95 | 96 | wxgui_scopesink2 97 | 98 | id 99 | wxgui_scopesink2_0 100 | 101 | 102 | _enabled 103 | True 104 | 105 | 106 | type 107 | float 108 | 109 | 110 | title 111 | Scope plot of input signal 112 | 113 | 114 | samp_rate 115 | samp_rate 116 | 117 | 118 | v_scale 119 | 0 120 | 121 | 122 | v_offset 123 | 0 124 | 125 | 126 | t_scale 127 | 0 128 | 129 | 130 | ac_couple 131 | False 132 | 133 | 134 | xy_mode 135 | False 136 | 137 | 138 | num_inputs 139 | 1 140 | 141 | 142 | win_size 143 | 144 | 145 | 146 | grid_pos 147 | 148 | 149 | 150 | notebook 151 | 152 | 153 | 154 | trig_mode 155 | wxgui.TRIG_MODE_AUTO 156 | 157 | 158 | y_axis_label 159 | Counts 160 | 161 | 162 | alias 163 | 164 | 165 | 166 | affinity 167 | 168 | 169 | 170 | _coordinate 171 | (248, 179) 172 | 173 | 174 | _rotation 175 | 0 176 | 177 | 178 | 179 | band_pass_filter 180 | 181 | id 182 | band_pass_filter_0 183 | 184 | 185 | _enabled 186 | True 187 | 188 | 189 | type 190 | fir_filter_ccc 191 | 192 | 193 | decim 194 | 1 195 | 196 | 197 | interp 198 | 1 199 | 200 | 201 | gain 202 | 1 203 | 204 | 205 | samp_rate 206 | samp_rate 207 | 208 | 209 | low_cutoff_freq 210 | 300 211 | 212 | 213 | high_cutoff_freq 214 | 3000 215 | 216 | 217 | width 218 | 100 219 | 220 | 221 | win 222 | firdes.WIN_HAMMING 223 | 224 | 225 | beta 226 | 6.76 227 | 228 | 229 | alias 230 | 231 | 232 | 233 | affinity 234 | 235 | 236 | 237 | minoutbuf 238 | 0 239 | 240 | 241 | maxoutbuf 242 | 0 243 | 244 | 245 | _coordinate 246 | (432, 267) 247 | 248 | 249 | _rotation 250 | 0 251 | 252 | 253 | 254 | audio_source 255 | 256 | id 257 | audio_source_0 258 | 259 | 260 | _enabled 261 | True 262 | 263 | 264 | samp_rate 265 | samp_rate 266 | 267 | 268 | device_name 269 | 270 | 271 | 272 | ok_to_block 273 | True 274 | 275 | 276 | num_outputs 277 | 1 278 | 279 | 280 | alias 281 | 282 | 283 | 284 | affinity 285 | 286 | 287 | 288 | minoutbuf 289 | 0 290 | 291 | 292 | maxoutbuf 293 | 0 294 | 295 | 296 | _coordinate 297 | (64, 307) 298 | 299 | 300 | _rotation 301 | 0 302 | 303 | 304 | 305 | blocks_float_to_complex 306 | 307 | id 308 | blocks_float_to_complex_0 309 | 310 | 311 | _enabled 312 | True 313 | 314 | 315 | vlen 316 | 1 317 | 318 | 319 | alias 320 | 321 | 322 | 323 | affinity 324 | 325 | 326 | 327 | minoutbuf 328 | 0 329 | 330 | 331 | maxoutbuf 332 | 0 333 | 334 | 335 | _coordinate 336 | (256, 312) 337 | 338 | 339 | _rotation 340 | 0 341 | 342 | 343 | 344 | analog_const_source_x 345 | 346 | id 347 | analog_const_source_x_0 348 | 349 | 350 | _enabled 351 | True 352 | 353 | 354 | type 355 | float 356 | 357 | 358 | const 359 | 0 360 | 361 | 362 | alias 363 | 364 | 365 | 366 | affinity 367 | 368 | 369 | 370 | minoutbuf 371 | 0 372 | 373 | 374 | maxoutbuf 375 | 0 376 | 377 | 378 | _coordinate 379 | (64, 403) 380 | 381 | 382 | _rotation 383 | 0 384 | 385 | 386 | 387 | blks2_tcp_sink 388 | 389 | id 390 | blks2_tcp_sink_0 391 | 392 | 393 | _enabled 394 | True 395 | 396 | 397 | type 398 | complex 399 | 400 | 401 | addr 402 | raspberrypi.local 403 | 404 | 405 | port 406 | 8011 407 | 408 | 409 | server 410 | False 411 | 412 | 413 | vlen 414 | 1 415 | 416 | 417 | alias 418 | 419 | 420 | 421 | affinity 422 | 423 | 424 | 425 | _coordinate 426 | (1056, 323) 427 | 428 | 429 | _rotation 430 | 0 431 | 432 | 433 | 434 | wxgui_waterfallsink2 435 | 436 | id 437 | wxgui_waterfallsink2_0 438 | 439 | 440 | _enabled 441 | True 442 | 443 | 444 | type 445 | complex 446 | 447 | 448 | title 449 | Waterfall plot of transmitted signal (I/Q) 450 | 451 | 452 | samp_rate 453 | samp_rate 454 | 455 | 456 | baseband_freq 457 | 0 458 | 459 | 460 | dynamic_range 461 | 100 462 | 463 | 464 | ref_level 465 | 0 466 | 467 | 468 | ref_scale 469 | 2.0 470 | 471 | 472 | fft_size 473 | 512 474 | 475 | 476 | fft_rate 477 | 15 478 | 479 | 480 | average 481 | False 482 | 483 | 484 | avg_alpha 485 | 0 486 | 487 | 488 | win 489 | None 490 | 491 | 492 | win_size 493 | 494 | 495 | 496 | grid_pos 497 | 498 | 499 | 500 | notebook 501 | 502 | 503 | 504 | freqvar 505 | None 506 | 507 | 508 | alias 509 | 510 | 511 | 512 | affinity 513 | 514 | 515 | 516 | _coordinate 517 | (1056, 427) 518 | 519 | 520 | _rotation 521 | 0 522 | 523 | 524 | 525 | freq_xlating_fir_filter_xxx 526 | 527 | id 528 | freq_xlating_fir_filter_xxx_0 529 | 530 | 531 | _enabled 532 | True 533 | 534 | 535 | type 536 | ccc 537 | 538 | 539 | decim 540 | 1 541 | 542 | 543 | taps 544 | [1] 545 | 546 | 547 | center_freq 548 | -10000 549 | 550 | 551 | samp_rate 552 | samp_rate 553 | 554 | 555 | alias 556 | 557 | 558 | 559 | affinity 560 | 561 | 562 | 563 | minoutbuf 564 | 0 565 | 566 | 567 | maxoutbuf 568 | 0 569 | 570 | 571 | _coordinate 572 | (792, 315) 573 | 574 | 575 | _rotation 576 | 0 577 | 578 | 579 | 580 | analog_agc_xx 581 | 582 | id 583 | analog_agc_xx_0 584 | 585 | 586 | _enabled 587 | True 588 | 589 | 590 | type 591 | complex 592 | 593 | 594 | rate 595 | 1e-4 596 | 597 | 598 | reference 599 | 1.0 600 | 601 | 602 | gain 603 | 1.0 604 | 605 | 606 | max_gain 607 | 65535 608 | 609 | 610 | alias 611 | 612 | 613 | 614 | affinity 615 | 616 | 617 | 618 | minoutbuf 619 | 0 620 | 621 | 622 | maxoutbuf 623 | 0 624 | 625 | 626 | _coordinate 627 | (608, 299) 628 | 629 | 630 | _rotation 631 | 0 632 | 633 | 634 | 635 | audio_source_0 636 | wxgui_scopesink2_0 637 | 0 638 | 0 639 | 640 | 641 | analog_const_source_x_0 642 | blocks_float_to_complex_0 643 | 0 644 | 1 645 | 646 | 647 | audio_source_0 648 | blocks_float_to_complex_0 649 | 0 650 | 0 651 | 652 | 653 | analog_agc_xx_0 654 | freq_xlating_fir_filter_xxx_0 655 | 0 656 | 0 657 | 658 | 659 | band_pass_filter_0 660 | analog_agc_xx_0 661 | 0 662 | 0 663 | 664 | 665 | freq_xlating_fir_filter_xxx_0 666 | wxgui_waterfallsink2_0 667 | 0 668 | 0 669 | 670 | 671 | blocks_float_to_complex_0 672 | band_pass_filter_0 673 | 0 674 | 0 675 | 676 | 677 | freq_xlating_fir_filter_xxx_0 678 | blks2_tcp_sink_0 679 | 0 680 | 0 681 | 682 | 683 | -------------------------------------------------------------------------------- /gnuradio/am-rpitx.grc: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Sun Nov 8 22:20:57 2015 5 | 6 | options 7 | 8 | id 9 | top_block 10 | 11 | 12 | _enabled 13 | True 14 | 15 | 16 | title 17 | 18 | 19 | 20 | author 21 | 22 | 23 | 24 | description 25 | 26 | 27 | 28 | window_size 29 | 1280, 1024 30 | 31 | 32 | generate_options 33 | wx_gui 34 | 35 | 36 | category 37 | Custom 38 | 39 | 40 | run_options 41 | prompt 42 | 43 | 44 | run 45 | True 46 | 47 | 48 | max_nouts 49 | 0 50 | 51 | 52 | realtime_scheduling 53 | 54 | 55 | 56 | alias 57 | 58 | 59 | 60 | _coordinate 61 | (10, 10) 62 | 63 | 64 | _rotation 65 | 0 66 | 67 | 68 | 69 | variable 70 | 71 | id 72 | samp_rate 73 | 74 | 75 | _enabled 76 | True 77 | 78 | 79 | value 80 | 48000 81 | 82 | 83 | alias 84 | 85 | 86 | 87 | _coordinate 88 | (8, 83) 89 | 90 | 91 | _rotation 92 | 0 93 | 94 | 95 | 96 | audio_source 97 | 98 | id 99 | audio_source_0 100 | 101 | 102 | _enabled 103 | True 104 | 105 | 106 | samp_rate 107 | samp_rate 108 | 109 | 110 | device_name 111 | 112 | 113 | 114 | ok_to_block 115 | True 116 | 117 | 118 | num_outputs 119 | 1 120 | 121 | 122 | alias 123 | 124 | 125 | 126 | affinity 127 | 128 | 129 | 130 | minoutbuf 131 | 0 132 | 133 | 134 | maxoutbuf 135 | 0 136 | 137 | 138 | _coordinate 139 | (24, 171) 140 | 141 | 142 | _rotation 143 | 0 144 | 145 | 146 | 147 | analog_const_source_x 148 | 149 | id 150 | analog_const_source_x_0 151 | 152 | 153 | _enabled 154 | True 155 | 156 | 157 | type 158 | float 159 | 160 | 161 | const 162 | 0 163 | 164 | 165 | alias 166 | 167 | 168 | 169 | affinity 170 | 171 | 172 | 173 | minoutbuf 174 | 0 175 | 176 | 177 | maxoutbuf 178 | 0 179 | 180 | 181 | _coordinate 182 | (24, 291) 183 | 184 | 185 | _rotation 186 | 0 187 | 188 | 189 | 190 | blks2_tcp_sink 191 | 192 | id 193 | blks2_tcp_sink_0 194 | 195 | 196 | _enabled 197 | True 198 | 199 | 200 | type 201 | complex 202 | 203 | 204 | addr 205 | raspberrypi.local 206 | 207 | 208 | port 209 | 8011 210 | 211 | 212 | server 213 | False 214 | 215 | 216 | vlen 217 | 1 218 | 219 | 220 | alias 221 | 222 | 223 | 224 | affinity 225 | 226 | 227 | 228 | _coordinate 229 | (1000, 315) 230 | 231 | 232 | _rotation 233 | 0 234 | 235 | 236 | 237 | wxgui_waterfallsink2 238 | 239 | id 240 | wxgui_waterfallsink2_0 241 | 242 | 243 | _enabled 244 | True 245 | 246 | 247 | type 248 | complex 249 | 250 | 251 | title 252 | Waterfall plot of transmitted signal (I/Q) 253 | 254 | 255 | samp_rate 256 | samp_rate 257 | 258 | 259 | baseband_freq 260 | 0 261 | 262 | 263 | dynamic_range 264 | 100 265 | 266 | 267 | ref_level 268 | 0 269 | 270 | 271 | ref_scale 272 | 2.0 273 | 274 | 275 | fft_size 276 | 512 277 | 278 | 279 | fft_rate 280 | 15 281 | 282 | 283 | average 284 | False 285 | 286 | 287 | avg_alpha 288 | 0 289 | 290 | 291 | win 292 | None 293 | 294 | 295 | win_size 296 | 297 | 298 | 299 | grid_pos 300 | 301 | 302 | 303 | notebook 304 | 305 | 306 | 307 | freqvar 308 | None 309 | 310 | 311 | alias 312 | 313 | 314 | 315 | affinity 316 | 317 | 318 | 319 | _coordinate 320 | (1000, 427) 321 | 322 | 323 | _rotation 324 | 0 325 | 326 | 327 | 328 | blocks_add_const_vxx 329 | 330 | id 331 | blocks_add_const_vxx_0 332 | 333 | 334 | _enabled 335 | True 336 | 337 | 338 | type 339 | complex 340 | 341 | 342 | const 343 | 0.7 344 | 345 | 346 | vlen 347 | 1 348 | 349 | 350 | alias 351 | 352 | 353 | 354 | affinity 355 | 356 | 357 | 358 | minoutbuf 359 | 0 360 | 361 | 362 | maxoutbuf 363 | 0 364 | 365 | 366 | _coordinate 367 | (704, 187) 368 | 369 | 370 | _rotation 371 | 0 372 | 373 | 374 | 375 | blocks_float_to_complex 376 | 377 | id 378 | blocks_float_to_complex_0 379 | 380 | 381 | _enabled 382 | True 383 | 384 | 385 | vlen 386 | 1 387 | 388 | 389 | alias 390 | 391 | 392 | 393 | affinity 394 | 395 | 396 | 397 | minoutbuf 398 | 0 399 | 400 | 401 | maxoutbuf 402 | 0 403 | 404 | 405 | _coordinate 406 | (216, 176) 407 | 408 | 409 | _rotation 410 | 0 411 | 412 | 413 | 414 | blocks_multiply_const_vxx 415 | 416 | id 417 | blocks_multiply_const_vxx_0 418 | 419 | 420 | _enabled 421 | True 422 | 423 | 424 | type 425 | complex 426 | 427 | 428 | const 429 | 0.3 430 | 431 | 432 | vlen 433 | 1 434 | 435 | 436 | alias 437 | 438 | 439 | 440 | affinity 441 | 442 | 443 | 444 | minoutbuf 445 | 0 446 | 447 | 448 | maxoutbuf 449 | 0 450 | 451 | 452 | _coordinate 453 | (552, 187) 454 | 455 | 456 | _rotation 457 | 0 458 | 459 | 460 | 461 | freq_xlating_fir_filter_xxx 462 | 463 | id 464 | freq_xlating_fir_filter_xxx_0 465 | 466 | 467 | _enabled 468 | True 469 | 470 | 471 | type 472 | ccc 473 | 474 | 475 | decim 476 | 1 477 | 478 | 479 | taps 480 | [1] 481 | 482 | 483 | center_freq 484 | -10000 485 | 486 | 487 | samp_rate 488 | samp_rate 489 | 490 | 491 | alias 492 | 493 | 494 | 495 | affinity 496 | 497 | 498 | 499 | minoutbuf 500 | 0 501 | 502 | 503 | maxoutbuf 504 | 0 505 | 506 | 507 | _coordinate 508 | (696, 371) 509 | 510 | 511 | _rotation 512 | 0 513 | 514 | 515 | 516 | band_pass_filter 517 | 518 | id 519 | band_pass_filter_0 520 | 521 | 522 | _enabled 523 | True 524 | 525 | 526 | type 527 | fir_filter_ccc 528 | 529 | 530 | decim 531 | 1 532 | 533 | 534 | interp 535 | 1 536 | 537 | 538 | gain 539 | 1 540 | 541 | 542 | samp_rate 543 | samp_rate 544 | 545 | 546 | low_cutoff_freq 547 | -5000 548 | 549 | 550 | high_cutoff_freq 551 | 5000 552 | 553 | 554 | width 555 | 100 556 | 557 | 558 | win 559 | firdes.WIN_HAMMING 560 | 561 | 562 | beta 563 | 6.76 564 | 565 | 566 | alias 567 | 568 | 569 | 570 | affinity 571 | 572 | 573 | 574 | minoutbuf 575 | 0 576 | 577 | 578 | maxoutbuf 579 | 0 580 | 581 | 582 | _coordinate 583 | (512, 323) 584 | 585 | 586 | _rotation 587 | 0 588 | 589 | 590 | 591 | analog_agc_xx 592 | 593 | id 594 | analog_agc_xx_0 595 | 596 | 597 | _enabled 598 | True 599 | 600 | 601 | type 602 | complex 603 | 604 | 605 | rate 606 | 1e-2 607 | 608 | 609 | reference 610 | 0.5 611 | 612 | 613 | gain 614 | 1.0 615 | 616 | 617 | max_gain 618 | 65535 619 | 620 | 621 | alias 622 | 623 | 624 | 625 | affinity 626 | 627 | 628 | 629 | minoutbuf 630 | 0 631 | 632 | 633 | maxoutbuf 634 | 0 635 | 636 | 637 | _coordinate 638 | (384, 163) 639 | 640 | 641 | _rotation 642 | 0 643 | 644 | 645 | 646 | analog_const_source_x_0 647 | blocks_float_to_complex_0 648 | 0 649 | 1 650 | 651 | 652 | audio_source_0 653 | blocks_float_to_complex_0 654 | 0 655 | 0 656 | 657 | 658 | freq_xlating_fir_filter_xxx_0 659 | wxgui_waterfallsink2_0 660 | 0 661 | 0 662 | 663 | 664 | freq_xlating_fir_filter_xxx_0 665 | blks2_tcp_sink_0 666 | 0 667 | 0 668 | 669 | 670 | blocks_multiply_const_vxx_0 671 | blocks_add_const_vxx_0 672 | 0 673 | 0 674 | 675 | 676 | blocks_add_const_vxx_0 677 | band_pass_filter_0 678 | 0 679 | 0 680 | 681 | 682 | blocks_float_to_complex_0 683 | analog_agc_xx_0 684 | 0 685 | 0 686 | 687 | 688 | analog_agc_xx_0 689 | blocks_multiply_const_vxx_0 690 | 0 691 | 0 692 | 693 | 694 | band_pass_filter_0 695 | freq_xlating_fir_filter_xxx_0 696 | 0 697 | 0 698 | 699 | 700 | --------------------------------------------------------------------------------