Skip to content

Commit 6d87fe8

Browse files
committed
added sweep style selection
1 parent 633d9c5 commit 6d87fe8

File tree

1 file changed

+75
-48
lines changed

1 file changed

+75
-48
lines changed

python_hackrf/pyhackrf_tools/pyhackrf_sweep.py

Lines changed: 75 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -35,18 +35,19 @@
3535

3636
PY_FREQ_MIN_MHZ = 0 # 0 MHz
3737
PY_FREQ_MAX_MHZ = 7_250 # 7250 MHz
38+
PY_BLOCKS_PER_TRANSFER = 16
3839

3940
# hackrf sweep settings
4041
AVAILABLE_SAMPLING_RATES = (2_000_000, 4_000_000, 6_000_000, 8_000_000, 10_000_000, 12_000_000, 14_000_000, 16_000_000, 18_000_000, 20_000_000)
4142
BASEBAND_FILTER_BANDWIDTH_RATIO = 0.75
4243
OFFSET_RATIO = 0.375
4344

44-
PY_BLOCKS_PER_TRANSFER = 16
4545

46-
sample_rate_hz = None
46+
SAMPLE_RATE = None
4747
frequency_step_1 = None
4848
frequency_step_2 = None
4949
frequency_step_3 = None
50+
SWEEP_STYLE = None
5051

5152
# hackrf sweep valiables
5253
binary_output_mode = False
@@ -101,9 +102,9 @@ def init_signals():
101102

102103

103104
def sweep_callback(buffer: np.ndarray, buffer_length: int, valid_length: int) -> int:
104-
global fftSize, window, pwr_1_start, pwr_1_stop, pwr_2_start, pwr_2_stop, norm_factor, data_length, sample_rate_hz
105+
global fftSize, window, pwr_1_start, pwr_1_stop, pwr_2_start, pwr_2_stop, norm_factor, data_length, SAMPLE_RATE
105106
global start_frequency, sweep_count, sweep_started, max_num_sweeps, check_max_num_sweeps, accepted_bytes, one_shot_mode, run_available
106-
global binary_output_mode, file_object, callback
107+
global binary_output_mode, file_object, callback, SWEEP_STYLE
107108

108109
timestamp = datetime.datetime.now()
109110
time_str = timestamp.strftime("%Y-%m-%d, %H:%M:%S.%f")
@@ -147,45 +148,66 @@ def sweep_callback(buffer: np.ndarray, buffer_length: int, valid_length: int) ->
147148
index += data_length
148149

