Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,9 +1,14 @@
// Python things
__pycache__
*.pyc
.venv
build

// My devenv
*.iq
*.cs16
*.cf32
*.cs8
*.iqhackrf
*.egg-info
.direnv
Expand Down
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -53,15 +53,15 @@ Options:
-s, --samplerate INTEGER Samplerate of the radio
-l, --linetime FLOAT Time for each line to show
-o, --output FILENAME File to write to (default: stdout)
--format [float|bladerf|hackrf]
--format [float|bladerf|hackrf|plutosdr]
Output format of samples
--help Show this message and exit.
```

* Samplerate is what you will configure in your radio later. About half of that bandwidth is actually used for the image. The edges are left free since I've seen some pretty ugly bandfilter effects sometimes.
* Linetime is the time in seconds that each line of your images will display. Experiment a bit here, usually a good starting value is around 0.005 - 0.01.
* Output is the file to write to. Per default this is stdout.
* Format selects the output formatter. There is support for bladerf and hackrf radio formats as well as raw I/Q interleaved 32-bit float samples.
* Format selects the output formatter. There is support for bladerf, hackrf, and plutosdr radio formats as well as raw I/Q interleaved 32-bit float samples.
* You can pass multiple images to the program which will all be converted and written to the output.

The FFT adapts to the image size. However, I've not tried what happens for very wide or narrow images. Pictures with a horizontal resolution between about 512-2048 pixels seem to work fine, though. Only the first color channel of the image is used, so images should be black and white.
Expand Down
6 changes: 3 additions & 3 deletions spectrum_painter/img2iqstream.py
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
import click
from spectrum_painter.radios import GenericFloat, Bladerf, Hackrf
from spectrum_painter.radios import GenericFloat, Bladerf, Hackrf, Plutosdr
from spectrum_painter.spectrum_painter import SpectrumPainter

FORMATTERS = {'float': GenericFloat, 'bladerf': Bladerf, 'hackrf': Hackrf}
FORMATTERS = {'float': GenericFloat, 'bladerf': Bladerf, 'hackrf': Hackrf, 'plutosdr': Plutosdr}

@click.command()
@click.option('--samplerate', '-s', type=int, default=1000000, help='Samplerate of the radio')
@click.option('--linetime', '-l', type=float, default=0.005, help='Time for each line to show')
@click.option('--output', '-o', type=click.File('wb'), help='File to write to (default: stdout)', default='-')
@click.option('--format', type=click.Choice(['float', 'bladerf', 'hackrf']), default='float', help='Output format of samples')
@click.option('--format', type=click.Choice(['float', 'bladerf', 'hackrf', 'plutosdr']), default='float', help='Output format of samples')
@click.argument('srcs', nargs=-1, type=click.Path(exists=True))
def img2iqstream(samplerate, linetime, output, format, srcs):
formatter = FORMATTERS[format]()
Expand Down
30 changes: 29 additions & 1 deletion spectrum_painter/radios.py
Original file line number Diff line number Diff line change
Expand Up @@ -99,4 +99,32 @@ def transmit(self, complex_iq):
hackout.wait()
sout = hackout.communicate()
os.unlink(pipe_file)
return sout
return sout

class Plutosdr(Radio):
def __init__(self):
super(Plutosdr, self).__init__()
self.txvga = 0
self.rxvga = 0
self.rxlna = 0

def convert(self, complex_iq):
intlv = self._interleave(complex_iq)
clipped = self._clip(intlv)
converted = 127. * clipped
plutosdr_out = converted.astype(np.int16)
return plutosdr_out

def transmit(self, complex_iq):
plutosdr_out = self.convert(complex_iq)
pipe_file = mktemp()
os.mkfifo(pipe_file)
plutoout = Popen(['tx_sdr', '-f', str(self.frequency), '-s', str(self.samplerate), '-B', str(self.bandwidth),
'-F', 'CS16', '-g', 70, pipe_file], stdin=PIPE, stdout=PIPE, stderr=PIPE)
pipe = open(pipe_file, 'wb')
pipe.write(plutosdr_out)
pipe.close()
plutoout.wait()
sout = plutoout.communicate()
os.unlink(pipe_file)
return sout