tsapython 2.0.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- tsapython/__init__.py +10 -0
- tsapython/core.py +2310 -0
- tsapython/py.typed +0 -0
- tsapython-2.0.0.dist-info/METADATA +84 -0
- tsapython-2.0.0.dist-info/RECORD +7 -0
- tsapython-2.0.0.dist-info/WHEEL +4 -0
- tsapython-2.0.0.dist-info/licenses/LICENSE +339 -0
tsapython/core.py
ADDED
|
@@ -0,0 +1,2310 @@
|
|
|
1
|
+
#! /usr/bin/python3
|
|
2
|
+
|
|
3
|
+
##------------------------------------------------------------------------------------------------\
|
|
4
|
+
# tinySA_python (tsapython)
|
|
5
|
+
# './src/tsapython/core.py'
|
|
6
|
+
# UNOFFICIAL Python API based on the tinySA official documentation at https://www.tinysa.org/wiki/
|
|
7
|
+
#
|
|
8
|
+
# references:
|
|
9
|
+
# https://tinysa.org/wiki/pmwiki.php?n=TinySA4.ConsoleCommands (NOTE: backwards compat not tested!)
|
|
10
|
+
# http://athome.kaashoek.com/tinySA/python/tinySA.py (existing library with some examples)
|
|
11
|
+
#
|
|
12
|
+
#
|
|
13
|
+
# This class was previously named tinySA_python. The rename is to cover the CORE device functionalities,
|
|
14
|
+
# with the device specifics being added as extra modules.
|
|
15
|
+
#
|
|
16
|
+
# Author(s): Lauren Linkous
|
|
17
|
+
# Last update: August 17, 2025
|
|
18
|
+
##--------------------------------------------------------------------------------------------------\
|
|
19
|
+
|
|
20
|
+
import serial
|
|
21
|
+
import serial.tools.list_ports # COM search method wants full path
|
|
22
|
+
import numpy as np
|
|
23
|
+
import re
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
class tinySA():
|
|
27
|
+
def __init__(self, parent=None):
|
|
28
|
+
# serial port
|
|
29
|
+
self.ser = None
|
|
30
|
+
|
|
31
|
+
# message feedback
|
|
32
|
+
self.verboseEnabled = False
|
|
33
|
+
self.returnErrorByte = False
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
# VARS BELOW HERE will be largely replaced with device class config calls
|
|
37
|
+
# # this will allow for user settings and device presets
|
|
38
|
+
|
|
39
|
+
# other overrides
|
|
40
|
+
self.ultraEnabled = False
|
|
41
|
+
self.abortEnabled = False
|
|
42
|
+
self.harmonicEnabled = False
|
|
43
|
+
|
|
44
|
+
#select device vars - hardcoding for the Ultra for now
|
|
45
|
+
# device params
|
|
46
|
+
self.maxPoints = 450
|
|
47
|
+
# spectrum analyzer
|
|
48
|
+
self.minSADeviceFreq = 100e3 #100 kHz
|
|
49
|
+
self.maxSADeviceFreq = 15e9 #5.3 GHz for normal operation, but 12 GHz for edge of harmonics.
|
|
50
|
+
# signal generator
|
|
51
|
+
self.minSGDeviceFreq = 100e3 #100 kHz
|
|
52
|
+
self.maxSGDeviceFreq = 960e6 #960 MHz
|
|
53
|
+
# battery
|
|
54
|
+
self.maxDeviceBattery = 4095
|
|
55
|
+
# screen
|
|
56
|
+
self.screenWidth = 480
|
|
57
|
+
self.screenHeight = 320
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
######################################################################
|
|
61
|
+
# Error and information printout
|
|
62
|
+
# set/get_verbose() - set how detailed the error printouts are
|
|
63
|
+
# print_message() - deal with the bool in one place
|
|
64
|
+
######################################################################
|
|
65
|
+
|
|
66
|
+
def set_verbose(self, verbose=False):
|
|
67
|
+
self.verboseEnabled = verbose
|
|
68
|
+
|
|
69
|
+
def get_verbose(self):
|
|
70
|
+
return self.verboseEnabled
|
|
71
|
+
|
|
72
|
+
def print_message(self, msg):
|
|
73
|
+
if self.verboseEnabled == True:
|
|
74
|
+
print(msg)
|
|
75
|
+
|
|
76
|
+
######################################################################
|
|
77
|
+
# Explicit error return
|
|
78
|
+
# set_error_byte_return() - set if explicit b'ERROR' is returned
|
|
79
|
+
# get_error_byte_return() - get the return mode True/False
|
|
80
|
+
# error_byte_return() - return 'ERROR' message or empty.
|
|
81
|
+
######################################################################
|
|
82
|
+
|
|
83
|
+
def set_error_byte_return(self, errByte=False):
|
|
84
|
+
self.returnErrorByte = errByte
|
|
85
|
+
|
|
86
|
+
def get_error_byte_return(self):
|
|
87
|
+
return self.returnErrorByte
|
|
88
|
+
|
|
89
|
+
def error_byte_return(self):
|
|
90
|
+
if self.returnErrorByte == True:
|
|
91
|
+
return bytearray(b'ERROR')
|
|
92
|
+
else:
|
|
93
|
+
return bytearray(b'') # the default
|
|
94
|
+
|
|
95
|
+
|
|
96
|
+
######################################################################
|
|
97
|
+
# Set Device Params
|
|
98
|
+
# Library specific functions. These set the boundaries & features for
|
|
99
|
+
# error checking in the library
|
|
100
|
+
#
|
|
101
|
+
# WARNING: these DO NOT change the settings on the DEVICE. just the library.
|
|
102
|
+
######################################################################
|
|
103
|
+
|
|
104
|
+
def select_existing_device(self, tinySAModel):
|
|
105
|
+
# uses pre-set config files.
|
|
106
|
+
# tinySAModel var must be one of the following:
|
|
107
|
+
# "BASIC", "ZS405", "ZS406", "ZS407"
|
|
108
|
+
try:
|
|
109
|
+
noErrors = self.dev.select_preset_model(tinySAModel)
|
|
110
|
+
if noErrors == False:
|
|
111
|
+
print("ERROR: device configuration unable to be set.This feature is underdevelopment")
|
|
112
|
+
return
|
|
113
|
+
|
|
114
|
+
# set variables from device configs.
|
|
115
|
+
# these are placeholders tes for now
|
|
116
|
+
# device params
|
|
117
|
+
self.maxPoints = 450
|
|
118
|
+
# spectrum analyzer
|
|
119
|
+
self.minSADeviceFreq = 100e3 #100 kHz
|
|
120
|
+
self.maxSADeviceFreq = 12e9 #5.3 GHz for normal operation, but 12 GHz for edge of harmonics
|
|
121
|
+
# signal generator
|
|
122
|
+
self.minSGDeviceFreq = 100e3 #100 kHz
|
|
123
|
+
self.maxSGDeviceFreq = 960e6 #960 MHz
|
|
124
|
+
# battery
|
|
125
|
+
self.maxDeviceBattery = 4095
|
|
126
|
+
# screen
|
|
127
|
+
self.screenWidth = 480
|
|
128
|
+
self.screenHeight = 320
|
|
129
|
+
|
|
130
|
+
|
|
131
|
+
except:
|
|
132
|
+
print("ERROR: device configuration unable to be set.This feature is underdevelopment")
|
|
133
|
+
|
|
134
|
+
def load_custom_config(self, configFile):
|
|
135
|
+
# TODO: for loading modified or other devices working on the same firmware
|
|
136
|
+
pass
|
|
137
|
+
|
|
138
|
+
|
|
139
|
+
|
|
140
|
+
######################################################################
|
|
141
|
+
# Direct overrides
|
|
142
|
+
# These are used during DEBUG or when device state/model is already known
|
|
143
|
+
# Not recommended unless you are sure of the device state
|
|
144
|
+
# and which settings each device has
|
|
145
|
+
# WARNING: these DO NOT change the settings on the DEVICE. just the library.
|
|
146
|
+
######################################################################
|
|
147
|
+
|
|
148
|
+
# error check bools
|
|
149
|
+
def set_ultra_mode(self, ultraMode=False):
|
|
150
|
+
self.ultraEnabled = ultraMode
|
|
151
|
+
|
|
152
|
+
def set_abort_mode(self, abortMode=False):
|
|
153
|
+
self.abortEnabled = abortMode
|
|
154
|
+
|
|
155
|
+
def set_harmonic_mode(self, harmonicMode=False):
|
|
156
|
+
self.harmonicEnabled = harmonicMode
|
|
157
|
+
|
|
158
|
+
# error check boundaries
|
|
159
|
+
## signal analyzer specific
|
|
160
|
+
def set_min_SA_freq(self, f):
|
|
161
|
+
self.minSADeviceFreq = float(f)
|
|
162
|
+
|
|
163
|
+
def get_min_SA_freq(self):
|
|
164
|
+
return self.minSADeviceFreq
|
|
165
|
+
|
|
166
|
+
def set_max_SA_freq(self, f):
|
|
167
|
+
self.maxSADeviceFreq = float(f)
|
|
168
|
+
|
|
169
|
+
def get_max_SA_freq(self):
|
|
170
|
+
return self.maxSADeviceFreq
|
|
171
|
+
|
|
172
|
+
## signal generator specific
|
|
173
|
+
def set_min_SG_freq(self, f):
|
|
174
|
+
self.minSGDeviceFreq = float(f)
|
|
175
|
+
|
|
176
|
+
def get_min_SG_freq(self):
|
|
177
|
+
return self.minSGDeviceFreq
|
|
178
|
+
|
|
179
|
+
def set_max_SG_freq(self, f):
|
|
180
|
+
self.maxSGDeviceFreq = float(f)
|
|
181
|
+
|
|
182
|
+
def get_max_SG_freq(self):
|
|
183
|
+
return self.maxSGDeviceFreq
|
|
184
|
+
|
|
185
|
+
|
|
186
|
+
|
|
187
|
+
######################################################################
|
|
188
|
+
# Serial management and message processing
|
|
189
|
+
######################################################################
|
|
190
|
+
|
|
191
|
+
def autoconnect(self, timeout=1):
|
|
192
|
+
# attempt to autoconnect to a detected port.
|
|
193
|
+
# returns: found_bool, connected_bool
|
|
194
|
+
# True if successful, False otherwise
|
|
195
|
+
|
|
196
|
+
# List all available serial ports
|
|
197
|
+
ports = serial.tools.list_ports.comports()
|
|
198
|
+
# loop through the ports and print out info
|
|
199
|
+
for port_info in ports:
|
|
200
|
+
|
|
201
|
+
# print out which port we're trying
|
|
202
|
+
port = port_info.device
|
|
203
|
+
self.print_message(f"Checking port: {port}")
|
|
204
|
+
vid = port_info.vid
|
|
205
|
+
pid = port_info.pid
|
|
206
|
+
|
|
207
|
+
# check if it's a tinySA or nanoVNA:
|
|
208
|
+
if (vid==None):
|
|
209
|
+
pass
|
|
210
|
+
elif (hex(vid) == '0x483') and (hex(pid)=='0x5740'):
|
|
211
|
+
self.print_message(f"tinySA device identified at port: {port}")
|
|
212
|
+
connected_bool = self.connect(port, timeout)
|
|
213
|
+
|
|
214
|
+
return True, connected_bool
|
|
215
|
+
|
|
216
|
+
|
|
217
|
+
return False, False # no tinySA found, not connected
|
|
218
|
+
|
|
219
|
+
|
|
220
|
+
def connect(self, port, timeout=1):
|
|
221
|
+
# attempt connection to provided port.
|
|
222
|
+
# returns: True if successful, False otherwise
|
|
223
|
+
|
|
224
|
+
try:
|
|
225
|
+
self.ser = serial.Serial(port=port, timeout=timeout)
|
|
226
|
+
return True
|
|
227
|
+
except Exception as err:
|
|
228
|
+
self.print_message("ERROR: cannot open port at " + str(port))
|
|
229
|
+
self.print_message(err)
|
|
230
|
+
return False
|
|
231
|
+
|
|
232
|
+
def disconnect(self):
|
|
233
|
+
# closes the serial port
|
|
234
|
+
self.ser.close()
|
|
235
|
+
|
|
236
|
+
|
|
237
|
+
def tinySA_serial(self, writebyte, printBool=False, pts=None):
|
|
238
|
+
# write out to serial, get message back, clean up, return
|
|
239
|
+
|
|
240
|
+
# clear INPUT buffer
|
|
241
|
+
self.ser.reset_input_buffer()
|
|
242
|
+
# clear OUTPUT buffer
|
|
243
|
+
self.ser.reset_output_buffer()
|
|
244
|
+
|
|
245
|
+
|
|
246
|
+
self.ser.write(bytes(writebyte, 'utf-8'))
|
|
247
|
+
msgbytes = self.get_serial_return()
|
|
248
|
+
msgbytes = self.clean_return(msgbytes)
|
|
249
|
+
|
|
250
|
+
if printBool == True:
|
|
251
|
+
print(msgbytes) #overrides verbose for debug
|
|
252
|
+
|
|
253
|
+
return msgbytes
|
|
254
|
+
|
|
255
|
+
|
|
256
|
+
def get_serial_return(self):
|
|
257
|
+
# while there's a buffer, read in the returned message
|
|
258
|
+
# original buffer reading from: https://groups.io/g/tinysa/topic/tinysa_screen_capture_using/82218670
|
|
259
|
+
|
|
260
|
+
buffer = bytes()
|
|
261
|
+
while True:
|
|
262
|
+
if self.ser.in_waiting > 0:
|
|
263
|
+
buffer += self.ser.read(self.ser.in_waiting)
|
|
264
|
+
try:
|
|
265
|
+
# split the stream to take a chunk at a time
|
|
266
|
+
# get up to '>' of the prompt
|
|
267
|
+
complete = buffer[:buffer.index(b'>')+1]
|
|
268
|
+
# leave the rest in buffer
|
|
269
|
+
buffer = buffer[buffer.index(b'ch>')+1:]
|
|
270
|
+
except ValueError:
|
|
271
|
+
# this is an acceptable err, so can skip it and keep looping
|
|
272
|
+
continue
|
|
273
|
+
except Exception as err:
|
|
274
|
+
# otherwise, something else is wrong
|
|
275
|
+
self.print_message("ERROR: exception thrown while reading serial")
|
|
276
|
+
self.print_message(err)
|
|
277
|
+
return None
|
|
278
|
+
break
|
|
279
|
+
|
|
280
|
+
return bytearray(complete)
|
|
281
|
+
|
|
282
|
+
|
|
283
|
+
def read_until_end_marker(self, end_marker=b'}', timeout=10.0):
|
|
284
|
+
# scan and scan raw might return early with tinySA_serial
|
|
285
|
+
# so this is written to
|
|
286
|
+
import time
|
|
287
|
+
|
|
288
|
+
buffer = bytes()
|
|
289
|
+
start_time = time.time()
|
|
290
|
+
|
|
291
|
+
while True:
|
|
292
|
+
if self.ser.in_waiting > 0:
|
|
293
|
+
buffer += self.ser.read(self.ser.in_waiting)
|
|
294
|
+
|
|
295
|
+
# Check if we have the end marker
|
|
296
|
+
if end_marker in buffer:
|
|
297
|
+
# Find the position after the end marker
|
|
298
|
+
end_pos = buffer.find(end_marker) + len(end_marker)
|
|
299
|
+
complete = buffer[:end_pos]
|
|
300
|
+
# Keep any remaining data for next read
|
|
301
|
+
self.remaining_buffer = buffer[end_pos:]
|
|
302
|
+
return bytearray(complete)
|
|
303
|
+
|
|
304
|
+
# Timeout check
|
|
305
|
+
if time.time() - start_time > timeout:
|
|
306
|
+
self.print_message(f"WARNING: Timeout waiting for end marker {end_marker}")
|
|
307
|
+
break
|
|
308
|
+
|
|
309
|
+
time.sleep(0.01)
|
|
310
|
+
|
|
311
|
+
return bytearray(buffer)
|
|
312
|
+
|
|
313
|
+
def clean_return(self, data):
|
|
314
|
+
# takes in a bytearray and removes 1) the text up to the first '\r\n' (includes the command), an 2) the ending 'ch>'
|
|
315
|
+
# Find the first occurrence of \r\n (carriage return + newline)
|
|
316
|
+
first_newline_index = data.find(b'\r\n')
|
|
317
|
+
if first_newline_index != -1:
|
|
318
|
+
# Slice the bytearray to remove everything before and including the first '\r\n'
|
|
319
|
+
data = data[first_newline_index + 2:] # Skip past '\r\n'
|
|
320
|
+
# Check if the message ends with 'ch>'
|
|
321
|
+
if data.endswith(b'ch>'):
|
|
322
|
+
# Remove 'ch>' from the end
|
|
323
|
+
data = data[:-4] # Remove the last 4 bytes ('ch>')
|
|
324
|
+
return data
|
|
325
|
+
|
|
326
|
+
######################################################################
|
|
327
|
+
# Reusable format checking functions
|
|
328
|
+
######################################################################
|
|
329
|
+
|
|
330
|
+
def convert_frequency(self, txtstr):
|
|
331
|
+
# this takes the user input (as text) and converts it.
|
|
332
|
+
# From documentation:
|
|
333
|
+
# Frequencies can be specified using an integer optionally postfixed with a the letter
|
|
334
|
+
# 'k' for kilo 'M' for Mega or 'G' for Giga. E.g. 0.1M (100kHz), 500k (0.5MHz) or 12000000 (12MHz)
|
|
335
|
+
# However the abbreviation makes error checking with numerics more difficult. so convert everything to Hz.
|
|
336
|
+
# e notation is fine
|
|
337
|
+
pass
|
|
338
|
+
|
|
339
|
+
def convert_time(self, txtstr):
|
|
340
|
+
# this takes the user input (as text) and converts it.
|
|
341
|
+
# From documentation:
|
|
342
|
+
# Time is specified in seconds optionally postfixed with the letters 'm' for mili
|
|
343
|
+
# or 'u' for micro. E.g. 1 (1 second), 2.5 (2.5 seconds), 120m (120 milliseconds)
|
|
344
|
+
|
|
345
|
+
|
|
346
|
+
|
|
347
|
+
pass
|
|
348
|
+
|
|
349
|
+
|
|
350
|
+
def is_rgb24(self, hexStr):
|
|
351
|
+
# check if the string matches the pattern 0xRRGGBB
|
|
352
|
+
pattern = r"^0x[0-9A-Fa-f]{6}$"
|
|
353
|
+
return bool(re.match(pattern, hexStr))
|
|
354
|
+
|
|
355
|
+
|
|
356
|
+
######################################################################
|
|
357
|
+
# Serial command config, input error checking
|
|
358
|
+
######################################################################
|
|
359
|
+
|
|
360
|
+
def abort(self, val=None):
|
|
361
|
+
# Sets the abort enabled status (on/off)
|
|
362
|
+
# usage: abort [off|on]
|
|
363
|
+
# example return: bytearray(b'')
|
|
364
|
+
|
|
365
|
+
# #explicitly allowed vals
|
|
366
|
+
accepted_vals = ["off", "on"]
|
|
367
|
+
|
|
368
|
+
#check input
|
|
369
|
+
if (str(val) in accepted_vals): #toggle state
|
|
370
|
+
writebyte = 'abort '+str(val)+'\r\n'
|
|
371
|
+
msgbytes = self.tinySA_serial(writebyte, printBool=False)
|
|
372
|
+
if val == "on":
|
|
373
|
+
self.print_message("ABORT option ENABLED")
|
|
374
|
+
self.abortEnabled = True
|
|
375
|
+
elif val == "off":
|
|
376
|
+
self.print_message("ABORT option DISABLED")
|
|
377
|
+
self.abortEnabled = False
|
|
378
|
+
elif val == None: #action
|
|
379
|
+
if self.abortEnabled == True:
|
|
380
|
+
writebyte = 'abort\r\n'
|
|
381
|
+
msgbytes = self.tinySA_serial(writebyte, printBool=False)
|
|
382
|
+
else:
|
|
383
|
+
self.print_message("ABORT option must be ENABLED before use")
|
|
384
|
+
msgbytes = bytearray(b'')
|
|
385
|
+
else:
|
|
386
|
+
self.print_message("ERROR: abort() takes NONE|\"off\"|\"on\" as arguments")
|
|
387
|
+
msgbytes = bytearray(b'')
|
|
388
|
+
return msgbytes
|
|
389
|
+
|
|
390
|
+
def enable_abort(self):
|
|
391
|
+
# alias for abort()
|
|
392
|
+
return self.abort( "on")
|
|
393
|
+
def disable_abort(self):
|
|
394
|
+
# alias for abort()
|
|
395
|
+
return self.abort("off")
|
|
396
|
+
def abort_action(self):
|
|
397
|
+
# alias for abort()
|
|
398
|
+
return self.abort()
|
|
399
|
+
|
|
400
|
+
def actual_freq(self, val=None):
|
|
401
|
+
# Sets or gets the frequency correction set by CORRECT FREQUENCY menu in the expert menu settings
|
|
402
|
+
# related to freq_corr
|
|
403
|
+
# usage: actual_freq [{frequency}]
|
|
404
|
+
# example return: bytearray(b'3000000000\r')
|
|
405
|
+
|
|
406
|
+
if val == None:
|
|
407
|
+
#get the dac
|
|
408
|
+
writebyte = 'actual_freq\r\n'
|
|
409
|
+
msgbytes = self.tinySA_serial(writebyte, printBool=False)
|
|
410
|
+
elif (isinstance(val, (int, float))) and (self.minSADeviceFreq <= val <=self.maxSADeviceFreq ):
|
|
411
|
+
writebyte = 'actual_freq '+str(val)+'\r\n'
|
|
412
|
+
msgbytes = self.tinySA_serial(writebyte, printBool=False)
|
|
413
|
+
self.print_message("actual_freq set to " + str(val))
|
|
414
|
+
else:
|
|
415
|
+
self.print_message("ERROR: actual_freq() takes either None or integers")
|
|
416
|
+
msgbytes = self.error_byte_return()
|
|
417
|
+
return msgbytes
|
|
418
|
+
|
|
419
|
+
def set_actual_freq(self, val):
|
|
420
|
+
# alias for actual_freq()
|
|
421
|
+
return self.actual_freq(val)
|
|
422
|
+
def get_actual_freq(self):
|
|
423
|
+
# alias for actual_freq()
|
|
424
|
+
return self.actual_freq(None)
|
|
425
|
+
|
|
426
|
+
|
|
427
|
+
def agc(self, val='auto'):
|
|
428
|
+
# Enables/disables the build in Automatic Gain Control
|
|
429
|
+
# usage: agc 0..7|auto
|
|
430
|
+
# example return: bytearray(b'')
|
|
431
|
+
|
|
432
|
+
#explicitly allowed vals
|
|
433
|
+
accepted_vals = np.arange(0, 8, 1) # max exclusive
|
|
434
|
+
#check input
|
|
435
|
+
if (str(val) == "auto") or (val in accepted_vals):
|
|
436
|
+
writebyte = 'agc '+str(val)+'\r\n'
|
|
437
|
+
msgbytes = self.tinySA_serial(writebyte, printBool=False)
|
|
438
|
+
self.print_message("agc() set with " + str(val))
|
|
439
|
+
else:
|
|
440
|
+
self.print_message("ERROR: agc() takes vals [0 - 7]|\"auto\"")
|
|
441
|
+
msgbytes = self.error_byte_return()
|
|
442
|
+
return msgbytes
|
|
443
|
+
|
|
444
|
+
def set_agc(self, val):
|
|
445
|
+
# alias for agc()
|
|
446
|
+
return self.agc(val)
|
|
447
|
+
|
|
448
|
+
def attenuate(self, val='auto'):
|
|
449
|
+
# sets the internal attenuation to automatic or a specific value
|
|
450
|
+
# usage: attenuate [auto|0-31]
|
|
451
|
+
# example return: bytearray(b'')
|
|
452
|
+
|
|
453
|
+
#explicitly allowed vals
|
|
454
|
+
accepted_vals = np.arange(0, 31, 1) # max exclusive
|
|
455
|
+
#check input
|
|
456
|
+
if (str(val) == "auto") or (val in accepted_vals):
|
|
457
|
+
writebyte = 'attenuate '+str(val)+'\r\n'
|
|
458
|
+
msgbytes = self.tinySA_serial(writebyte, printBool=False)
|
|
459
|
+
self.print_message("attenuate() set with " + str(val))
|
|
460
|
+
else:
|
|
461
|
+
self.print_message("ERROR: attenuate() takes vals [0 - 31]|\"auto\"")
|
|
462
|
+
msgbytes = self.error_byte_return()
|
|
463
|
+
return msgbytes
|
|
464
|
+
|
|
465
|
+
def set_attenuation(self, val):
|
|
466
|
+
# alias for attenuate()
|
|
467
|
+
return self.attenuate(val)
|
|
468
|
+
|
|
469
|
+
def bulk(self):
|
|
470
|
+
# sent by tinySA when in auto refresh mode
|
|
471
|
+
# format: "bulk\r\n{X}{Y}{Width}{Height}
|
|
472
|
+
# {Pixeldata}\r\n"
|
|
473
|
+
# where all numbers are binary coded 2
|
|
474
|
+
# bytes little endian. The Pixeldata is
|
|
475
|
+
# encoded as 2 bytes per pixel. similar to fill()
|
|
476
|
+
|
|
477
|
+
writebyte = 'bulk\r\n'
|
|
478
|
+
msgbytes = self.tinySA_serial(writebyte, printBool=False)
|
|
479
|
+
self.print_message("bulk() called for screen data")
|
|
480
|
+
return msgbytes
|
|
481
|
+
|
|
482
|
+
def get_bulk_data(self):
|
|
483
|
+
# alias for bulk()
|
|
484
|
+
return self.bulk()
|
|
485
|
+
|
|
486
|
+
def calc(self, val="off"):
|
|
487
|
+
# sets or cancels one of the measurement modes
|
|
488
|
+
# the commands are the same as those listed
|
|
489
|
+
# in the MEASURE menu
|
|
490
|
+
# usage: calc off|minh|maxh|maxd|aver4|aver16|quasip
|
|
491
|
+
# example return:
|
|
492
|
+
|
|
493
|
+
#explicitly allowed vals
|
|
494
|
+
accepted_vals = ["off", "minh", "maxh", "maxd",
|
|
495
|
+
"aver4", "aver16", "quasip"]
|
|
496
|
+
#check input
|
|
497
|
+
if (str(val) in accepted_vals):
|
|
498
|
+
writebyte = 'calc '+str(val)+'\r\n'
|
|
499
|
+
msgbytes = self.tinySA_serial(writebyte, printBool=False)
|
|
500
|
+
self.print_message("calc() set with " + str(val))
|
|
501
|
+
else:
|
|
502
|
+
self.print_message("ERROR: calc() takes vals \"off\"|\"minh\"|\"maxh\"|\"maxd\"|\"aver4\"|\"aver16\"|\"quasip\"")
|
|
503
|
+
msgbytes = self.error_byte_return()
|
|
504
|
+
return msgbytes
|
|
505
|
+
|
|
506
|
+
def set_calc_off(self):
|
|
507
|
+
return self.calc("off")
|
|
508
|
+
def set_calc_minh(self):
|
|
509
|
+
return self.calc("minh")
|
|
510
|
+
def set_calc_maxh(self):
|
|
511
|
+
return self.calc("maxh")
|
|
512
|
+
def set_calc_maxd(self):
|
|
513
|
+
return self.calc("maxd")
|
|
514
|
+
def set_calc_aver4(self):
|
|
515
|
+
return self.calc("aver4")
|
|
516
|
+
def set_calc_aver16(self):
|
|
517
|
+
return self.calc("aver16")
|
|
518
|
+
def set_calc_quasip(self):
|
|
519
|
+
return self.calc("quasip")
|
|
520
|
+
|
|
521
|
+
def cal_output(self, val="off"):
|
|
522
|
+
# disables or sets the caloutput to a specified frequency in MHz
|
|
523
|
+
# usage: caloutput off|30|15|10|4|3|2|1
|
|
524
|
+
# example return: bytearray(b'')
|
|
525
|
+
|
|
526
|
+
#explicitly allowed vals
|
|
527
|
+
accepted_vals = ["off", 'off', 1,2,3,4,10,15,30]
|
|
528
|
+
#check input
|
|
529
|
+
if (val in accepted_vals):
|
|
530
|
+
writebyte = 'caloutput '+str(val)+'\r\n'
|
|
531
|
+
msgbytes = self.tinySA_serial(writebyte, printBool=False)
|
|
532
|
+
self.print_message("caloutput() set with " + str(val))
|
|
533
|
+
else:
|
|
534
|
+
self.print_message("ERROR: caloutput() takes vals 1|2|3|4|10|15|30|\"off\"")
|
|
535
|
+
msgbytes = self.error_byte_return()
|
|
536
|
+
return msgbytes
|
|
537
|
+
|
|
538
|
+
def set_cal_output_off(self):
|
|
539
|
+
# alias for cal_output()
|
|
540
|
+
return self.caloutput("off")
|
|
541
|
+
def set_cal_output_30(self):
|
|
542
|
+
# alias for cal_output()
|
|
543
|
+
return self.caloutput(30)
|
|
544
|
+
def set_cal_output_15(self):
|
|
545
|
+
# alias for cal_output()
|
|
546
|
+
return self.caloutput(15)
|
|
547
|
+
def set_cal_output_10(self):
|
|
548
|
+
# alias for cal_output()
|
|
549
|
+
return self.caloutput(10)
|
|
550
|
+
def set_cal_output_4(self):
|
|
551
|
+
# alias for cal_output()
|
|
552
|
+
return self.caloutput(4)
|
|
553
|
+
def set_cal_output_3(self):
|
|
554
|
+
# alias for cal_output()
|
|
555
|
+
return self.caloutput(3)
|
|
556
|
+
def set_cal_output_2(self):
|
|
557
|
+
# alias for cal_output()
|
|
558
|
+
return self.caloutput(2)
|
|
559
|
+
def set_cal_output_1(self):
|
|
560
|
+
# alias for cal_output()
|
|
561
|
+
return self.caloutput(1)
|
|
562
|
+
|
|
563
|
+
|
|
564
|
+
def capture(self):
|
|
565
|
+
# requests a screen dump to be sent in binary format
|
|
566
|
+
# of 320x240 pixels of each 2 bytes
|
|
567
|
+
# usage: capture
|
|
568
|
+
# example return: bytearray(b'\x00 ...\x00\x00\x00')
|
|
569
|
+
writebyte = 'capture\r\n'
|
|
570
|
+
msgbytes = self.tinySA_serial(writebyte, printBool=False)
|
|
571
|
+
self.print_message("capture() called for screen data")
|
|
572
|
+
return msgbytes
|
|
573
|
+
|
|
574
|
+
def capture_screen(self):
|
|
575
|
+
return self.capture()
|
|
576
|
+
|
|
577
|
+
def clear_config(self):
|
|
578
|
+
# resets the configuration data to factory defaults. requires password
|
|
579
|
+
# NOTE: does take other commands to fully clear all
|
|
580
|
+
# usage: clearconfig 1234
|
|
581
|
+
# example return: bytearray(b'Config and all cal data cleared.
|
|
582
|
+
# \r\nDo reset manually to take effect.
|
|
583
|
+
# Then do touch cal and save.\r')
|
|
584
|
+
writebyte = 'clearconfig 1234\r\n'
|
|
585
|
+
msgbytes = self.tinySA_serial(writebyte, printBool=False)
|
|
586
|
+
self.print_message("clear_config() with password. Config and all cal data cleared. \
|
|
587
|
+
Reset manually to take effect.")
|
|
588
|
+
return msgbytes
|
|
589
|
+
|
|
590
|
+
def clear_and_reset(self):
|
|
591
|
+
# alias function for full clear and reset process
|
|
592
|
+
self.clear_config()
|
|
593
|
+
self.reset()
|
|
594
|
+
|
|
595
|
+
def color(self, ID=None, RGB='0xF8FCF8'):
|
|
596
|
+
# sets or dumps the colors used
|
|
597
|
+
# usage: color [{id} {rgb24}]
|
|
598
|
+
# example return:
|
|
599
|
+
|
|
600
|
+
# explicitly allowed vals
|
|
601
|
+
accepted_ID = np.arange(0, 31, 1) # max exclusive
|
|
602
|
+
|
|
603
|
+
if ID == None:
|
|
604
|
+
# get the color
|
|
605
|
+
writebyte = 'color\r\n'
|
|
606
|
+
msgbytes = self.tinySA_serial(writebyte, printBool=False)
|
|
607
|
+
elif (ID in accepted_ID) and (self.is_rgb24(RGB)==True):
|
|
608
|
+
# set the color based on ID
|
|
609
|
+
writebyte = 'color ' + str(ID) + ' ' + str(RGB) + '\r\n'
|
|
610
|
+
msgbytes = self.tinySA_serial(writebyte, printBool=False)
|
|
611
|
+
self.print_message("color() set with ID: " +str(ID) + " RGB: " + str(RGB))
|
|
612
|
+
else:
|
|
613
|
+
self.print_message("ERROR: color() takes either None, or ID as int 0..31 and RGB as a hex value")
|
|
614
|
+
msgbytes = self.error_byte_return()
|
|
615
|
+
return msgbytes
|
|
616
|
+
|
|
617
|
+
def get_all_colors(self):
|
|
618
|
+
# alias for color(). returns array of all colors
|
|
619
|
+
return self.color()
|
|
620
|
+
|
|
621
|
+
def get_color(self, ID):
|
|
622
|
+
# alias for color(). val must be int 1-31
|
|
623
|
+
msgbytes = self.color()
|
|
624
|
+
# check if something has been returned, otherwise pass the error through
|
|
625
|
+
if len(msgbytes) > 10:
|
|
626
|
+
# Use regex to find the value at index ID
|
|
627
|
+
pattern = rf'\b{int(ID)}:\s*0x([0-9A-Fa-f]+)'
|
|
628
|
+
match = re.search(pattern, msgbytes)
|
|
629
|
+
if match:
|
|
630
|
+
return f"0x{match.group(1)}" #return rgb24 value if found
|
|
631
|
+
|
|
632
|
+
# if not found, then
|
|
633
|
+
self.print_message("ERROR: color() takes either None, or ID as int 0..31 and RGB as a hex value")
|
|
634
|
+
msgbytes = self.error_byte_return()
|
|
635
|
+
return msgbytes
|
|
636
|
+
|
|
637
|
+
def set_color(self, ID, val):
|
|
638
|
+
# alias for color()
|
|
639
|
+
return self.color(ID, val)
|
|
640
|
+
|
|
641
|
+
|
|
642
|
+
def command(self, val):
|
|
643
|
+
# if the command isn't already a function,
|
|
644
|
+
# use existing func setup to send command
|
|
645
|
+
writebyte = str(val) + '\r\n'
|
|
646
|
+
msgbytes = self.tinySA_serial(writebyte, printBool=False)
|
|
647
|
+
self.print_message("command() called with ::" + str(val))
|
|
648
|
+
return msgbytes
|
|
649
|
+
|
|
650
|
+
|
|
651
|
+
def correction(self, argName="low", slot=None, freq=None, val=None):
|
|
652
|
+
# sets or dumps the frequency level orrection table
|
|
653
|
+
# usage: correction [0..9 {frequency} {level dB}]
|
|
654
|
+
# usage: correction low|lna|ultra|ultra_lna|direct|direct_lna|harm|harm_lna|out|out_direct|out_adf|out_ultra|off|on 0-19 frequency(Hz) value(dB)
|
|
655
|
+
# example return:
|
|
656
|
+
|
|
657
|
+
# explicitly allowed vals
|
|
658
|
+
accepted_table_args = ["low", "lna", "ultra", "ultra_lna",
|
|
659
|
+
"direct", "direct_lna", "harm",
|
|
660
|
+
"harm_lna", "out", "out_direct",
|
|
661
|
+
"out_adf", "out_ultra", "off", "on"]
|
|
662
|
+
|
|
663
|
+
accepted_slots = np.arange(0, 20, 1) # max exclusive.
|
|
664
|
+
|
|
665
|
+
if (argName in accepted_table_args) and (slot==None):
|
|
666
|
+
# prints out the table as it currently is
|
|
667
|
+
writebyte = 'correction ' + str(argName)+ '\r\n'
|
|
668
|
+
msgbytes = self.tinySA_serial(writebyte, printBool=False)
|
|
669
|
+
else:
|
|
670
|
+
# check error conditions quickly since there's 4
|
|
671
|
+
if not(argName in accepted_table_args):
|
|
672
|
+
self.print_message("ERROR: correction() requires a table indicator. see documentation")
|
|
673
|
+
msgbytes = self.error_byte_return()
|
|
674
|
+
return msgbytes
|
|
675
|
+
if not(slot in accepted_slots):
|
|
676
|
+
self.print_message("ERROR: correction() requires a slot from ["+ str(accepted_slots) + "]. see documentation")
|
|
677
|
+
msgbytes = self.error_byte_return()
|
|
678
|
+
return msgbytes
|
|
679
|
+
if not(self.minSADeviceFreq<=freq) and not(freq<=self.maxSADeviceFreq):
|
|
680
|
+
self.print_message("ERROR: correction() frequency outside of device specs. see documentation")
|
|
681
|
+
msgbytes = self.error_byte_return()
|
|
682
|
+
return msgbytes
|
|
683
|
+
if not(-10<=val) and not(val<=35):
|
|
684
|
+
self.print_message("ERROR: correction() val dB outside of specs. see documentation")
|
|
685
|
+
msgbytes = self.error_byte_return()
|
|
686
|
+
return msgbytes
|
|
687
|
+
writebyte = 'correction ' + str(argName) + ' ' + str(slot) +\
|
|
688
|
+
' ' + str(freq) + ' ' + str(val) + '\r\n'
|
|
689
|
+
msgbytes = self.tinySA_serial(writebyte, printBool=False)
|
|
690
|
+
self.print_message("correction() set with " + str(argName) + " " + str(slot) +\
|
|
691
|
+
" " + str(freq) + " " + str(val))
|
|
692
|
+
return msgbytes
|
|
693
|
+
|
|
694
|
+
|
|
695
|
+
#TODO ADD the CORRECTION setter shortcuts here.
|
|
696
|
+
|
|
697
|
+
|
|
698
|
+
def dac(self, val=None):
|
|
699
|
+
# sets or dumps the dac value
|
|
700
|
+
# usage: dac [0..4095]
|
|
701
|
+
# example return: bytearray(b'usage: dac {value(0-4095)}\r\ncurrent value: 1922\r')
|
|
702
|
+
|
|
703
|
+
if val == None:
|
|
704
|
+
#get the dac
|
|
705
|
+
writebyte = 'dac\r\n'
|
|
706
|
+
msgbytes = self.tinySA_serial(writebyte, printBool=False)
|
|
707
|
+
elif (isinstance(val, (int, float))) and (0<= val <=4095):
|
|
708
|
+
writebyte = 'dac '+str(val)+'\r\n'
|
|
709
|
+
msgbytes = self.tinySA_serial(writebyte, printBool=False)
|
|
710
|
+
self.print_message("dac set to " + str(val))
|
|
711
|
+
else:
|
|
712
|
+
self.print_message("ERROR: dac() takes either None or integers")
|
|
713
|
+
msgbytes = self.error_byte_return()
|
|
714
|
+
return msgbytes
|
|
715
|
+
|
|
716
|
+
def set_dac(self, val):
|
|
717
|
+
# alias for dac()
|
|
718
|
+
return self.dac(val)
|
|
719
|
+
def get_dac(self):
|
|
720
|
+
# alias for dac()
|
|
721
|
+
return self.dac()
|
|
722
|
+
|
|
723
|
+
|
|
724
|
+
|
|
725
|
+
def data(self, val=0):
|
|
726
|
+
# dumps the trace data.
|
|
727
|
+
# usage: data [0-2]
|
|
728
|
+
# 0=temp value, 1=stored trace, 2=measurement
|
|
729
|
+
# example return: bytearray(b'-8.671875e+01\r\n... -8.337500e+01\r\n-8.237500e+01\r')
|
|
730
|
+
|
|
731
|
+
#explicitly allowed vals
|
|
732
|
+
accepted_vals = [0,1,2]
|
|
733
|
+
#check input
|
|
734
|
+
if val in accepted_vals:
|
|
735
|
+
writebyte = 'data '+str(val)+'\r\n'
|
|
736
|
+
msgbytes = self.tinySA_serial(writebyte, printBool=False)
|
|
737
|
+
if val == 0:
|
|
738
|
+
self.print_message("returning temp value data")
|
|
739
|
+
elif val == 1:
|
|
740
|
+
self.print_message("returning stored trace data")
|
|
741
|
+
elif val == 2:
|
|
742
|
+
self.print_message("returning measurement data")
|
|
743
|
+
else:
|
|
744
|
+
self.print_message("ERROR: data() takes vals [0-2]")
|
|
745
|
+
msgbytes = self.error_byte_return()
|
|
746
|
+
return msgbytes
|
|
747
|
+
|
|
748
|
+
def get_temporary_data(self):
|
|
749
|
+
# alias func for data()
|
|
750
|
+
return self.data(val=0)
|
|
751
|
+
def get_stored_trace_data(self):
|
|
752
|
+
# alias func for data()
|
|
753
|
+
return self.data(val=1)
|
|
754
|
+
def dump_measurement_data(self):
|
|
755
|
+
# alias func for data()
|
|
756
|
+
return self.data(val=2)
|
|
757
|
+
|
|
758
|
+
|
|
759
|
+
def device_id(self, ID=None):
|
|
760
|
+
# sets or dumps a user settable number that can be used to identify a specific tinySA
|
|
761
|
+
# usage: deviceid [{number}]
|
|
762
|
+
# example return: bytearray(b'deviceid 12\r')
|
|
763
|
+
|
|
764
|
+
if ID == None:
|
|
765
|
+
#get the device ID
|
|
766
|
+
writebyte = 'deviceid\r\n'
|
|
767
|
+
msgbytes = self.tinySA_serial(writebyte, printBool=False)
|
|
768
|
+
elif isinstance(ID, int):
|
|
769
|
+
writebyte = 'deviceid '+str(ID)+'\r\n'
|
|
770
|
+
msgbytes = self.tinySA_serial(writebyte, printBool=False)
|
|
771
|
+
self.print_message("device ID set to " + str(ID))
|
|
772
|
+
else:
|
|
773
|
+
self.print_message("ERROR: device_id() takes either None or integers")
|
|
774
|
+
msgbytes = self.error_byte_return()
|
|
775
|
+
return msgbytes
|
|
776
|
+
|
|
777
|
+
def get_device_id(self):
|
|
778
|
+
# alias for device_id()
|
|
779
|
+
return self.device_id()
|
|
780
|
+
|
|
781
|
+
def set_device_id(self, ID):
|
|
782
|
+
# alias for device_id()
|
|
783
|
+
return self.device_id(ID)
|
|
784
|
+
|
|
785
|
+
def direct(self, val, freq):
|
|
786
|
+
# Output mode for generating a square wave signal between 830MHz and 1130MHz
|
|
787
|
+
# usage: direct {start|stop|on|off} {freq(Hz)}
|
|
788
|
+
# example return: ''
|
|
789
|
+
|
|
790
|
+
#explicitly allowed vals
|
|
791
|
+
accepted_vals = ["start", "stop",
|
|
792
|
+
"on", "off"]
|
|
793
|
+
#check input
|
|
794
|
+
if (str(val)=="on") or (str(val) =="off"):
|
|
795
|
+
writebyte = 'direct '+str(val)+'\r\n'
|
|
796
|
+
msgbytes = self.tinySA_serial(writebyte, printBool=False)
|
|
797
|
+
self.print_message("direct() set with " + str(val))
|
|
798
|
+
elif (str(val)=="start") or (str(val)=="stop"):
|
|
799
|
+
#TODO: add frequency checking here
|
|
800
|
+
writebyte = 'direct '+str(val)+' ' +str(freq)+ '\r\n'
|
|
801
|
+
msgbytes = self.tinySA_serial(writebyte, printBool=False)
|
|
802
|
+
self.print_message("direct() set with " + str(val) + "frequency of " + str(freq))
|
|
803
|
+
else:
|
|
804
|
+
self.print_message("ERROR: direct() takes val={'on', 'off', 'start', 'stop'}, freq=INT")
|
|
805
|
+
msgbytes = self.error_byte_return()
|
|
806
|
+
return msgbytes
|
|
807
|
+
|
|
808
|
+
def set_direct_on(self):
|
|
809
|
+
# alias for direct()
|
|
810
|
+
return self.direct("on")
|
|
811
|
+
def set_direct_off(self):
|
|
812
|
+
# alias for direct()
|
|
813
|
+
return self.direct("off")
|
|
814
|
+
def set_direct_start(self, freq):
|
|
815
|
+
# alias for direct()
|
|
816
|
+
return self.direct("start", freq)
|
|
817
|
+
def set_direct_stop(self, freq):
|
|
818
|
+
# alias for direct()
|
|
819
|
+
return self.direct("stop", freq)
|
|
820
|
+
|
|
821
|
+
def ext_gain(self, val):
|
|
822
|
+
# sets the external attenuation/amplification.
|
|
823
|
+
# Works in both input and output mode
|
|
824
|
+
# usage: ext_gain -100..100
|
|
825
|
+
# example return: ''
|
|
826
|
+
|
|
827
|
+
#check input
|
|
828
|
+
if (isinstance(val, (int, float))) and (-100<= val <=100):
|
|
829
|
+
writebyte = 'ext_gain '+str(val)+'\r\n'
|
|
830
|
+
msgbytes = self.tinySA_serial(writebyte, printBool=False)
|
|
831
|
+
self.print_message("ext_gain() set to " + str(val))
|
|
832
|
+
else:
|
|
833
|
+
self.print_message("ERROR: ext_gain() takes vals [-100 - 100]")
|
|
834
|
+
msgbytes = self.error_byte_return()
|
|
835
|
+
return msgbytes
|
|
836
|
+
|
|
837
|
+
def set_ext_gain(self, val):
|
|
838
|
+
# alias for ext_gain()
|
|
839
|
+
return self.ext_gain(val)
|
|
840
|
+
|
|
841
|
+
|
|
842
|
+
def fill(self):
|
|
843
|
+
# sent by tinySA when in auto refresh mode
|
|
844
|
+
# format: "fill\r\n{X}{Y}{Width}{Height}
|
|
845
|
+
# {Color}\r\n"
|
|
846
|
+
# where all numbers are binary coded 2
|
|
847
|
+
# bytes little endian. Similar ot bulk()
|
|
848
|
+
|
|
849
|
+
writebyte = 'fill\r\n'
|
|
850
|
+
msgbytes = self.tinySA_serial(writebyte, printBool=False)
|
|
851
|
+
self.print_message("fill() called for screen data")
|
|
852
|
+
return msgbytes
|
|
853
|
+
|
|
854
|
+
def get_fill_data(self):
|
|
855
|
+
# alias for fill()
|
|
856
|
+
return self.fill()
|
|
857
|
+
|
|
858
|
+
def freq(self, val):
|
|
859
|
+
# pauses the sweep and sets the measurement frequency.
|
|
860
|
+
# usage: freq {frequency}
|
|
861
|
+
# example return: bytearray(b'')
|
|
862
|
+
|
|
863
|
+
#check input
|
|
864
|
+
if (isinstance(val, (int, float))) and (self.minSADeviceFreq<= val <=self.maxSADeviceFreq):
|
|
865
|
+
writebyte = 'freq '+str(val)+'\r\n'
|
|
866
|
+
msgbytes = self.tinySA_serial(writebyte, printBool=False)
|
|
867
|
+
self.print_message("freq() set to " + str(val))
|
|
868
|
+
else:
|
|
869
|
+
self.print_message("ERROR: freq() takes integer vals [100 kHz - 5.3 GHz] as Hz for the tinySA Ultra")
|
|
870
|
+
msgbytes = self.error_byte_return()
|
|
871
|
+
return msgbytes
|
|
872
|
+
|
|
873
|
+
def set_freq(self, val):
|
|
874
|
+
# freq() alias
|
|
875
|
+
return self.freq(val)
|
|
876
|
+
|
|
877
|
+
|
|
878
|
+
def freq_corr(self):
|
|
879
|
+
# get frequency correction
|
|
880
|
+
# usage: freq_corr
|
|
881
|
+
# example return: bytearray(b'0 ppb\r')
|
|
882
|
+
|
|
883
|
+
writebyte = 'freq_corr\r\n'
|
|
884
|
+
msgbytes = self.tinySA_serial(writebyte, printBool=False)
|
|
885
|
+
self.print_message("getting frequency correction")
|
|
886
|
+
return msgbytes
|
|
887
|
+
|
|
888
|
+
def get_frequency_correction(self):
|
|
889
|
+
# alias for freq_corr()
|
|
890
|
+
return self.freq_corr()
|
|
891
|
+
|
|
892
|
+
def frequencies(self):
|
|
893
|
+
# gets the frequencies used by the last sweep
|
|
894
|
+
# usage: frequencies
|
|
895
|
+
# example return: bytearray(b'1500000000\r\n... \r\n3000000000\r')
|
|
896
|
+
|
|
897
|
+
writebyte = 'frequencies\r\n'
|
|
898
|
+
msgbytes = self.tinySA_serial(writebyte, printBool=False)
|
|
899
|
+
self.print_message("getting frequencies from the last sweep")
|
|
900
|
+
return msgbytes
|
|
901
|
+
|
|
902
|
+
def get_last_freqs(self):
|
|
903
|
+
# get frequencies of last sweep
|
|
904
|
+
return self.frequencies()
|
|
905
|
+
|
|
906
|
+
|
|
907
|
+
def hop(self, start, stop, inc, outmask=None):
|
|
908
|
+
# this is a measurement, maybe a sample measurement. format looks like hop freqval integer
|
|
909
|
+
# usage: hop {start(Hz)} {stop(Hz)} {step(Hz) | points} [outmask]
|
|
910
|
+
# outmask: 1 is frequency, 2 is level
|
|
911
|
+
# example return: ''
|
|
912
|
+
|
|
913
|
+
if (isinstance(start, (int, float))) and (isinstance(stop, (int, float))) and (isinstance(inc, (int, float))):
|
|
914
|
+
if (isinstance(outmask, int)) and (0<outmask<3):
|
|
915
|
+
writebyte = 'hop ' + str(start) + ' ' + str(stop) + ' ' + str(inc) + ' ' + str(outmask) + '\r\n'
|
|
916
|
+
|
|
917
|
+
elif outmask ==None:
|
|
918
|
+
writebyte = 'hop ' + str(start) + ' ' + str(stop) + ' ' + str(inc) + '\r\n'
|
|
919
|
+
|
|
920
|
+
msgbytes = self.tinySA_serial(writebyte, printBool=False)
|
|
921
|
+
self.print_message("sampling over frequency range")
|
|
922
|
+
return msgbytes
|
|
923
|
+
|
|
924
|
+
else:
|
|
925
|
+
self.print_message("hop() takes arguments start=Int, stop=Int, inc=Int, outmask=None|Int")
|
|
926
|
+
|
|
927
|
+
return None
|
|
928
|
+
|
|
929
|
+
def get_sample_pts(self, start, stop, pts):
|
|
930
|
+
# alias for hop()
|
|
931
|
+
return self.hop(start, stop, pts, outmask=1)
|
|
932
|
+
|
|
933
|
+
|
|
934
|
+
def set_IF(self, val=0):
|
|
935
|
+
# the IF call, but avoiding reserved keywords
|
|
936
|
+
# sets the IF to automatic or a specific value. 0 means automatic
|
|
937
|
+
# usage: if ( 0 | 433M..435M )
|
|
938
|
+
# example return: ''
|
|
939
|
+
|
|
940
|
+
#check input
|
|
941
|
+
if (val == 0) or (val=='auto'):
|
|
942
|
+
writebyte = 'if '+str(0)+'\r\n'
|
|
943
|
+
msgbytes = self.tinySA_serial(writebyte, printBool=False)
|
|
944
|
+
self.print_message("setIF() set to auto")
|
|
945
|
+
elif ((433e6) <=val <=(435e6)):
|
|
946
|
+
writebyte = 'if '+str(val)+'\r\n'
|
|
947
|
+
msgbytes = self.tinySA_serial(writebyte, printBool=False)
|
|
948
|
+
self.print_message("setIF() set to " + str(val))
|
|
949
|
+
else:
|
|
950
|
+
self.print_message("ERROR: if() takes vals ['auto'|0|433M...435M] in Hz as integers")
|
|
951
|
+
msgbytes = self.error_byte_return()
|
|
952
|
+
return msgbytes
|
|
953
|
+
|
|
954
|
+
def set_IF1(self, val):
|
|
955
|
+
# usage: if1 {975M..979M}\r\n977.555902MHz
|
|
956
|
+
# example return: ''
|
|
957
|
+
|
|
958
|
+
#check input
|
|
959
|
+
if (val == 0) or (val=='auto'):
|
|
960
|
+
writebyte = 'if1 '+str(0)+'\r\n'
|
|
961
|
+
msgbytes = self.tinySA_serial(writebyte, printBool=False)
|
|
962
|
+
self.print_message("setIF1() set to auto")
|
|
963
|
+
elif ((975e6) <=val <=(979e6)):
|
|
964
|
+
writebyte = 'if1 '+str(val)+'\r\n'
|
|
965
|
+
msgbytes = self.tinySA_serial(writebyte, printBool=False)
|
|
966
|
+
self.print_message("setIF() set to " + str(val))
|
|
967
|
+
else:
|
|
968
|
+
self.print_message("ERROR: if1() takes vals ['auto'|0|975M...979M] in Hz as integers")
|
|
969
|
+
msgbytes = self.error_byte_return()
|
|
970
|
+
return msgbytes
|
|
971
|
+
|
|
972
|
+
def info(self):
|
|
973
|
+
# displays various SW and HW information
|
|
974
|
+
# usage: info
|
|
975
|
+
# example return: bytearray(b'tinySA ...\r')
|
|
976
|
+
|
|
977
|
+
writebyte = 'info\r\n'
|
|
978
|
+
msgbytes = self.tinySA_serial(writebyte, printBool=False)
|
|
979
|
+
self.print_message("returning device info()")
|
|
980
|
+
return msgbytes
|
|
981
|
+
|
|
982
|
+
def get_info(self):
|
|
983
|
+
# alias for info()
|
|
984
|
+
return self.info()
|
|
985
|
+
|
|
986
|
+
|
|
987
|
+
def level(self, val):
|
|
988
|
+
# sets the output level. Not all values in the range are available
|
|
989
|
+
# usage: level -76..13
|
|
990
|
+
# example return: b''
|
|
991
|
+
|
|
992
|
+
# explicitly allowed vals
|
|
993
|
+
accepted_vals = np.arange(-76, 14, 1) # max exclusive
|
|
994
|
+
#check input
|
|
995
|
+
if val in accepted_vals:
|
|
996
|
+
writebyte = 'level '+str(val)+'\r\n'
|
|
997
|
+
msgbytes = self.tinySA_serial(writebyte, printBool=False)
|
|
998
|
+
self.print_message("level() set to " + str(val))
|
|
999
|
+
else:
|
|
1000
|
+
self.print_message("ERROR: level() takes vals [-76 to 13]")
|
|
1001
|
+
self.print_message("ERROR: value given: " + str(val))
|
|
1002
|
+
msgbytes = self.error_byte_return()
|
|
1003
|
+
return msgbytes
|
|
1004
|
+
|
|
1005
|
+
def set_level(self, val):
|
|
1006
|
+
# alias for level()
|
|
1007
|
+
return self.level(val)
|
|
1008
|
+
|
|
1009
|
+
|
|
1010
|
+
def level_change(self, val):
|
|
1011
|
+
# sets the output level delta for low output mode level sweep
|
|
1012
|
+
# usage: levelchange -70..+70
|
|
1013
|
+
# example return: ''
|
|
1014
|
+
|
|
1015
|
+
#explicitly allowed vals
|
|
1016
|
+
accepted_vals = np.arange(-70, 71, 1) # max exclusive
|
|
1017
|
+
#check input
|
|
1018
|
+
if (val in accepted_vals):
|
|
1019
|
+
writebyte = 'levelchange '+str(val)+'\r\n'
|
|
1020
|
+
msgbytes = self.tinySA_serial(writebyte, printBool=False)
|
|
1021
|
+
self.print_message("levelchange() set to " + str(val))
|
|
1022
|
+
else:
|
|
1023
|
+
self.print_message("ERROR: levelchange() takes vals [-70 - 70]")
|
|
1024
|
+
self.print_message("ERROR: value set to" + str(val))
|
|
1025
|
+
msgbytes = self.error_byte_return()
|
|
1026
|
+
return msgbytes
|
|
1027
|
+
|
|
1028
|
+
def set_level_change(self, val):
|
|
1029
|
+
# alias for level_change()
|
|
1030
|
+
return self.level_change(val)
|
|
1031
|
+
|
|
1032
|
+
|
|
1033
|
+
def level_offset(self, val, offset, isOutput=False):
|
|
1034
|
+
# sets or dumps the level calibration data.
|
|
1035
|
+
# For the output corrections first ensure correct output
|
|
1036
|
+
# levels at maximum output level.
|
|
1037
|
+
# For the low output set the output to -50dBm and
|
|
1038
|
+
# measure and correct the level with
|
|
1039
|
+
# "leveloffset switch error" where for all output
|
|
1040
|
+
# leveloffset commands measure the level with the
|
|
1041
|
+
# leveloffset to zero and calculate
|
|
1042
|
+
# error = measured level - specified level
|
|
1043
|
+
|
|
1044
|
+
|
|
1045
|
+
# usage: leveloffset [low|switch|receive_switch|out_switch|lna|
|
|
1046
|
+
# harmonic|shift|shift1|shift2|shift3|drive1|drive2|drive3|
|
|
1047
|
+
# direct|direct_lna|ultra|ultra_lna|harmonic_lna|adf]
|
|
1048
|
+
# {output} [-20..+20]
|
|
1049
|
+
|
|
1050
|
+
|
|
1051
|
+
#NOTE: there's probably some limitations on which of these take the 'output' command,
|
|
1052
|
+
# but that error checking isn't done here YET
|
|
1053
|
+
|
|
1054
|
+
#explicitly allowed vals
|
|
1055
|
+
accepted_vals = ["low","switch","receive_switch","out_switch","lna",
|
|
1056
|
+
"harmonic","shift","shift1","shift2","shift3",
|
|
1057
|
+
"drive1","drive2","drive3","direct","direct_lna",
|
|
1058
|
+
"ultra","ultra_lna","harmonic_lna","adf"]
|
|
1059
|
+
#check input
|
|
1060
|
+
if (val in accepted_vals):
|
|
1061
|
+
if (-20.0<=offset<=20.0):
|
|
1062
|
+
if isOutput == True:
|
|
1063
|
+
# success message
|
|
1064
|
+
writebyte = 'leveloffset '+str(val)+ ' output ' + str(float(offset)) +'\r\n'
|
|
1065
|
+
msgbytes = self.tinySA_serial(writebyte, printBool=False)
|
|
1066
|
+
self.print_message("leveloffset() set to " + str(val) + " output " + str(offset))
|
|
1067
|
+
|
|
1068
|
+
|
|
1069
|
+
elif isOutput == False:
|
|
1070
|
+
# success message
|
|
1071
|
+
writebyte = 'leveloffset '+str(val)+ ' ' + str(float(offset)) +'\r\n'
|
|
1072
|
+
msgbytes = self.tinySA_serial(writebyte, printBool=False)
|
|
1073
|
+
self.print_message("leveloffset() set to " + str(val) + " " + str(offset))
|
|
1074
|
+
|
|
1075
|
+
else:
|
|
1076
|
+
# just for the error check when bulking this function out
|
|
1077
|
+
self.print_message("ERROR: leveloffset() value isOutput is a Boolean")
|
|
1078
|
+
self.print_message("ERROR: value set to" + str(isOutput))
|
|
1079
|
+
msgbytes = self.error_byte_return()
|
|
1080
|
+
return msgbytes
|
|
1081
|
+
|
|
1082
|
+
|
|
1083
|
+
else:
|
|
1084
|
+
self.print_message("ERROR: leveloffset() takes offset vals as floats [-20.0 - 20.0]")
|
|
1085
|
+
self.print_message("ERROR: value set to" + str(offset))
|
|
1086
|
+
msgbytes = self.error_byte_return()
|
|
1087
|
+
|
|
1088
|
+
|
|
1089
|
+
else:
|
|
1090
|
+
self.print_message("ERROR: leveloffset() takes value arguments low|switch|receive_switch|out_switch|lna|" \
|
|
1091
|
+
"harmonic|shift|shift1|shift2|shift3|drive1|drive2|drive3|direct|" \
|
|
1092
|
+
"direct_lna|ultra|ultra_lna|harmonic_lna|adf, ans specificed output and level")
|
|
1093
|
+
self.print_message("ERROR: value set to" + str(val))
|
|
1094
|
+
msgbytes = self.error_byte_return()
|
|
1095
|
+
return msgbytes
|
|
1096
|
+
|
|
1097
|
+
|
|
1098
|
+
|
|
1099
|
+
|
|
1100
|
+
|
|
1101
|
+
|
|
1102
|
+
msgbytes = self.error_byte_return()
|
|
1103
|
+
self.print_message("Function does not exist yet. error checking needed")
|
|
1104
|
+
return None
|
|
1105
|
+
|
|
1106
|
+
def line(self, val):
|
|
1107
|
+
# Disables the horizontal line or sets it to a specific level.
|
|
1108
|
+
# usage: line off|{level}
|
|
1109
|
+
# example return: ''
|
|
1110
|
+
if (val=="off"):
|
|
1111
|
+
writebyte = 'line '+str(val)+'\r\n'
|
|
1112
|
+
msgbytes = self.tinySA_serial(writebyte, printBool=False)
|
|
1113
|
+
self.print_message("horizontal line turned off")
|
|
1114
|
+
elif (isinstance(val, (int, float))): # or (isinstance(val, float)):
|
|
1115
|
+
writebyte = 'line '+str(val)+'\r\n'
|
|
1116
|
+
msgbytes = self.tinySA_serial(writebyte, printBool=False)
|
|
1117
|
+
self.print_message("horizontal line turned off")
|
|
1118
|
+
else:
|
|
1119
|
+
self.print_message("ERROR: line takes arguments 'off' or level")
|
|
1120
|
+
msgbytes = self.error_byte_return()
|
|
1121
|
+
return msgbytes
|
|
1122
|
+
|
|
1123
|
+
def line_off(self):
|
|
1124
|
+
# alias for line
|
|
1125
|
+
return self.line("off")
|
|
1126
|
+
|
|
1127
|
+
def set_line(self, val):
|
|
1128
|
+
# alias for line
|
|
1129
|
+
return self.line(val)
|
|
1130
|
+
|
|
1131
|
+
def load(self, val=0):
|
|
1132
|
+
# loads a previously stored preset,where 0 is the startup preset
|
|
1133
|
+
# usage: load [0-4]
|
|
1134
|
+
# example return: ''
|
|
1135
|
+
|
|
1136
|
+
#explicitly allowed vals
|
|
1137
|
+
accepted_vals = [0,1,2,3,4]
|
|
1138
|
+
#check input
|
|
1139
|
+
if (val in accepted_vals):
|
|
1140
|
+
writebyte = 'load '+str(val)+'\r\n'
|
|
1141
|
+
msgbytes = self.tinySA_serial(writebyte, printBool=False)
|
|
1142
|
+
self.print_message("load() called for preset # " + str(val))
|
|
1143
|
+
else:
|
|
1144
|
+
self.print_message("ERROR: load() takes vals [0 - 4]")
|
|
1145
|
+
msgbytes = self.error_byte_return()
|
|
1146
|
+
return msgbytes
|
|
1147
|
+
|
|
1148
|
+
def lna(self, val):
|
|
1149
|
+
# toggle lna usage off/on
|
|
1150
|
+
# usage: lna off|on
|
|
1151
|
+
# example return: ''
|
|
1152
|
+
|
|
1153
|
+
#explicitly allowed vals
|
|
1154
|
+
accepted_vals = ["on", "off"]
|
|
1155
|
+
#check input
|
|
1156
|
+
if (str(val) in accepted_vals):
|
|
1157
|
+
writebyte = 'lna '+str(val)+'\r\n'
|
|
1158
|
+
msgbytes = self.tinySA_serial(writebyte, printBool=False)
|
|
1159
|
+
self.print_message("lna() set to " + str(val))
|
|
1160
|
+
else:
|
|
1161
|
+
self.print_message("ERROR: lna() takes vals [on|off]")
|
|
1162
|
+
msgbytes = self.error_byte_return()
|
|
1163
|
+
return msgbytes
|
|
1164
|
+
|
|
1165
|
+
def set_lna_on(self):
|
|
1166
|
+
#alias for lna1()
|
|
1167
|
+
return self.lna("on")
|
|
1168
|
+
def set_lna_off(self):
|
|
1169
|
+
#alias for lna1()
|
|
1170
|
+
return self.lna("off")
|
|
1171
|
+
|
|
1172
|
+
|
|
1173
|
+
def lna2(self, val="auto"):
|
|
1174
|
+
# Set the second LNA usage off/on.
|
|
1175
|
+
# The Ultra Plus devices have a 2nd LNA at a higher frequency range.
|
|
1176
|
+
# usage: lna2 0..7|auto
|
|
1177
|
+
# example return: ''
|
|
1178
|
+
|
|
1179
|
+
#explicitly allowed vals
|
|
1180
|
+
accepted_vals = [0,1,2,3,4,5,6,7]
|
|
1181
|
+
#check input
|
|
1182
|
+
if (val == "auto") or (val in accepted_vals):
|
|
1183
|
+
writebyte = 'lna2 '+str(val)+'\r\n'
|
|
1184
|
+
msgbytes = self.tinySA_serial(writebyte, printBool=False)
|
|
1185
|
+
self.print_message("lna2() set to " + str(val))
|
|
1186
|
+
else:
|
|
1187
|
+
self.print_message("ERROR: lna2() takes vals [0 - 7]|auto")
|
|
1188
|
+
msgbytes = self.error_byte_return()
|
|
1189
|
+
return msgbytes
|
|
1190
|
+
|
|
1191
|
+
def set_lna2(self, val):
|
|
1192
|
+
#alias for lna2()
|
|
1193
|
+
return self.lna2(val)
|
|
1194
|
+
|
|
1195
|
+
|
|
1196
|
+
def marker(self, ID, val):
|
|
1197
|
+
# sets or dumps marker info.
|
|
1198
|
+
# where id=1..4 index=0..num_points-1
|
|
1199
|
+
# Marker levels will use the selected unit.
|
|
1200
|
+
# Marker peak will:
|
|
1201
|
+
# 1) activate the marker (if not done already),
|
|
1202
|
+
# 2) position the marker on the strongest signal, and
|
|
1203
|
+
# 3) display the marker info.
|
|
1204
|
+
# The frequency must be within the selected sweep range
|
|
1205
|
+
# usage: marker {id} on|off|peak|{freq}|{index}
|
|
1206
|
+
# example return: ''
|
|
1207
|
+
|
|
1208
|
+
#explicitly allowed vals
|
|
1209
|
+
accepted_vals = ["on", "off", "peak"]
|
|
1210
|
+
#check input
|
|
1211
|
+
if ID == None:
|
|
1212
|
+
self.print_message("ERROR: marker() takes ID=Int|0..4")
|
|
1213
|
+
msgbytes = self.error_byte_return()
|
|
1214
|
+
return msgbytes
|
|
1215
|
+
|
|
1216
|
+
if (str(val) in accepted_vals):
|
|
1217
|
+
writebyte = 'marker ' + str(ID) + ' ' +str(val)+'\r\n'
|
|
1218
|
+
msgbytes = self.tinySA_serial(writebyte, printBool=False)
|
|
1219
|
+
self.print_message("marker set to " + str(val))
|
|
1220
|
+
elif (isinstance(val, (int, float))): # or (isinstance(val, float)):
|
|
1221
|
+
writebyte = 'marker ' + str(ID) + ' ' +str(val)+'\r\n'
|
|
1222
|
+
msgbytes = self.tinySA_serial(writebyte, printBool=False)
|
|
1223
|
+
self.print_message("marker set to " + str(val))
|
|
1224
|
+
else:
|
|
1225
|
+
self.print_message("ERROR: marker() takes ID=Int|0..4, and frequency or index in Int or Float")
|
|
1226
|
+
msgbytes = self.error_byte_return()
|
|
1227
|
+
return msgbytes
|
|
1228
|
+
|
|
1229
|
+
def marker_on(self, ID):
|
|
1230
|
+
# alias for marker()
|
|
1231
|
+
self.marker(ID, "on")
|
|
1232
|
+
def marker_off(self, ID):
|
|
1233
|
+
# alias for marker()
|
|
1234
|
+
self.marker(ID, "off")
|
|
1235
|
+
def marker_peak(self, ID):
|
|
1236
|
+
# alias for marker()
|
|
1237
|
+
self.marker(ID, "peak")
|
|
1238
|
+
def marker_freq(self, ID, val):
|
|
1239
|
+
# alias for marker()
|
|
1240
|
+
self.marker(ID, val)
|
|
1241
|
+
def marker_index(self, ID, val):
|
|
1242
|
+
# alias for marker()
|
|
1243
|
+
self.marker(ID, val)
|
|
1244
|
+
|
|
1245
|
+
def menu(self, val):
|
|
1246
|
+
# The menu command can be used to activate any menu item
|
|
1247
|
+
# usage: menu {#} [{#} [{#} [{#}]]]
|
|
1248
|
+
# example return: ''
|
|
1249
|
+
|
|
1250
|
+
writebyte = 'menu ' + str(val) + '\r\n'
|
|
1251
|
+
msgbytes = self.tinySA_serial(writebyte, printBool=False)
|
|
1252
|
+
self.print_message("clicking menu button")
|
|
1253
|
+
return msgbytes
|
|
1254
|
+
|
|
1255
|
+
def mode(self, val1="low", val2="input"):
|
|
1256
|
+
# sets the mode of the tinySA
|
|
1257
|
+
# usage: mode low|high input|output
|
|
1258
|
+
# example return: ''
|
|
1259
|
+
|
|
1260
|
+
#explicitly allowed vals
|
|
1261
|
+
accepted_val1 = ["low", "high"]
|
|
1262
|
+
accepted_val2= ["input", "output"]
|
|
1263
|
+
#check input
|
|
1264
|
+
if (val1 in accepted_val1) and (val2 in accepted_val2):
|
|
1265
|
+
writebyte = 'mode '+str(val1)+ + ' ' +str(val2)+'\r\n'
|
|
1266
|
+
msgbytes = self.tinySA_serial(writebyte, printBool=False)
|
|
1267
|
+
else:
|
|
1268
|
+
self.print_message("ERROR: output() takes vals [on|off]")
|
|
1269
|
+
msgbytes = self.error_byte_return()
|
|
1270
|
+
return msgbytes
|
|
1271
|
+
|
|
1272
|
+
def set_low_input_mode(self):
|
|
1273
|
+
# alias for mode()
|
|
1274
|
+
return self.mode("low", "input")
|
|
1275
|
+
|
|
1276
|
+
def set_low_output_mode(self):
|
|
1277
|
+
# alias for mode()
|
|
1278
|
+
return self.mode("low", "output")
|
|
1279
|
+
|
|
1280
|
+
def set_high_input_mode(self):
|
|
1281
|
+
# alias for mode()
|
|
1282
|
+
return self.mode("high", "input")
|
|
1283
|
+
|
|
1284
|
+
def set_high_output_mode(self):
|
|
1285
|
+
# alias for mode()
|
|
1286
|
+
# TODO: ERROR CHECKING
|
|
1287
|
+
return self.mode("high", "output")
|
|
1288
|
+
|
|
1289
|
+
def modulation(self, val):
|
|
1290
|
+
# sets the modulation in output mode
|
|
1291
|
+
# usage: modulation off|AM_1kHz|AM_10Hz|NFM|WFM|extern
|
|
1292
|
+
# example return: ''
|
|
1293
|
+
|
|
1294
|
+
#explicitly allowed vals
|
|
1295
|
+
accepted_vals = ["off", "AM_1kHz", "AM_10Hz",
|
|
1296
|
+
"NFM", "WFM", "extern"]
|
|
1297
|
+
#check input
|
|
1298
|
+
if (str(val) in accepted_vals):
|
|
1299
|
+
writebyte = 'output '+str(val)+'\r\n'
|
|
1300
|
+
msgbytes = self.tinySA_serial(writebyte, printBool=False)
|
|
1301
|
+
else:
|
|
1302
|
+
self.print_message("ERROR: output() takes vals [on|off]")
|
|
1303
|
+
msgbytes = self.error_byte_return()
|
|
1304
|
+
return msgbytes
|
|
1305
|
+
|
|
1306
|
+
def set_mod_off(self):
|
|
1307
|
+
# alias for modulation()
|
|
1308
|
+
return self.modulation("off")
|
|
1309
|
+
def set_mod_AM_1khz(self):
|
|
1310
|
+
# alias for modulation()
|
|
1311
|
+
return self.modulation("AM_1kHz")
|
|
1312
|
+
def set_mod_AM_10Hz(self):
|
|
1313
|
+
# alias for modulation()
|
|
1314
|
+
return self.modulation("AM_10Hz")
|
|
1315
|
+
def set_mod_NFM(self):
|
|
1316
|
+
# alias for modulation()
|
|
1317
|
+
return self.modulation("NFM")
|
|
1318
|
+
def set_mod_WFM(self):
|
|
1319
|
+
# alias for modulation()
|
|
1320
|
+
return self.modulation("WFM")
|
|
1321
|
+
def set_mod_extern(self):
|
|
1322
|
+
# alias for modulation()
|
|
1323
|
+
return self.modulation("extern")
|
|
1324
|
+
|
|
1325
|
+
|
|
1326
|
+
def nf(self):
|
|
1327
|
+
# get the noise floor in dB.
|
|
1328
|
+
# This function CAN be used to set nf,
|
|
1329
|
+
# but that might bypass a measurement process. UNKNOWN right now.
|
|
1330
|
+
# usage: nf {value}\r\n
|
|
1331
|
+
# example return: ''
|
|
1332
|
+
writebyte = 'nf\r\n'
|
|
1333
|
+
msgbytes = self.tinySA_serial(writebyte, printBool=False)
|
|
1334
|
+
self.print_message("getting saved noise floor value")
|
|
1335
|
+
return msgbytes
|
|
1336
|
+
|
|
1337
|
+
def get_nf(self):
|
|
1338
|
+
# alias function for nf()
|
|
1339
|
+
return self.nf()
|
|
1340
|
+
|
|
1341
|
+
def output(self, val):
|
|
1342
|
+
# sets the output on or off
|
|
1343
|
+
# usage: output on|off
|
|
1344
|
+
# example return: ''
|
|
1345
|
+
|
|
1346
|
+
# explicitly allowed vals
|
|
1347
|
+
accepted_vals = ["on", "off"]
|
|
1348
|
+
#check input
|
|
1349
|
+
if (str(val) in accepted_vals):
|
|
1350
|
+
writebyte = 'output '+str(val)+'\r\n'
|
|
1351
|
+
msgbytes = self.tinySA_serial(writebyte, printBool=False)
|
|
1352
|
+
else:
|
|
1353
|
+
self.print_message("ERROR: output() takes vals [on|off]")
|
|
1354
|
+
msgbytes = self.error_byte_return()
|
|
1355
|
+
return msgbytes
|
|
1356
|
+
|
|
1357
|
+
def set_output_on(self):
|
|
1358
|
+
#alias for output()
|
|
1359
|
+
return self.output("on")
|
|
1360
|
+
def set_output_off(self):
|
|
1361
|
+
#alias for output()
|
|
1362
|
+
return self.output("off")
|
|
1363
|
+
|
|
1364
|
+
|
|
1365
|
+
def pause(self):
|
|
1366
|
+
# pauses the sweeping in either input or output mode
|
|
1367
|
+
# usage: pause
|
|
1368
|
+
# example return: ''
|
|
1369
|
+
|
|
1370
|
+
writebyte = 'pause\r\n'
|
|
1371
|
+
msgbytes = self.tinySA_serial(writebyte, printBool=False)
|
|
1372
|
+
self.print_message("pausing tinySA device")
|
|
1373
|
+
return msgbytes
|
|
1374
|
+
|
|
1375
|
+
def rbw(self, val="auto"):
|
|
1376
|
+
# sets the rbw to either automatic or a specific value.
|
|
1377
|
+
# the number specifies the target rbw in kHz
|
|
1378
|
+
# usage: rbw auto|3..600
|
|
1379
|
+
# example return: ''
|
|
1380
|
+
|
|
1381
|
+
#check input
|
|
1382
|
+
if (val == "auto"):
|
|
1383
|
+
writebyte = 'rbw '+str(val)+'\r\n'
|
|
1384
|
+
msgbytes = self.tinySA_serial(writebyte, printBool=False)
|
|
1385
|
+
elif (isinstance(val, int)):
|
|
1386
|
+
writebyte = 'rbw '+str(val)+'\r\n'
|
|
1387
|
+
msgbytes = self.tinySA_serial(writebyte, printBool=False)
|
|
1388
|
+
else:
|
|
1389
|
+
self.print_message("ERROR: rbw() takes vals [auto |0 - 600] in kHz as integers")
|
|
1390
|
+
msgbytes = self.error_byte_return()
|
|
1391
|
+
return msgbytes
|
|
1392
|
+
|
|
1393
|
+
def set_rbw_auto(self):
|
|
1394
|
+
# alias for rbw()
|
|
1395
|
+
return self.rbw("auto")
|
|
1396
|
+
|
|
1397
|
+
|
|
1398
|
+
def recall(self, val=0):
|
|
1399
|
+
# loads a previously stored preset,where 0 is the startup preset
|
|
1400
|
+
# usage: recall [0-4]
|
|
1401
|
+
# example return: ''
|
|
1402
|
+
|
|
1403
|
+
#explicitly allowed vals
|
|
1404
|
+
accepted_vals = [0,1,2,3,4]
|
|
1405
|
+
#check input
|
|
1406
|
+
if (val in accepted_vals):
|
|
1407
|
+
writebyte = 'recall '+str(val)+'\r\n'
|
|
1408
|
+
msgbytes = self.tinySA_serial(writebyte, printBool=False)
|
|
1409
|
+
self.print_message("recall() set to value " + str(val))
|
|
1410
|
+
else:
|
|
1411
|
+
self.print_message("ERROR: recall() takes vals [0 - 4]")
|
|
1412
|
+
msgbytes = self.error_byte_return()
|
|
1413
|
+
return msgbytes
|
|
1414
|
+
|
|
1415
|
+
def refresh(self, val):
|
|
1416
|
+
# enables/disables the auto refresh mode
|
|
1417
|
+
# usage: refresh on|off
|
|
1418
|
+
# example return: ''
|
|
1419
|
+
|
|
1420
|
+
#explicitly allowed vals
|
|
1421
|
+
accepted_vals = ["on", "off"]
|
|
1422
|
+
#check input
|
|
1423
|
+
if (str(val) in accepted_vals):
|
|
1424
|
+
writebyte = 'refresh '+str(val)+'\r\n'
|
|
1425
|
+
msgbytes = self.tinySA_serial(writebyte, printBool=False)
|
|
1426
|
+
self.print_message("refresh() set to " + str(val))
|
|
1427
|
+
else:
|
|
1428
|
+
self.print_message("ERROR: refresh() takes vals [on|off]")
|
|
1429
|
+
msgbytes = self.error_byte_return()
|
|
1430
|
+
return msgbytes
|
|
1431
|
+
|
|
1432
|
+
def refresh_on(self):
|
|
1433
|
+
# alias for refresh()
|
|
1434
|
+
return self.refresh("on")
|
|
1435
|
+
|
|
1436
|
+
def refresh_off(self):
|
|
1437
|
+
# alias for refresh()
|
|
1438
|
+
return self.refresh("off")
|
|
1439
|
+
|
|
1440
|
+
def release(self):
|
|
1441
|
+
# signals a removal of the touch
|
|
1442
|
+
# usage: release
|
|
1443
|
+
# example return: bytearray(b'')
|
|
1444
|
+
|
|
1445
|
+
writebyte = 'release\r\n'
|
|
1446
|
+
msgbytes = self.tinySA_serial(writebyte, printBool=False)
|
|
1447
|
+
self.print_message("sending touch release signal")
|
|
1448
|
+
return msgbytes
|
|
1449
|
+
|
|
1450
|
+
def remark(self, val):
|
|
1451
|
+
# does nothing
|
|
1452
|
+
# usage: remark {any text}
|
|
1453
|
+
# example return: bytearray(b'')
|
|
1454
|
+
writebyte = 'remark ' + str(val) + '\r\n'
|
|
1455
|
+
msgbytes = self.tinySA_serial(writebyte, printBool=False)
|
|
1456
|
+
self.print_message("remark " + str(val))
|
|
1457
|
+
|
|
1458
|
+
return msgbytes
|
|
1459
|
+
|
|
1460
|
+
def repeat(self, val=1):
|
|
1461
|
+
# Sets the number of (re)measurements that
|
|
1462
|
+
# should be taken at every frequency
|
|
1463
|
+
# usage: repeat
|
|
1464
|
+
# example return: bytearray(b'')
|
|
1465
|
+
|
|
1466
|
+
val = int(val)
|
|
1467
|
+
if (1<=val<=1000):
|
|
1468
|
+
writebyte = 'repeat ' + str(val) + '\r\n'
|
|
1469
|
+
msgbytes = self.tinySA_serial(writebyte, printBool=False)
|
|
1470
|
+
self.print_message("setting the repeat() measurement to " + str(val))
|
|
1471
|
+
else:
|
|
1472
|
+
self.print_message("ERROR: repeat() takes integer vals [0 - 1000]")
|
|
1473
|
+
msgbytes = self.error_byte_return()
|
|
1474
|
+
return msgbytes
|
|
1475
|
+
|
|
1476
|
+
def reset(self):
|
|
1477
|
+
# reset the tinySA Ultra. NOTE: will disconnect and fully reset
|
|
1478
|
+
# usage: reset
|
|
1479
|
+
# example return: throws error. raise SerialException
|
|
1480
|
+
|
|
1481
|
+
writebyte = 'reset\r\n'
|
|
1482
|
+
self.print_message("sending reset signal. Serial will disconnect...")
|
|
1483
|
+
msgbytes = self.tinySA_serial(writebyte, printBool=False)
|
|
1484
|
+
return msgbytes
|
|
1485
|
+
|
|
1486
|
+
def reset_device(self):
|
|
1487
|
+
# alias function for reset()
|
|
1488
|
+
return self.reset()
|
|
1489
|
+
|
|
1490
|
+
|
|
1491
|
+
def restart(self, val=0):
|
|
1492
|
+
# restarts the tinySA after the specified number of seconds
|
|
1493
|
+
# usage: restart {seconds}
|
|
1494
|
+
# example return: ''
|
|
1495
|
+
val = int(val)
|
|
1496
|
+
if val == 0:
|
|
1497
|
+
writebyte = 'restart ' + str(val) + '\r\n'
|
|
1498
|
+
msgbytes = self.tinySA_serial(writebyte, printBool=False)
|
|
1499
|
+
self.print_message("restarting cancelled.")
|
|
1500
|
+
elif (0<val):
|
|
1501
|
+
writebyte = 'restart ' + str(val) + '\r\n'
|
|
1502
|
+
msgbytes = self.tinySA_serial(writebyte, printBool=False)
|
|
1503
|
+
self.print_message("restarting the device in " + str(val) + " seconds.")
|
|
1504
|
+
else:
|
|
1505
|
+
self.print_message("ERROR: restart() takes vals 0 or greater")
|
|
1506
|
+
msgbytes = self.error_byte_return()
|
|
1507
|
+
|
|
1508
|
+
return msgbytes
|
|
1509
|
+
|
|
1510
|
+
def restart_device(self, val):
|
|
1511
|
+
# alias function for restart
|
|
1512
|
+
return self.restart(val)
|
|
1513
|
+
def cancel_restart(self):
|
|
1514
|
+
# alias function for restart
|
|
1515
|
+
return self.restart(val=0)
|
|
1516
|
+
|
|
1517
|
+
|
|
1518
|
+
def resume(self):
|
|
1519
|
+
# resumes the sweeping in either input or output mode
|
|
1520
|
+
# usage: resume
|
|
1521
|
+
# example return: ''
|
|
1522
|
+
|
|
1523
|
+
writebyte = 'resume\r\n'
|
|
1524
|
+
msgbytes = self.tinySA_serial(writebyte, printBool=False)
|
|
1525
|
+
self.print_message("resuming sweep")
|
|
1526
|
+
return msgbytes
|
|
1527
|
+
|
|
1528
|
+
def save(self, val=1):
|
|
1529
|
+
# saves the current setting to a preset, where 0 is the startup preset
|
|
1530
|
+
# usage: save [0-4]
|
|
1531
|
+
# example return: ''
|
|
1532
|
+
|
|
1533
|
+
#explicitly allowed vals
|
|
1534
|
+
accepted_vals = [0,1,2,3,4]
|
|
1535
|
+
#check input
|
|
1536
|
+
if (val in accepted_vals):
|
|
1537
|
+
writebyte = 'save '+str(val)+'\r\n'
|
|
1538
|
+
msgbytes = self.tinySA_serial(writebyte, printBool=False)
|
|
1539
|
+
self.print_message("saving to preset " + str(val))
|
|
1540
|
+
else:
|
|
1541
|
+
self.print_message("ERROR: save() takes vals [0 - 4] as integers")
|
|
1542
|
+
msgbytes = self.error_byte_return()
|
|
1543
|
+
return msgbytes
|
|
1544
|
+
|
|
1545
|
+
def save_config(self):
|
|
1546
|
+
# saves the device configuration data
|
|
1547
|
+
# usage: saveconfig
|
|
1548
|
+
# example return: bytearray(b'Config saved.\r')
|
|
1549
|
+
|
|
1550
|
+
writebyte = 'saveconfig\r\n'
|
|
1551
|
+
msgbytes = self.tinySA_serial(writebyte, printBool=False)
|
|
1552
|
+
self.print_message("save_config() called")
|
|
1553
|
+
return msgbytes
|
|
1554
|
+
|
|
1555
|
+
def scan(self, start, stop, pts=250, outmask=None):
|
|
1556
|
+
# Performs a scan and optionally outputs the measured data.
|
|
1557
|
+
# usage: scan {start(Hz)} {stop(Hz)} [points] [outmask]
|
|
1558
|
+
# where the outmask is a binary OR of:
|
|
1559
|
+
# 1=frequencies, 2=measured data,
|
|
1560
|
+
# 4=stored data and max points is device dependent
|
|
1561
|
+
|
|
1562
|
+
if (0<=start) and (start < stop) and (pts <= self.maxPoints):
|
|
1563
|
+
if outmask == None:
|
|
1564
|
+
writebyte = 'scan '+str(start)+' '+str(stop)+' '+str(pts)+'\r\n'
|
|
1565
|
+
else:
|
|
1566
|
+
writebyte = 'scan '+str(start)+' '+str(stop)+' '+str(pts)+ ' '+str(outmask)+'\r\n'
|
|
1567
|
+
msgbytes = self.tinySA_serial(writebyte, printBool=False)
|
|
1568
|
+
self.print_message("scanning...")
|
|
1569
|
+
else:
|
|
1570
|
+
self.print_message("ERROR: scan takes START STOP PTS OUTMASK as args. Check doc for format and limits")
|
|
1571
|
+
msgbytes = self.error_byte_return()
|
|
1572
|
+
return msgbytes
|
|
1573
|
+
|
|
1574
|
+
|
|
1575
|
+
def scan_raw(self, start, stop, pts=250, unbuf=1):
|
|
1576
|
+
# performs a scan of unlimited amount of points
|
|
1577
|
+
# and sends the data in binary form
|
|
1578
|
+
# usage: scanraw {start(Hz)} {stop(Hz)} [points] [unbuffered]
|
|
1579
|
+
# The measured data is sent as:
|
|
1580
|
+
# '{' ('x' MSB LSB)*points '}'
|
|
1581
|
+
# where the 16 bit data is scaled by 32 & shifted based on device.
|
|
1582
|
+
# the README has examples for processing
|
|
1583
|
+
|
|
1584
|
+
if (0<=start) and (start < stop) and (pts <= self.maxPoints):
|
|
1585
|
+
if (unbuf == 1) or (unbuf==2) or (unbuf==3):
|
|
1586
|
+
writebyte = 'scanraw '+str(start)+' '+str(stop)+' '+str(pts)+ ' '+str(unbuf)+'\r\n'
|
|
1587
|
+
|
|
1588
|
+
# write out to serial, get message back, clean up, return
|
|
1589
|
+
self.print_message("scanning...")
|
|
1590
|
+
msgbytes = self.tinySA_serial(writebyte, printBool=False, pts=pts) #pts added for error checking
|
|
1591
|
+
return msgbytes
|
|
1592
|
+
else:
|
|
1593
|
+
self.print_message("ERROR: unrecognized UBUF for scanraw")
|
|
1594
|
+
msgbytes = self.error_byte_return()
|
|
1595
|
+
else:
|
|
1596
|
+
self.print_message("ERROR: scanraw takes START STOP PTS UNBUF as args. Check doc for format and limits")
|
|
1597
|
+
msgbytes = self.error_byte_return()
|
|
1598
|
+
return msgbytes
|
|
1599
|
+
|
|
1600
|
+
def continious_scanraw(self):
|
|
1601
|
+
pass # the continious scan might need to be handled differently
|
|
1602
|
+
|
|
1603
|
+
def sd_delete(self, val):
|
|
1604
|
+
# delete a specific file on the sd card
|
|
1605
|
+
# usage: sd_delete {filename}
|
|
1606
|
+
# example return:
|
|
1607
|
+
|
|
1608
|
+
writebyte = 'sd_delete ' + str(val)+ '\r\n'
|
|
1609
|
+
msgbytes = self.tinySA_serial(writebyte, printBool=False)
|
|
1610
|
+
self.print_message("deleting file from sd card")
|
|
1611
|
+
return msgbytes
|
|
1612
|
+
|
|
1613
|
+
|
|
1614
|
+
def sd_list(self):
|
|
1615
|
+
# displays list of filenames with extension and sizes
|
|
1616
|
+
# usage: sd_list
|
|
1617
|
+
# example return: bytearray(b'-0.bmp 307322\r')
|
|
1618
|
+
|
|
1619
|
+
writebyte = 'sd_list\r\n'
|
|
1620
|
+
msgbytes = self.tinySA_serial(writebyte, printBool=False)
|
|
1621
|
+
self.print_message("listing files from sd card")
|
|
1622
|
+
return msgbytes
|
|
1623
|
+
|
|
1624
|
+
def sd_read(self, val):
|
|
1625
|
+
# read a specific file on the sd_card
|
|
1626
|
+
# usage: sd_read {filename}
|
|
1627
|
+
# example return:
|
|
1628
|
+
|
|
1629
|
+
writebyte = 'sd_read ' + str(val)+ '\r\n'
|
|
1630
|
+
msgbytes = self.tinySA_serial(writebyte, printBool=False)
|
|
1631
|
+
self.print_message("reading file from sd card")
|
|
1632
|
+
return msgbytes
|
|
1633
|
+
|
|
1634
|
+
def self_test(self, val=0):
|
|
1635
|
+
# performs one or all selftests
|
|
1636
|
+
# usage: selftest 0 0..9.
|
|
1637
|
+
# 0 appears to be 'run all'
|
|
1638
|
+
# example return: msgbytes = bytearray(b'')
|
|
1639
|
+
|
|
1640
|
+
#check input
|
|
1641
|
+
if (isinstance(val, int)):
|
|
1642
|
+
writebyte = 'selftest ' + str(val) + '\r\n'
|
|
1643
|
+
msgbytes = self.tinySA_serial(writebyte, printBool=False)
|
|
1644
|
+
self.print_message("SELFTEST RUNNING. CHECK CONNECTION CAL to RF")
|
|
1645
|
+
else:
|
|
1646
|
+
self.print_message("ERROR: self_test() takes interger vals. 0 to run all.")
|
|
1647
|
+
msgbytes = self.error_byte_return()
|
|
1648
|
+
return msgbytes
|
|
1649
|
+
|
|
1650
|
+
def spur(self, val):
|
|
1651
|
+
# enables or disables spur reduction
|
|
1652
|
+
# usage: spur on|off
|
|
1653
|
+
# example return:
|
|
1654
|
+
|
|
1655
|
+
# explicitly allowed vals
|
|
1656
|
+
accepted_vals = ["on", "off"]
|
|
1657
|
+
#check input
|
|
1658
|
+
if (str(val) in accepted_vals):
|
|
1659
|
+
writebyte = 'spur '+str(val)+'\r\n'
|
|
1660
|
+
msgbytes = self.tinySA_serial(writebyte, printBool=False)
|
|
1661
|
+
self.print_message("spur() set to " + str(val))
|
|
1662
|
+
else:
|
|
1663
|
+
self.print_message("ERROR: spur() takes vals [on|off]")
|
|
1664
|
+
msgbytes = self.error_byte_return()
|
|
1665
|
+
return msgbytes
|
|
1666
|
+
|
|
1667
|
+
def spur_on(self):
|
|
1668
|
+
# alias for spur()
|
|
1669
|
+
return self.spur("on")
|
|
1670
|
+
def spur_off(self):
|
|
1671
|
+
# alias for spur()
|
|
1672
|
+
return self.spur("off")
|
|
1673
|
+
|
|
1674
|
+
def status(self):
|
|
1675
|
+
# displays the current device status (paused/resumed)
|
|
1676
|
+
# usage: status
|
|
1677
|
+
# example return: bytearray(b'Resumed\r')
|
|
1678
|
+
|
|
1679
|
+
writebyte = 'status\r\n'
|
|
1680
|
+
msgbytes = self.tinySA_serial(writebyte, printBool=False)
|
|
1681
|
+
self.print_message("getting device status() paused/resumed")
|
|
1682
|
+
return msgbytes
|
|
1683
|
+
|
|
1684
|
+
def get_status(self):
|
|
1685
|
+
# alias for status()
|
|
1686
|
+
return self.get_status()
|
|
1687
|
+
|
|
1688
|
+
|
|
1689
|
+
def config_sweep(self, argName=None, val=None):
|
|
1690
|
+
# split call for SWEEP
|
|
1691
|
+
# Set sweep boundaries.
|
|
1692
|
+
# Sweep without arguments lists the current sweep
|
|
1693
|
+
# settings. The frequencies specified should be
|
|
1694
|
+
# within the permissible range. The sweep commands
|
|
1695
|
+
# apply both to input and output modes
|
|
1696
|
+
# usage:
|
|
1697
|
+
# sweep [(start|stop|center|span|cw {frequency}) |
|
|
1698
|
+
# ({start(Hz)} {stop(Hz)} [0..290])]
|
|
1699
|
+
# EXAMPLES:
|
|
1700
|
+
# sweep start {frequency}: sets the start frequency of the sweep.
|
|
1701
|
+
# sweep stop {frequency}: sets the stop frequency of the sweep.
|
|
1702
|
+
# sweep center {frequency}: sets the center frequency of the sweep.
|
|
1703
|
+
# sweep span {frequency}: sets the span of the sweep.
|
|
1704
|
+
# sweep cw {frequency}: sets the continuous wave frequency (zero span sweep).
|
|
1705
|
+
# # example return: b''
|
|
1706
|
+
|
|
1707
|
+
# explicitly allowed vals
|
|
1708
|
+
accepted_table_args = ["start", "stop", "center",
|
|
1709
|
+
"span", "cw"]
|
|
1710
|
+
|
|
1711
|
+
if (argName==None) and (val==None):
|
|
1712
|
+
# do sweep
|
|
1713
|
+
writebyte = 'sweep\r\n'
|
|
1714
|
+
msgbytes = self.tinySA_serial(writebyte, printBool=False)
|
|
1715
|
+
|
|
1716
|
+
elif (argName in accepted_table_args):
|
|
1717
|
+
if val == None:
|
|
1718
|
+
#error
|
|
1719
|
+
self.print_message("ERROR: sweep " + str(argName) + " needs a value")
|
|
1720
|
+
msgbytes = self.error_byte_return()
|
|
1721
|
+
else:
|
|
1722
|
+
#do stuff, error checking needed
|
|
1723
|
+
writebyte = 'sweep ' + str(argName)+ ' ' + str(val)+ '\r\n'
|
|
1724
|
+
self.print_message("sweep " +str(argName) + " is " + str(val))
|
|
1725
|
+
msgbytes = self.tinySA_serial(writebyte, printBool=False)
|
|
1726
|
+
|
|
1727
|
+
else: #not in table of accepted args, so doesn't matter what val is
|
|
1728
|
+
self.print_message("ERROR: " + str(argName) + " invalid argument for sweep")
|
|
1729
|
+
msgbytes = self.error_byte_return()
|
|
1730
|
+
|
|
1731
|
+
return msgbytes
|
|
1732
|
+
|
|
1733
|
+
def get_sweep_params(self):
|
|
1734
|
+
# alias for config_sweep()
|
|
1735
|
+
return self.config_sweep()
|
|
1736
|
+
def set_sweep_start(self, val):
|
|
1737
|
+
# alias for config_sweep()
|
|
1738
|
+
return self.config_sweep("start", val)
|
|
1739
|
+
def set_sweep_stop(self, val):
|
|
1740
|
+
# alias for config_sweep()
|
|
1741
|
+
return self.config_sweep("stop", val)
|
|
1742
|
+
def set_sweep_center(self, val):
|
|
1743
|
+
# alias for config_sweep()
|
|
1744
|
+
return self.config_sweep("center", val)
|
|
1745
|
+
def set_sweep_span(self, val):
|
|
1746
|
+
# alias for config_sweep()
|
|
1747
|
+
return self.config_sweep("span", val)
|
|
1748
|
+
def set_sweep_cw(self, val):
|
|
1749
|
+
# alias for config_sweep()
|
|
1750
|
+
return self.config_sweep("cw", val)
|
|
1751
|
+
|
|
1752
|
+
def run_sweep(self, startVal=None, stopVal=None, pts=250):
|
|
1753
|
+
# split call for SWEEP
|
|
1754
|
+
# Execute sweep.
|
|
1755
|
+
# The frequencies specified should be
|
|
1756
|
+
# within the permissible range. The sweep commands
|
|
1757
|
+
# apply both to input and output modes
|
|
1758
|
+
# usage:
|
|
1759
|
+
# sweep [(start|stop|center|span|cw {frequency}) |
|
|
1760
|
+
# ({start(Hz)} {stop(Hz)} [0..290])]
|
|
1761
|
+
# # example return:
|
|
1762
|
+
if (startVal==None) or (stopVal==None):
|
|
1763
|
+
self.print_message("ERROR: sweep start and stop need non-empty values")
|
|
1764
|
+
msgbytes = self.error_byte_return()
|
|
1765
|
+
elif (int(startVal) >= int(stopVal)):
|
|
1766
|
+
self.print_message("ERROR: sweep start must be less than sweep stop value")
|
|
1767
|
+
msgbytes = self.error_byte_return()
|
|
1768
|
+
else:
|
|
1769
|
+
#do stuff, error checking needed
|
|
1770
|
+
self.print_message("sweeping...")
|
|
1771
|
+
writebyte = 'sweep '+str(startVal)+' '+str(stopVal)+' '+str(pts)+'1\r\n'
|
|
1772
|
+
msgbytes = self.tinySA_serial(writebyte, printBool=False)
|
|
1773
|
+
|
|
1774
|
+
return msgbytes
|
|
1775
|
+
|
|
1776
|
+
def sweep_time(self, val):
|
|
1777
|
+
# sets the sweeptime
|
|
1778
|
+
# usage: sweep {time(Seconds)}the time
|
|
1779
|
+
# specified may end in a letter where
|
|
1780
|
+
# m=mili and u=micro
|
|
1781
|
+
# example return: b''
|
|
1782
|
+
|
|
1783
|
+
|
|
1784
|
+
# needs some error checking
|
|
1785
|
+
|
|
1786
|
+
writebyte = 'sweeptime '+str(val)+'\r\n'
|
|
1787
|
+
msgbytes = self.tinySA_serial(writebyte, printBool=False)
|
|
1788
|
+
self.print_message("sweeptime set to " + str(val))
|
|
1789
|
+
return msgbytes
|
|
1790
|
+
|
|
1791
|
+
def temp(self):
|
|
1792
|
+
# gets the temperature
|
|
1793
|
+
# usage: k (NOTE: single letter command)
|
|
1794
|
+
# example return:
|
|
1795
|
+
# b'43.25\r'
|
|
1796
|
+
writebyte = 'k\r\n'
|
|
1797
|
+
msgbytes = self.tinySA_serial(writebyte, printBool=False)
|
|
1798
|
+
self.print_message("getting temperature")
|
|
1799
|
+
return msgbytes
|
|
1800
|
+
|
|
1801
|
+
def get_temp(self):
|
|
1802
|
+
# alias for temp()
|
|
1803
|
+
return self.temp()
|
|
1804
|
+
|
|
1805
|
+
|
|
1806
|
+
def text(self, val=""):
|
|
1807
|
+
# specifies the text entry for the active keypad
|
|
1808
|
+
# usage: text(val="")
|
|
1809
|
+
# example return: b''
|
|
1810
|
+
|
|
1811
|
+
if len(str(val))>0:
|
|
1812
|
+
writebyte = 'text ' + str(val) +'\r\n'
|
|
1813
|
+
msgbytes = self.tinySA_serial(writebyte, printBool=False)
|
|
1814
|
+
self.print_message("text() entered is " + str(val))
|
|
1815
|
+
else:
|
|
1816
|
+
self.print_message("ERROR: text needs non-empty values")
|
|
1817
|
+
msgbytes = self.error_byte_return()
|
|
1818
|
+
return msgbytes
|
|
1819
|
+
|
|
1820
|
+
def threads(self):
|
|
1821
|
+
# lists information of the threads in the tinySA
|
|
1822
|
+
# usage: threads
|
|
1823
|
+
# example return:
|
|
1824
|
+
# bytearray(b'stklimit| ...\r')
|
|
1825
|
+
|
|
1826
|
+
writebyte = 'threads\r\n'
|
|
1827
|
+
msgbytes = self.tinySA_serial(writebyte, printBool=False)
|
|
1828
|
+
self.print_message("returning thread information for device")
|
|
1829
|
+
return msgbytes
|
|
1830
|
+
|
|
1831
|
+
def touch(self, x=0, y=0):
|
|
1832
|
+
# sends the coordinates of a touch.
|
|
1833
|
+
# The upper left corner of the screen is 0 0
|
|
1834
|
+
# usage: touch {X coordinate} {Y coordinate}
|
|
1835
|
+
# example return:
|
|
1836
|
+
|
|
1837
|
+
# check if valid x
|
|
1838
|
+
if (x<0) or (self.screenWidth<x):
|
|
1839
|
+
self.print_message("ERROR: touch() needs a valid x coordinate")
|
|
1840
|
+
msgbytes = self.error_byte_return()
|
|
1841
|
+
return msgbytes
|
|
1842
|
+
# check if valid y
|
|
1843
|
+
if (y<0) or (self.screenHeight<y):
|
|
1844
|
+
self.print_message("ERROR: touch() needs a valid y coordinate")
|
|
1845
|
+
msgbytes = self.error_byte_return()
|
|
1846
|
+
return msgbytes
|
|
1847
|
+
writebyte = 'touch ' + str(x) + ' ' + str(y) + '\r\n'
|
|
1848
|
+
msgbytes = self.tinySA_serial(writebyte, printBool=False)
|
|
1849
|
+
self.print_message("setting the touch() (" + str(x)+"," + str(y) + ")")
|
|
1850
|
+
return msgbytes
|
|
1851
|
+
|
|
1852
|
+
def preform_touch(self, x, y):
|
|
1853
|
+
#alias for touch()
|
|
1854
|
+
return self.touch(x,y)
|
|
1855
|
+
|
|
1856
|
+
|
|
1857
|
+
def touch_cal(self):
|
|
1858
|
+
# starts the touch calibration
|
|
1859
|
+
# usage: touchcal
|
|
1860
|
+
# example return: bytearray(b'')
|
|
1861
|
+
writebyte = 'touchcal\r\n'
|
|
1862
|
+
msgbytes = self.tinySA_serial(writebyte, printBool=False)
|
|
1863
|
+
self.print_message("starting touchcal")
|
|
1864
|
+
return msgbytes
|
|
1865
|
+
|
|
1866
|
+
def start_touch_cal(self):
|
|
1867
|
+
return self.touch_cal()
|
|
1868
|
+
|
|
1869
|
+
def touch_test(self):
|
|
1870
|
+
# starts the touch test
|
|
1871
|
+
# usage: touchtest
|
|
1872
|
+
# example return: bytearray(b'')
|
|
1873
|
+
|
|
1874
|
+
writebyte = 'touchtest\r\n'
|
|
1875
|
+
msgbytes = self.tinySA_serial(writebyte, printBool=False)
|
|
1876
|
+
self.print_message("starting the touch_test()")
|
|
1877
|
+
return msgbytes
|
|
1878
|
+
|
|
1879
|
+
def start_touch_test(self):
|
|
1880
|
+
return self.touch_test()
|
|
1881
|
+
|
|
1882
|
+
def trace_select(self, ID):
|
|
1883
|
+
# split call for TRACE. select an available trace
|
|
1884
|
+
if (isinstance(ID, int)) and ID >=0:
|
|
1885
|
+
writebyte = 'trace '+ str(ID) +'\r\n'
|
|
1886
|
+
msgbytes = self.tinySA_serial(writebyte, printBool=False)
|
|
1887
|
+
self.print_message("selecting trace")
|
|
1888
|
+
else:
|
|
1889
|
+
self.print_message("ERROR: trace numbers must be integers greater than 0. see device documentation for max")
|
|
1890
|
+
msgbytes = self.error_byte_return()
|
|
1891
|
+
return msgbytes
|
|
1892
|
+
|
|
1893
|
+
def trace_units(self, val):
|
|
1894
|
+
# split call for TRACE. set the units for the traces
|
|
1895
|
+
# explicitly allowed vals
|
|
1896
|
+
accepted_vals = ["dBm", "dBmV", "dBuV", "V", "W", "Vpp", "RAW"]
|
|
1897
|
+
|
|
1898
|
+
if (str(val) in accepted_vals):
|
|
1899
|
+
writebyte = 'trace '+ str(val) +'\r\n'
|
|
1900
|
+
msgbytes = self.tinySA_serial(writebyte, printBool=False)
|
|
1901
|
+
self.print_message("setting trace units to " + str(val))
|
|
1902
|
+
else:
|
|
1903
|
+
self.print_message("ERROR: trace vals can be 'dBm'|'dBmV'|'dBuV'|'RAW'|'V'|'Vpp'|'W'")
|
|
1904
|
+
msgbytes = self.error_byte_return()
|
|
1905
|
+
return msgbytes
|
|
1906
|
+
|
|
1907
|
+
def trace_scale(self, val="auto"):
|
|
1908
|
+
# split call for TRACE. scales a trace/traces.
|
|
1909
|
+
writebyte = 'trace scale' + str(val) + '\r\n'
|
|
1910
|
+
msgbytes = self.tinySA_serial(writebyte, printBool=False)
|
|
1911
|
+
self.print_message("scaling trace")
|
|
1912
|
+
return msgbytes
|
|
1913
|
+
|
|
1914
|
+
def trace_reflevel(self, val="auto"):
|
|
1915
|
+
# split call for TRACE. sets the reference level of a trace
|
|
1916
|
+
writebyte = 'trace reflevel' + str(val) + '\r\n'
|
|
1917
|
+
msgbytes = self.tinySA_serial(writebyte, printBool=False)
|
|
1918
|
+
self.print_message("setting reference level of trace")
|
|
1919
|
+
return msgbytes
|
|
1920
|
+
|
|
1921
|
+
def trace_value(self, ID):
|
|
1922
|
+
# split call for TRACE. gets values of trace
|
|
1923
|
+
|
|
1924
|
+
writebyte = 'trace' + str(ID) + 'value \r\n'
|
|
1925
|
+
msgbytes = self.tinySA_serial(writebyte, printBool=False)
|
|
1926
|
+
self.print_message("getting raw trace values")
|
|
1927
|
+
return msgbytes
|
|
1928
|
+
|
|
1929
|
+
def trace_toggle(self, ID, val="on"):
|
|
1930
|
+
# split call for TRACE. toggle trace ON or OFF
|
|
1931
|
+
# full description: displays all or one trace information
|
|
1932
|
+
# or sets trace related information
|
|
1933
|
+
# usage:
|
|
1934
|
+
# trace [ {0..2} |
|
|
1935
|
+
# dBm|dBmV|dBuV|V|W |store|clear|subtract | (scale|
|
|
1936
|
+
# reflevel) auto|{level}
|
|
1937
|
+
# example return:
|
|
1938
|
+
|
|
1939
|
+
accepted_vals = ["on", "off"]
|
|
1940
|
+
|
|
1941
|
+
if (isinstance(ID,int)) and (str(val) in accepted_vals):
|
|
1942
|
+
writebyte = 'trace' + str(ID) + ' ' +str(val)+ '\r\n'
|
|
1943
|
+
msgbytes = self.tinySA_serial(writebyte, printBool=False)
|
|
1944
|
+
self.print_message("toggling trace " +str(val))
|
|
1945
|
+
else:
|
|
1946
|
+
self.print_message("ERROR: trace ID is an Int, val='on'|'off'")
|
|
1947
|
+
msgbytes = self.error_byte_return()
|
|
1948
|
+
|
|
1949
|
+
return msgbytes
|
|
1950
|
+
|
|
1951
|
+
def trace_subtract(self, ID1, ID2):
|
|
1952
|
+
# split call for TRACE. subtracts a trace/traces.
|
|
1953
|
+
# subtract ID1 FROM ID2
|
|
1954
|
+
|
|
1955
|
+
if (isinstance(ID1,int)) and (isinstance(ID2,int)):
|
|
1956
|
+
writebyte = 'trace' + str(ID1) + ' subtract ' +str(ID2)+ '\r\n'
|
|
1957
|
+
msgbytes = self.tinySA_serial(writebyte, printBool=False)
|
|
1958
|
+
self.print_message("subtracting traces")
|
|
1959
|
+
else:
|
|
1960
|
+
self.print_message("ERROR: trace IDs must be Ints")
|
|
1961
|
+
msgbytes = self.error_byte_return()
|
|
1962
|
+
|
|
1963
|
+
return msgbytes
|
|
1964
|
+
|
|
1965
|
+
def trace_copy(self, ID1, ID2):
|
|
1966
|
+
# split call for TRACE. copies a trace/traces.
|
|
1967
|
+
|
|
1968
|
+
if (isinstance(ID1,int)) and (isinstance(ID2,int)):
|
|
1969
|
+
writebyte = 'trace' + str(ID1) + ' subtract ' +str(ID2)+ '\r\n'
|
|
1970
|
+
msgbytes = self.tinySA_serial(writebyte, printBool=False)
|
|
1971
|
+
self.print_message("copying traces")
|
|
1972
|
+
else:
|
|
1973
|
+
self.print_message("ERROR: trace IDs must be Ints")
|
|
1974
|
+
msgbytes = self.error_byte_return()
|
|
1975
|
+
|
|
1976
|
+
return msgbytes
|
|
1977
|
+
|
|
1978
|
+
def trace_freeze(self, ID):
|
|
1979
|
+
# split call for TRACE. freezes a trace
|
|
1980
|
+
|
|
1981
|
+
if (isinstance(ID,int)):
|
|
1982
|
+
writebyte = 'trace' + str(ID) + ' freeze\r\n'
|
|
1983
|
+
msgbytes = self.tinySA_serial(writebyte, printBool=False)
|
|
1984
|
+
self.print_message("freezing trace")
|
|
1985
|
+
else:
|
|
1986
|
+
self.print_message("ERROR: trace ID must be Ints")
|
|
1987
|
+
msgbytes = self.error_byte_return()
|
|
1988
|
+
|
|
1989
|
+
return msgbytes
|
|
1990
|
+
|
|
1991
|
+
|
|
1992
|
+
def trace_clear(self, val):
|
|
1993
|
+
# split call for TRACE. clears a trace/traces. doesnt seem to take inputs
|
|
1994
|
+
# full description: displays all or one trace information
|
|
1995
|
+
# or sets trace related information
|
|
1996
|
+
# usage:
|
|
1997
|
+
# trace [ {0..2} |
|
|
1998
|
+
# dBm|dBmV|dBuV|V|W |store|clear|subtract | (scale|
|
|
1999
|
+
# reflevel) auto|{level}
|
|
2000
|
+
# example return:
|
|
2001
|
+
|
|
2002
|
+
writebyte = 'trace ' + str(val) + 'clear \r\n'
|
|
2003
|
+
msgbytes = self.tinySA_serial(writebyte, printBool=False)
|
|
2004
|
+
self.print_message("clearing trace(s)")
|
|
2005
|
+
return msgbytes
|
|
2006
|
+
|
|
2007
|
+
|
|
2008
|
+
|
|
2009
|
+
def trace_freeze(self, ID):
|
|
2010
|
+
# split call for TRACE. sets the reference level of a trace
|
|
2011
|
+
# full description: displays all or one trace information
|
|
2012
|
+
# or sets trace related information
|
|
2013
|
+
# usage:
|
|
2014
|
+
# trace [ {0..2} |
|
|
2015
|
+
# dBm|dBmV|dBuV|V|W |store|clear|subtract | (scale|
|
|
2016
|
+
# reflevel) auto|{level}
|
|
2017
|
+
# example return:
|
|
2018
|
+
|
|
2019
|
+
writebyte = 'trace' + str(ID) + 'freeze \r\n'
|
|
2020
|
+
msgbytes = self.tinySA_serial(writebyte, printBool=False)
|
|
2021
|
+
self.print_message("freezing trace")
|
|
2022
|
+
return msgbytes
|
|
2023
|
+
|
|
2024
|
+
|
|
2025
|
+
|
|
2026
|
+
def trace_action(self, ID, val):
|
|
2027
|
+
# split call for TRACE. toggle trace ON or OFF
|
|
2028
|
+
# full description: displays all or one trace information
|
|
2029
|
+
# or sets trace related information
|
|
2030
|
+
# usage:
|
|
2031
|
+
# trace [ {0..2} |
|
|
2032
|
+
# dBm|dBmV|dBuV|V|W |store|clear|subtract | (scale|
|
|
2033
|
+
# reflevel) auto|{level}
|
|
2034
|
+
# example return:
|
|
2035
|
+
|
|
2036
|
+
accepted_vals = ["copy","freeze","subtract","view","value"]
|
|
2037
|
+
|
|
2038
|
+
if (isinstance(ID,int)) and (str(val) in accepted_vals):
|
|
2039
|
+
writebyte = 'trace' + str(ID) + ' ' +str(val)+ '\r\n'
|
|
2040
|
+
msgbytes = self.tinySA_serial(writebyte, printBool=False)
|
|
2041
|
+
self.print_message("setting trace action")
|
|
2042
|
+
else:
|
|
2043
|
+
self.print_message("ERROR: trace vals can be 'copy'|'freeze'|'subtract'|'view'|'value' and ID is an Int")
|
|
2044
|
+
msgbytes = self.error_byte_return()
|
|
2045
|
+
|
|
2046
|
+
return msgbytes
|
|
2047
|
+
|
|
2048
|
+
|
|
2049
|
+
|
|
2050
|
+
def trigger(self, val, freq=None):
|
|
2051
|
+
# sets the trigger type or level
|
|
2052
|
+
# usage: trigger auto|normal|single|{level(dBm)}
|
|
2053
|
+
# the trigger level is always set in dBm and is the only numerical input
|
|
2054
|
+
# example return:
|
|
2055
|
+
# #explicitly allowed vals
|
|
2056
|
+
accepted_vals = ["auto", "normal", "single"]
|
|
2057
|
+
|
|
2058
|
+
if str(val) in accepted_vals:
|
|
2059
|
+
writebyte = 'trigger ' + str(val) +'\r\n'
|
|
2060
|
+
msgbytes = self.tinySA_serial(writebyte, printBool=False)
|
|
2061
|
+
self.print_message("setting trigger to " + str(val))
|
|
2062
|
+
elif val==None and isinstance(freq,int):
|
|
2063
|
+
writebyte = 'trigger ' + str(freq) +'\r\n'
|
|
2064
|
+
msgbytes = self.tinySA_serial(writebyte, printBool=False)
|
|
2065
|
+
self.print_message("setting trigger level (dBm) to " + str(freq))
|
|
2066
|
+
else:
|
|
2067
|
+
self.print_message("ERROR: trigger takes inputs auto|normal|single|{level(dBm)}")
|
|
2068
|
+
msgbytes = self.error_byte_return()
|
|
2069
|
+
return msgbytes
|
|
2070
|
+
|
|
2071
|
+
def trigger_auto(self):
|
|
2072
|
+
# alias for trigger
|
|
2073
|
+
return self.trigger("auto")
|
|
2074
|
+
def trigger_normal(self):
|
|
2075
|
+
# alias for trigger
|
|
2076
|
+
return self.trigger("normal")
|
|
2077
|
+
def trigger_single(self):
|
|
2078
|
+
# alias for trigger
|
|
2079
|
+
return self.trigger("single")
|
|
2080
|
+
def trigger_level(self, val):
|
|
2081
|
+
# alias for trigger
|
|
2082
|
+
return self.trigger(None, val)
|
|
2083
|
+
|
|
2084
|
+
def ultra(self, val="off", freq=None):
|
|
2085
|
+
# turn on/config tiny SA ultra mode
|
|
2086
|
+
# usage: ultra off|on|auto|start|harm {freq}
|
|
2087
|
+
# example return: bytearray(b'')
|
|
2088
|
+
|
|
2089
|
+
# explicitly allowed vals
|
|
2090
|
+
accepted_vals = ["off", "on", "auto", "start", "harm"]
|
|
2091
|
+
|
|
2092
|
+
if str(val) in ["off", "on", "auto"]:
|
|
2093
|
+
writebyte = 'ultra ' + str(val) +'\r\n'
|
|
2094
|
+
msgbytes = self.tinySA_serial(writebyte, printBool=False)
|
|
2095
|
+
self.print_message("configuring ultra() " + str(val))
|
|
2096
|
+
elif str(val) in ["start", "harm"]:
|
|
2097
|
+
writebyte = 'ultra ' + str(val) + ' ' + str(freq) +'\r\n'
|
|
2098
|
+
msgbytes = self.tinySA_serial(writebyte, printBool=False)
|
|
2099
|
+
self.print_message("configuring ultra() " + str(val) + " at " + str(freq))
|
|
2100
|
+
else:
|
|
2101
|
+
self.print_message("ERROR: ultra() currently only takes on/off as args")
|
|
2102
|
+
msgbytes = self.error_byte_return()
|
|
2103
|
+
|
|
2104
|
+
return msgbytes
|
|
2105
|
+
|
|
2106
|
+
def set_ultra_on(self):
|
|
2107
|
+
return self.ultra("on")
|
|
2108
|
+
|
|
2109
|
+
def set_ultra_off(self):
|
|
2110
|
+
return self.ultra("off")
|
|
2111
|
+
|
|
2112
|
+
def set_ultra_auto(self):
|
|
2113
|
+
return self.ultra("auto")
|
|
2114
|
+
|
|
2115
|
+
def set_ultra_start(self, val):
|
|
2116
|
+
return self.ultra("start", val)
|
|
2117
|
+
|
|
2118
|
+
def set_ultra_harmonic(self, val):
|
|
2119
|
+
return self.ultra("harm", val)
|
|
2120
|
+
|
|
2121
|
+
def usart_cfg(self):
|
|
2122
|
+
# gets the current serial config
|
|
2123
|
+
# usage: usart_cfg
|
|
2124
|
+
# example return: bytearray(b'Serial: 115200 baud\r')
|
|
2125
|
+
|
|
2126
|
+
writebyte = 'usart_cfg\r\n'
|
|
2127
|
+
msgbytes = self.tinySA_serial(writebyte, printBool=False)
|
|
2128
|
+
self.print_message("usart_cfg() returning config vals")
|
|
2129
|
+
return msgbytes
|
|
2130
|
+
|
|
2131
|
+
def get_usart_cfg(self):
|
|
2132
|
+
#alias for usart_cfg()
|
|
2133
|
+
return self.usart_cfg()
|
|
2134
|
+
|
|
2135
|
+
|
|
2136
|
+
def vbat(self):
|
|
2137
|
+
# displays the battery voltage
|
|
2138
|
+
# usage: vbat
|
|
2139
|
+
# example return: bytearray(b'4132 mV\r')
|
|
2140
|
+
writebyte = 'vbat\r\n'
|
|
2141
|
+
msgbytes = self.tinySA_serial(writebyte, printBool=False)
|
|
2142
|
+
self.print_message("returning current battery voltage")
|
|
2143
|
+
return msgbytes
|
|
2144
|
+
|
|
2145
|
+
def get_vbat(self):
|
|
2146
|
+
# alias for vbat
|
|
2147
|
+
return self.vbat()
|
|
2148
|
+
|
|
2149
|
+
def vbat_offset(self, val=None):
|
|
2150
|
+
# displays or sets the battery offset value
|
|
2151
|
+
# usage: vbat_offset [{0..4095}]
|
|
2152
|
+
# example return: bytearray(b'300\r')
|
|
2153
|
+
|
|
2154
|
+
if val == None:
|
|
2155
|
+
#get the offset
|
|
2156
|
+
writebyte = 'vbat_offset\r\n'
|
|
2157
|
+
msgbytes = self.tinySA_serial(writebyte, printBool=False)
|
|
2158
|
+
elif (isinstance(val, (int, float))) and (0<= val <=4095):
|
|
2159
|
+
writebyte = 'vbat_offset '+str(val)+'\r\n'
|
|
2160
|
+
msgbytes = self.tinySA_serial(writebyte, printBool=False)
|
|
2161
|
+
self.print_message("vbat_offset set to " + str(val))
|
|
2162
|
+
else:
|
|
2163
|
+
self.print_message("ERROR: vbat_offset() takes either None or [0 - 4095] integers")
|
|
2164
|
+
msgbytes = self.error_byte_return()
|
|
2165
|
+
return msgbytes
|
|
2166
|
+
|
|
2167
|
+
def get_vbat_offset(self):
|
|
2168
|
+
# alias for vbat_offset()
|
|
2169
|
+
return self.vbat_offset()
|
|
2170
|
+
def set_vbat_offset(self, val):
|
|
2171
|
+
# alias for vbat_offset()
|
|
2172
|
+
return self.vbat_offset(val)
|
|
2173
|
+
|
|
2174
|
+
|
|
2175
|
+
def version(self):
|
|
2176
|
+
# displays the version text
|
|
2177
|
+
# usage: version
|
|
2178
|
+
# example return: tinySA4_v1.4-143-g864bb27\r\nHW Version:V0.4.5.1.1
|
|
2179
|
+
|
|
2180
|
+
writebyte = 'version\r\n'
|
|
2181
|
+
msgbytes = self.tinySA_serial(writebyte, printBool=False)
|
|
2182
|
+
self.print_message("getting device version information")
|
|
2183
|
+
return msgbytes
|
|
2184
|
+
|
|
2185
|
+
def get_version(self):
|
|
2186
|
+
# alias for version()
|
|
2187
|
+
return self.version()
|
|
2188
|
+
|
|
2189
|
+
def wait(self, val=0):
|
|
2190
|
+
# wait for a single sweep to finish and pauses
|
|
2191
|
+
# sweep or waits for specified number of seconds
|
|
2192
|
+
# usage: wait [{seconds}]
|
|
2193
|
+
# example return:
|
|
2194
|
+
|
|
2195
|
+
if val == None:
|
|
2196
|
+
writebyte = 'wait\r\n'
|
|
2197
|
+
msgbytes = self.tinySA_serial(writebyte, printBool=False)
|
|
2198
|
+
self.print_message("device in wait() state. manually resume")
|
|
2199
|
+
elif val>0:
|
|
2200
|
+
writebyte = 'wait ' + str(val) + '\r\n'
|
|
2201
|
+
msgbytes = self.tinySA_serial(writebyte, printBool=False)
|
|
2202
|
+
self.print_message("device wait() trigged for " + str(val) + " seconds.")
|
|
2203
|
+
else:
|
|
2204
|
+
self.print_message("ERROR: wait() takes None or positive ints")
|
|
2205
|
+
msgbytes = self.error_byte_return()
|
|
2206
|
+
return msgbytes
|
|
2207
|
+
|
|
2208
|
+
def zero(self, val):
|
|
2209
|
+
#get or set the zero offset in dBm
|
|
2210
|
+
# DO NOT CHANGE if unfamiliar with device and offset
|
|
2211
|
+
# usage: zero {level}\r\n174dBm
|
|
2212
|
+
# example return:
|
|
2213
|
+
|
|
2214
|
+
if val == None:
|
|
2215
|
+
writebyte = 'zero\r\n'
|
|
2216
|
+
msgbytes = self.tinySA_serial(writebyte, printBool=False)
|
|
2217
|
+
self.print_message("returning zero offset")
|
|
2218
|
+
else:
|
|
2219
|
+
writebyte = 'zero ' + str(val) + '\r\n'
|
|
2220
|
+
msgbytes = self.tinySA_serial(writebyte, printBool=False)
|
|
2221
|
+
self.print_message("device zero offset is " + str(val) + " dBm.")
|
|
2222
|
+
|
|
2223
|
+
return msgbytes
|
|
2224
|
+
|
|
2225
|
+
def get_zero_offset(self):
|
|
2226
|
+
# alias function for zero
|
|
2227
|
+
return self.zero()
|
|
2228
|
+
|
|
2229
|
+
|
|
2230
|
+
######################################################################
|
|
2231
|
+
# Device and library help
|
|
2232
|
+
######################################################################
|
|
2233
|
+
|
|
2234
|
+
def help(self, val=0):
|
|
2235
|
+
# val controls if the tinySA help is called or the
|
|
2236
|
+
# 1 = library_help(), everything else is the tinySA_help()
|
|
2237
|
+
|
|
2238
|
+
if val == 1:
|
|
2239
|
+
msgbytes = self.library_help()
|
|
2240
|
+
else:
|
|
2241
|
+
msgbytes = self.tinySA_help()
|
|
2242
|
+
return msgbytes
|
|
2243
|
+
|
|
2244
|
+
def library_help(self):
|
|
2245
|
+
self.print_message("Returning command options for this library")
|
|
2246
|
+
self.print_message("IN PROGRESS. Include tinySA_help.py")
|
|
2247
|
+
|
|
2248
|
+
return b''
|
|
2249
|
+
|
|
2250
|
+
def tinySA_help(self):
|
|
2251
|
+
# dumps a list of the available commands
|
|
2252
|
+
# usage: help
|
|
2253
|
+
# example return: bytearray(b'commands: freq time dac
|
|
2254
|
+
# nf saveconfig clearconfig zero sweep pause resume wait
|
|
2255
|
+
# repeat status caloutput save recall trace trigger
|
|
2256
|
+
# marker line usart_cfg vbat_offset color if if1 lna2
|
|
2257
|
+
# agc actual_freq freq_corr attenuate level sweeptime
|
|
2258
|
+
# leveloffset levelchange modulation rbw mode spur
|
|
2259
|
+
# lna direct ultra load ext_gain output deviceid
|
|
2260
|
+
# correction calc menu text remark\r\nOther commands:
|
|
2261
|
+
# version reset data frequencies scan hop scanraw test
|
|
2262
|
+
# touchcal touchtest usart capture refresh touch release
|
|
2263
|
+
# vbat help info selftest sd_list sd_read sd_delete
|
|
2264
|
+
# threads\r')
|
|
2265
|
+
|
|
2266
|
+
writebyte = 'help\r\n'
|
|
2267
|
+
msgbytes = self.tinySA_serial(writebyte, printBool=False)
|
|
2268
|
+
self.print_message("Returning command options for tinySA device")
|
|
2269
|
+
return msgbytes
|
|
2270
|
+
|
|
2271
|
+
|
|
2272
|
+
|
|
2273
|
+
######################################################################
|
|
2274
|
+
# Device Selection and Config Functions
|
|
2275
|
+
# TODO LATER
|
|
2276
|
+
# This is a quick template. there's more options that need to
|
|
2277
|
+
# be researched
|
|
2278
|
+
######################################################################
|
|
2279
|
+
|
|
2280
|
+
|
|
2281
|
+
|
|
2282
|
+
|
|
2283
|
+
######################################################################
|
|
2284
|
+
# Unit testing
|
|
2285
|
+
######################################################################
|
|
2286
|
+
|
|
2287
|
+
if __name__ == "__main__":
|
|
2288
|
+
# unit testing. not recomended to write program from here
|
|
2289
|
+
|
|
2290
|
+
# create a new tinySA object
|
|
2291
|
+
tsa = tinySA()
|
|
2292
|
+
# attempt to connect to previously discovered serial port
|
|
2293
|
+
#success = tsa.connect(port='COM10')
|
|
2294
|
+
|
|
2295
|
+
# attempt to autoconnect
|
|
2296
|
+
found_bool, connected_bool = tsa.autoconnect()
|
|
2297
|
+
|
|
2298
|
+
# if port open, then complete task(s) and disconnect
|
|
2299
|
+
if connected_bool == True: # or if success == True:
|
|
2300
|
+
print("device connected")
|
|
2301
|
+
tsa.set_verbose(True) #detailed messages
|
|
2302
|
+
tsa.set_error_byte_return(True) #get explicit b'ERROR'
|
|
2303
|
+
msg = tsa.get_device_id()
|
|
2304
|
+
print(msg)
|
|
2305
|
+
|
|
2306
|
+
|
|
2307
|
+
tsa.disconnect()
|
|
2308
|
+
else:
|
|
2309
|
+
print("ERROR: could not connect to port")
|
|
2310
|
+
|