149150
if binary_output_mode:
150-
record_length = 16 + (fftSize // 4) * 4
151-
line = struct.pack('I', record_length)
152-
line += struct.pack('Q', frequency)
153-
line += struct.pack('Q', frequency + frequency_step_1)
154-
line += struct.pack('<' + 'f' * (fftSize // 4), *pwr[pwr_1_start: pwr_1_stop])
155-
line += struct.pack('I', record_length)
156-
line += struct.pack('Q', frequency + frequency_step_2)
157-
line += struct.pack('Q', frequency + frequency_step_3)
158-
line += struct.pack('<' + 'f' * (fftSize // 4), *pwr[pwr_2_start: pwr_2_stop])
151+
if SWEEP_STYLE == pyhackrf.py_sweep_style.INTERLEAVED:
152+
record_length = 16 + (fftSize // 4) * 4
153+
line = struct.pack('I', record_length)
154+
line += struct.pack('Q', frequency)
155+
line += struct.pack('Q', frequency + frequency_step_1)
156+
line += struct.pack('<' + 'f' * (fftSize // 4), *pwr[pwr_1_start: pwr_1_stop])
157+
line += struct.pack('I', record_length)
158+
line += struct.pack('Q', frequency + frequency_step_2)
159+
line += struct.pack('Q', frequency + frequency_step_3)
160+
line += struct.pack('<' + 'f' * (fftSize // 4), *pwr[pwr_2_start: pwr_2_stop])
161+
else:
162+
record_length = 16 + fftSize * 4
163+
line = struct.pack('I', record_length)
164+
line += struct.pack('Q', frequency)
165+
line += struct.pack('Q', frequency + SAMPLE_RATE)
166+
line += struct.pack('<' + 'f' * fftSize, *pwr)
159167

160168
if file_object is None:
161169
sys.stdout.buffer.write(line)
162170
else:
163171
file_object.write(line)
164172

165173
elif callback is not None:
166-
callback({
167-
'timestamp': time_str,
168-
'start_frequency': frequency,
169-
'stop_frequency': frequency + frequency_step_1,
170-
'array': pwr[pwr_1_start: pwr_1_stop]
171-
})
172-
callback({
173-
'timestamp': time_str,
174-
'start_frequency': frequency + frequency_step_2,
175-
'stop_frequency': frequency + frequency_step_3,
176-
'array': pwr[pwr_2_start: pwr_2_stop]
177-
})
174+
if SWEEP_STYLE == pyhackrf.py_sweep_style.INTERLEAVED:
175+
callback({
176+
'timestamp': time_str,
177+
'start_frequency': frequency,
178+
'stop_frequency': frequency + frequency_step_1,
179+
'array': pwr[pwr_1_start: pwr_1_stop]
180+
})
181+
callback({
182+
'timestamp': time_str,
183+
'start_frequency': frequency + frequency_step_2,
184+
'stop_frequency': frequency + frequency_step_3,
185+
'array': pwr[pwr_2_start: pwr_2_stop]
186+
})
187+
188+
else:
189+
callback({
190+
'timestamp': time_str,
191+
'start_frequency': frequency,
192+
'stop_frequency': frequency + SAMPLE_RATE,
193+
'array': pwr
194+
})
178195

179196
else:
180-
line = f'{time_str}, {frequency}, {frequency + frequency_step_1}, {sample_rate_hz / fftSize}, {fftSize}, '
181-
pwr_1 = pwr[pwr_1_start: pwr_1_stop]
182-
for i in range(len(pwr_1)):
183-
line += f'{pwr_1[i]:.2f}, '
184-
line += f'\n{time_str}, {frequency + frequency_step_2}, {frequency + frequency_step_3}, {(sample_rate_hz / fftSize)}, {fftSize}, '
185-
pwr_2 = pwr[pwr_2_start: pwr_2_stop]
186-
for i in range(len(pwr_2)):
187-
line += f'{pwr_2[i]:.2f}, '
188-
line += '\n'
197+
if SWEEP_STYLE == pyhackrf.py_sweep_style.INTERLEAVED:
198+
line = f'{time_str}, {frequency}, {frequency + frequency_step_1}, {SAMPLE_RATE / fftSize}, {fftSize}, '
199+
pwr_1 = pwr[pwr_1_start: pwr_1_stop]
200+
for i in range(len(pwr_1)):
201+
line += f'{pwr_1[i]:.2f}, '
202+
line += f'\n{time_str}, {frequency + frequency_step_2}, {frequency + frequency_step_3}, {(SAMPLE_RATE / fftSize)}, {fftSize}, '
203+
pwr_2 = pwr[pwr_2_start: pwr_2_stop]
204+
for i in range(len(pwr_2)):
205+
line += f'{pwr_2[i]:.2f}, '
206+
line += '\n'
207+
else:
208+
line = f'{time_str}, {frequency}, {frequency + SAMPLE_RATE}, {SAMPLE_RATE / fftSize}, {fftSize}, '
209+
for i in range(len(pwr)):
210+
line += f'{pwr[i]:.2f}, '
189211

190212
if file_object is None:
191213
print(line, end='')
@@ -199,18 +221,23 @@ def sweep_callback(buffer: np.ndarray, buffer_length: int, valid_length: int) ->
199221

200222
def pyhackrf_sweep(frequencies: list = [0, 6000], lna_gain: int = 16, vga_gain: int = 20, bin_width: int = 100_000,
201223
serial_number: str = None, amp_enable: bool = False, antenna_enable: bool = False, sample_rate: int = 20_000_000,
202-
num_sweeps: int = None, binary_output: bool = False, one_shot: bool = False, filename: str = None,
224+
num_sweeps: int = None, binary_output: bool = False, one_shot: bool = False, filename: str = None, sweep_style: pyhackrf.py_sweep_style = pyhackrf.py_sweep_style.INTERLEAVED,
203225
print_to_console: bool = True, device: pyhackrf.PyHackrfDevice = None):
204226

205-
global fftSize, window, pwr_1_start, pwr_1_stop, pwr_2_start, pwr_2_stop, norm_factor, data_length, sample_rate_hz
227+
global fftSize, window, pwr_1_start, pwr_1_stop, pwr_2_start, pwr_2_stop, norm_factor, data_length, SAMPLE_RATE
206228
global start_frequency, sweep_count, sweep_started, max_num_sweeps, check_max_num_sweeps, accepted_bytes, one_shot_mode, run_available
207-
global binary_output_mode, file_object, callback
229+
global binary_output_mode, file_object, callback, SWEEP_STYLE
208230
global frequency_step_1, frequency_step_2, frequency_step_3
209231

232+
if sweep_style in pyhackrf.py_sweep_style:
233+
SWEEP_STYLE = sweep_style
234+
else:
235+
SWEEP_STYLE = pyhackrf.sweep_stylepyhackrf.py_sweep_style.INTERLEAVED
236+
210237
if sample_rate in AVAILABLE_SAMPLING_RATES:
211-
sample_rate_hz = sample_rate
238+
SAMPLE_RATE = sample_rate
212239
else:
213-
sample_rate_hz = 20_000_000
240+
SAMPLE_RATE = 20_000_000
214241

215242
frequency_step_1 = sample_rate // 4
216243
frequency_step_2 = sample_rate // 2
@@ -222,9 +249,9 @@ def pyhackrf_sweep(frequencies: list = [0, 6000], lna_gain: int = 16, vga_gain:
222249
accepted_bytes = 0
223250
sweep_started = False
224251

225-
BASEBAND_FILTER_BANDWIDTH = int(sample_rate_hz * BASEBAND_FILTER_BANDWIDTH_RATIO)
226-
OFFSET = int(sample_rate_hz * OFFSET_RATIO)
227-
TUNE_STEP = sample_rate_hz / 1e6
252+
BASEBAND_FILTER_BANDWIDTH = int(SAMPLE_RATE * BASEBAND_FILTER_BANDWIDTH_RATIO)
253+
OFFSET = int(SAMPLE_RATE * OFFSET_RATIO)
254+
TUNE_STEP = SAMPLE_RATE / 1e6
228255

229256
init_signals()
230257

@@ -249,8 +276,8 @@ def pyhackrf_sweep(frequencies: list = [0, 6000], lna_gain: int = 16, vga_gain:
249276
device.set_sweep_callback(sweep_callback)
250277

251278
if print_to_console:
252-
print(f'call pyhackrf_sample_rate_set({sample_rate_hz / 1e6 :.3f} MHz)', file=sys.stderr)
253-
device.pyhackrf_set_sample_rate_manual(sample_rate_hz, 1)
279+
print(f'call pyhackrf_sample_rate_set({SAMPLE_RATE / 1e6 :.3f} MHz)', file=sys.stderr)
280+
device.pyhackrf_set_sample_rate_manual(SAMPLE_RATE, 1)
254281

255282
if print_to_console:
256283
print(f'call pyhackrf_set_baseband_filter_bandwidth({BASEBAND_FILTER_BANDWIDTH / 1e6 :.3f} MHz)', file=sys.stderr)
@@ -283,15 +310,15 @@ def pyhackrf_sweep(frequencies: list = [0, 6000], lna_gain: int = 16, vga_gain:
283310

284311
start_frequency = int(frequencies[0] * 1e6)
285312

286-
fftSize = int(sample_rate_hz / bin_width)
313+
fftSize = int(SAMPLE_RATE / bin_width)
287314
while ((fftSize + 4) % 8):
288315
fftSize += 1
289316

290317
if fftSize < 4:
291-
raise RuntimeError(f'bin_width should be between no more than {sample_rate_hz // 4} Hz')
318+
raise RuntimeError(f'bin_width should be between no more than {SAMPLE_RATE // 4} Hz')
292319

293320
if fftSize > 8180:
294-
raise RuntimeError(f'bin_width should be between no less than {sample_rate_hz // 8180 + 1} Hz')
321+
raise RuntimeError(f'bin_width should be between no less than {SAMPLE_RATE // 8180 + 1} Hz')
295322

296323
pwr_1_start = 1 + (fftSize * 5) // 8
297324
pwr_1_stop = 1 + (fftSize * 5) // 8 + fftSize // 4
@@ -304,7 +331,7 @@ def pyhackrf_sweep(frequencies: list = [0, 6000], lna_gain: int = 16, vga_gain:
304331

305332
window = np.hanning(fftSize)
306333

307-
device.pyhackrf_init_sweep(frequencies, num_ranges, pyhackrf.PY_BYTES_PER_BLOCK, int(TUNE_STEP * 1e6), OFFSET, pyhackrf.py_sweep_style.INTERLEAVED)
334+
device.pyhackrf_init_sweep(frequencies, num_ranges, pyhackrf.PY_BYTES_PER_BLOCK, int(TUNE_STEP * 1e6), OFFSET, sweep_style)
308335

309336
if amp_enable:
310337
if print_to_console:

0 commit comments

Comments
 (0)