Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

An unofficial Python API for the tinySA device line

License

NotificationsYou must be signed in to change notification settings

LC-Linkous/tinySA_python

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

AN UNOFFICIAL Python Library for the tinySA Device Series

A Non-GUI Python API class for the tinySA series of devices. This repository uses official resources and documentation but is NOT endorsed by the official tinySA product or company. See thereferences section for further reading. See theofficial tinySA resources for device features.

This library covers most documented commands for the tinySA device series. The documentation is sorted based on the serial command, with some provided usage examples. While some error checking exists in both the device and the library, it is not exhaustive. It is strongly suggested to read the official documentation before attempting to script with your device.

Done:

  • library commands for common args
  • documentation for original command usage and library functions
  • examples for basic functionality
  • some Debian-flavored Linux testing

Working on it:

  • filling in unfinished args and any new tinySA features
    • scan and scanraw occasionally throw back bad data. handled in an example, but actual fix in progress
    • trigger needs more alias funcs to cover full functionality
  • scanraw serial FROM DEVICE issues with the buffer. This is being explored see Example #3 inPlotting Data with Matplotlib for details.
  • An argparse option + some example scripts
  • Beginner notes, vocab, and some examples for common usage

Table of Contents

The tinySA Series of Devices

ThetinySA line of devices are a series of portable and pretty user-friendly devices with both spectrum analyzer and signal generator capabilities. There are four main versions, all of which share the same key features. The Ultra and Ultra Plus versions build off of the original tinySA Basic. They look very similar to theNanoVNA series, but are NOT the same device and have different functionalities.

The NanoVNA series is a handheld vector network analyzer (VNA), which measures the S-parameters (loosely: a type of response of a device or antenna) over at different frequencies, while a spectrum analyzer measures the amplitude of RF signals at different frequencies. There's a lot of overlap with the use of both devices, but the measurements are very different. A signal generator is exactly what it sounds like - it generates a signal at a specific frequency or frequencies at a specified power level.

Official documentation can be found athttps://tinysa.org/. The official Wiki is going to be more up to date than this repo with new versions and features, and they also have links to GUI-based software (which is also under development). Several community projects also exist on GitHub.

There is also a very active tinySA community athttps://groups.io/g/tinysa exploring the device capabilities and its many features.

The end of this README will have some references and links to supporting material, but it is STRONGLY suggested to do some basic research and become familiar with your device before attempting to script or write code for it.

Requirements

This project requires numpy, pandas and pyserial.

Use 'pip install -r requirements.txt' to install the following dependencies:

pyserialnumpypandas

The above dependencies are only for the API interfacing of the tinySA_python library. Additional dependencies should be installed if you are following the examples in this README. These can be installed with 'pip install -r test_requirements.txt':

pyserialnumpypandasmatplotlibpillowpyQt5

For anyone unfamiliar with using requirements files, or having issues with the libraries, these can also be installed manually in the terminal (we recommend a Python virtual environment) with:

pipinstallpyserialnumpypandasmatplotlibpillowpyQt5

pyQt5 is used withmatplotlib to draw the figures. It needs to be installed on Linux systems to follow the examples included in tinySA_python, but is not needed on all Windows machines.

Library Usage

This library is currently only available as the tinySA class in 'tinySA_python.py' in this repository. It is very much under development and missing some key error checking and handling. HOWEVER, ‘any’ error checking is currently more than the ‘no’ error checking provided by interfacing directly with the device. The code that is included in this repository has been tested on at least one tinySA device and is relatively stable.

Several usage examples are provided in theExample Implementations section, including working with the hardware and plotting results with matplotlib.

Error Handling

Some error handling has been implemented for the individual functions in this library, but not for the device configuration. Most functions have a list of acceptable formats for input, which is included in the documentation and thelibrary_help function. ThetinySA_help function will get output from the current version of firmware running on the connected tinySA device.

Detailed error messages can be returned by toggling 'verbose' on.

From theofficial wiki USB Interface page:

There is limited error checking against incorrect parameters or incorrect device mode. Some error checking will be integrated as the device configurations are included, but this is not intended to be exhaustive.

Some error checking includes:

  • Frequencies can be specified using an integer optionally postfixed with a the letter 'k' for kilo 'M' for Mega or 'G' for Giga. E.g. 0.1M (100kHz), 500k (0.5MHz) or 12000000 (12MHz)
  • Levels are specified in dB(m) and can be specified using a floating point notation. E.g. 10 or 2.5
  • Time is specified in seconds optionally postfixed with the letters 'm' for mili or 'u' for micro. E.g. 1 (1 second), 2.5 (2.5 seconds), 120m (120 milliseconds)

Example Implementations

This library was developed on Windows and has been lightly tested on Linux. The main difference (so far) has been in the permissions for first access of the serial port, but there may be smaller bugs in format that have not been detected yet.

Finding the Serial Port

To start, a serial connection between the tinySA and user PC device must be created. There are several ways to list available serial ports. The library supports some rudimentary autodetection, but if that does not work instructions in this section also support manual detection.

Autoconnection with the tinySA_python Library

The tinySA_python currently has some autodetection capabilities, but these are new and not very complex. If multiple devices have the same VID, then the first one found is used. If you are connecting multiple devices to a user PC, then it is suggested to connect them manually (for now).

# import tinySA library# (NOTE: check library path relative to script path)fromsrc.tinySA_pythonimporttinySA# create a new tinySA objecttsa=tinySA()# set the return message preferencestsa.set_verbose(True)#detailed messagestsa.set_error_byte_return(True)#get explicit b'ERROR' if error thrown# attempt to autoconnectfound_bool,connected_bool=tsa.autoconnect()# if port found and connected, then complete task(s) and disconnectifconnected_bool==True:print("device connected")msg=tsa.get_device_id()print(msg)tsa.disconnect()else:print("ERROR: could not connect to port")

Manually Finding a Port on Windows

  1. OpenDevice Manager, scroll down toPorts (COM & LPT), and expand the menu. There should be aCOM# port listing "USB Serial Device(COM #)". If your tinySA Ultra is set up to work with Serial, this will be it.

  2. This uses the pyserial library requirement already installed for this library. It probably also works on Linux systems, but has not been tested yet.

importserial.tools.list_portsports=serial.tools.list_ports.comports()forport,desc,hwidinports:print(f"Port:{port}, Description:{desc}, Hardware ID:{hwid}")

Example output for this method (on Windows) is as follows:

Port:COM4,Description:StandardSerialoverBluetoothlink (COM4),HardwareID:BTHENUM\{00001101-0000-1000-8000-00805F9B34FB}_LOCALMFG&0000\7&D0D1EE&0&000000000000_00000000Port:COM3,Description:StandardSerialoverBluetoothlink (COM3),HardwareID:BTHENUM\{00001101-0000-1000-8000-00805F9B34FB}_LOCALMFG&0002\7&D0D1EE&0&B8B3DC31CBA8_C00000000Port:COM10,Description:USBSerialDevice (COM10),HardwareID:USBVID:PID=0483:5740SER=400LOCATION=1-3

"COM10" is the port location of the tinySA Ultra that is used in the examples in this README.

Manually Finding a Port on Linux

importserial.tools.list_portsports=serial.tools.list_ports.comports()forport,desc,hwidinports:print(f"Port:{port}, Description:{desc}, Hardware ID:{hwid}")
Port:/dev/ttyS0,Description:n/a,HardwareID:n/aPort:/dev/ttyS3,Description:n/a,HardwareID:n/aPort:/dev/ttyS2,Description:n/a,HardwareID:n/aPort:/dev/ttyS1,Description:n/a,HardwareID:n/aPort:/dev/ttyACM0,Description:tinySA4,HardwareID:USBVID:PID=0483:5740SER=400LOCATION=3-3:1.0

This method identified the/dev/ttyACM0. Now, when attempting to use the autoconnect feature, the following error was initially returned:

[Errno13]couldnotopenport/dev/ttyACM0: [Errno13]Permissiondenied:'/dev/ttyACM0'

This was due to not having permission to access the port. In this case, this error was solved by opening a terminal and executingsudo chmod a+rw /dev/ttyACM0. Should this issue be persistent, other solutions related to user groups and access will need to be investigated.

Serial Message Return Format

This library returns strings as cleaned byte arrays. The command and first\r\n pair are removed from the front, and thech> is removed from the end of the tinySA serial return.

The original message format:

bytearray(b'deviceid\r\ndeviceid 0\r\nch>')

Cleaned version:

bytearray(b'deviceid 0\r')

Connecting and Disconnecting the Device

This example shows the process for initializing, opening the serial port, getting device info, and disconnecting.

# import the library class for the tinySA# (NOTE: check library path relative to script path)fromsrc.tinySA_pythonimporttinySA# create a new tinySA objecttsa=tinySA()# set the return message preferencestsa.set_verbose(True)#detailed messagestsa.set_error_byte_return(True)#get explicit b'ERROR' if error thrown# attempt to connect to previously discovered serial portsuccess=tsa.autoconnect()# if port open, then get device information and disconnectifsuccess==False:print("ERROR: could not connect to port")else:msg=tsa.info()print(msg)tsa.disconnect()

Example output for this method is as follows:

bytearray(b'tinySA ULTRA\r\n2019-2024 Copyright @Erik Kaashoek\r\n2016-2020 Copyright @edy555\r\nSW licensed under GPL. See: https://github.com/erikkaashoek/tinySA\r\nVersion: tinySA4_v1.4-143-g864bb27\r\nBuild Time: Jan 10 2024 - 11:14:08\r\nKernel: 4.0.0\r\nCompiler: GCC 7.2.1 20170904 (release) [ARM/embedded-7-branch revision 255204]\r\nArchitecture: ARMv7E-M Core Variant: Cortex-M4F\r\nPort Info: Advanced kernel mode\r\nPlatform: STM32F303xC Analog & DSP\r')

Toggle Error Messages

The following can be used to turn on or off returned error messages.

  1. the 'verbose' option. When enabled, detailed messages are printed out.
# detailed messages are ONtsa.set_verbose(True)# detailed messages are OFFtsa.set_verbose(False)
  1. the 'errorByte' option. When enabled, if there is an error with the command or configuration,b'ERROR' is returned instead of the defaultb''.
# when an error occurs, b'ERROR' is returnedtsa.set_error_byte_return(True)# when an error occurs, the default b'' might be returnedtsa.set_error_byte_return(False)

Device and Library Help

There are three options for help() with this library.

# the default help function# 1 = help for this library, other values call the tinySA device help functiontsa.help(1)# calling the library help function directlytsa.library_help()# calling the tinySA device help directlytsa.tinySA_help()

All three return a bytearray in the formatbytearray(b'commands:......')

Setting tinySA Parameters

TODO when error checking is complete to show multiple examples

Getting Data from Active Screen

See other sections for the following examples:

This example shows several types of common data requests:

# import the library class for the tinySA# (NOTE: check library path relative to script path)fromsrc.tinySA_pythonimporttinySA# create a new tinySA objecttsa=tinySA()# set the return message preferencestsa.set_verbose(True)#detailed messagestsa.set_error_byte_return(True)#get explicit b'ERROR' if error thrown# attempt to connect to previously discovered serial portsuccess=tsa.autoconnect()# if port open, then complete task(s) and disconnectifsuccess==False:print("ERROR: could not connect to port")else:# get current trace data on screenmsg=tsa.data(val=2)print(msg)# set current device IDmsg=tsa.device_id(3)print(msg)# get current device IDmsg=tsa.device_id()print(msg)# get device informationmsg=tsa.info()print(msg)# pause sweepingmsg=tsa.pause()print(msg)# resume sweepingmsg=tsa.resume()print(msg)# get current battery voltage (mV)msg=tsa.vbat()print(msg)tsa.disconnect()

Saving Screen Images

Thecapture() function can be used to capture the screen and output it to an image file. Note that the screen size varies by device. The library itself does not have a function for saving to an image (requires an additional library), but examples and the CLI wrapper have this functionality.

This example truncates the last hex value, so a single paddingx00 value has been added. This will eventually be investigated, but it's not hurting the output right now.

# import the library class for the tinySA# (NOTE: check library path relative to script path)fromsrc.tinySA_pythonimporttinySA# imports FOR THE EXAMPLEimportnumpyasnpfromPILimportImageimportstructdefconvert_data_to_image(data_bytes,width,height):# this is not a particularly pretty example, and the data_bytes is sometimes a byte short# calculate the expected data sizeexpected_size=width*height*2# 16 bits per pixel (RGB565), 2 bytes per pixel# error checking - brute force, but fine while developingiflen(data_bytes)<expected_size:print(f"Data size is too small. Expected{expected_size} bytes, got{len(data_bytes)} bytes.")# if the data size is off by 1 byte, add a padding byteiflen(data_bytes)==expected_size-1:print("Data size is 1 byte smaller than expected. Adding 1 byte of padding.")# add a padding byte (0x00) to make the size matchdata_bytes.append(0)else:returneliflen(data_bytes)>expected_size:# truncate the data to the expected size (in case it's larger than needed)data_bytes=data_bytes[:expected_size]print("Data is larger than the expected size. truncating. check data.")# unpack the byte array to get pixel values (RGB565 format)num_pixels=width*height# unpacking as unsigned shorts (2 bytes each)x=struct.unpack(f">{num_pixels}H",data_bytes)# convert the RGB565 to RGBAarr=np.array(x,dtype=np.uint32)arr=0xFF000000+ ((arr&0xF800)>>8)+ ((arr&0x07E0)<<5)+ ((arr&0x001F)<<19)# reshape array to match the image dimensions. (height, width) formatarr=arr.reshape((height,width))# create the imageimg=Image.frombuffer('RGBA', (width,height),arr.tobytes(),'raw','RGBA',0,1)# save the imageimg.save("capture_example.png")# show the imageimg.show()# create a new tinySA objecttsa=tinySA()# set the return message preferencestsa.set_verbose(True)#detailed messagestsa.set_error_byte_return(True)#get explicit b'ERROR' if error thrown# attempt to connect to previously discovered serial portsuccess=tsa.autoconnect()# if port closed, then return error messageifsuccess==False:print("ERROR: could not connect to port")else:# port open, complete task(s) and disconnect# get the trace datadata_bytes=tsa.capture()print(data_bytes)tsa.disconnect()# processing after disconnect (just for this example)# test with 480x320 resolution for tinySA Ultraconvert_data_to_image(data_bytes,480,320)

Capture of On-screen Trace Data

Capture On-Screen Trace Data of a Frequency Sweep from 100 kHz to 800 kHz

Plotting Data with Matplotlib

Example 1: Plot using On-Screen Trace Data and Frequencies

This example plots the last/current sweep of data from the tinySA device.data() gets the trace data.frequencies() gets the frequency values used.byteArrayToNumArray(byteArr) takes in the returned trace data and frequencybytearrays and converts them to arrays that are then plotted usingmatplotlib

This example works becausedata() returns a trace, which is going to be the same dimensionality of thefrequencies() return because they have the sameRBW

# import tinySA library# (NOTE: check library path relative to script path)fromsrc.tinySA_pythonimporttinySA# import matplotlib FOR THE EXAMPLEimportmatplotlib.pyplotasplt# functions used in this exampledefbyteArrayToNumArray(byteArr,enc="utf-8"):# decode the bytearray to a stringdecodedStr=byteArr.decode(enc)# split the string by newline charactersstringVals=decodedStr.splitlines()# convert each value to a floatfloatVals= [float(val)forvalinstringVals]returnfloatVals# create a new tinySA objecttsa=tinySA()# set the return message preferencestsa.set_verbose(True)#detailed messagestsa.set_error_byte_return(True)#get explicit b'ERROR' if error thrown# attempt to connect to previously discovered serial portsuccess=tsa.autoconnect()# if port closed, then return error messageifsuccess==False:print("ERROR: could not connect to port")else:# port open, complete task(s) and disconnect# get the trace datadata_bytes=tsa.data()print(data_bytes)# get the frequencies used by the last sweepfreq_bytes=tsa.frequencies()tsa.disconnect()# processing after disconnect (just for this example)dataVals=byteArrayToNumArray(data_bytes)print(len(dataVals))# length of 450 data pointsfreqVals=byteArrayToNumArray(freq_bytes)print(len(freqVals))# length of 450 data points# create the plotplt.plot(freqVals,dataVals)# add labels and titleplt.xlabel('Frequency (Hz)')plt.ylabel('Measured Data (dBm)')plt.title('tinySA Trace Plot')# show the plotplt.show()

Plot of On-screen Trace Data

Plotted On-Screen Trace Data of a Frequency Sweep from 100 kHz to 800 MHz

Example 2: Plot using Scan Data and Frequencies

This example usesscan() to take a data measurement of data that DOES NOT need to be on the screen, unlikeExample 1 above. Then, the frequencies on the x-axis are calculated between thestart andstop frequencies using thenumber of points. This is done becausefrequencies() would have the values of the last scan, which are connected toRBW and not thenumber of points.

# import tinySA library# (NOTE: check library path relative to script path)fromsrc.tinySA_pythonimporttinySA# imports FOR THE EXAMPLEimportnumpyasnpimportmatplotlib.pyplotaspltdefconvert_data_to_arrays(start,stop,pts,data):# using the start and stop frequencies, and the number of points,freq_arr=np.linspace(start,stop,pts)# note that the decimals might go out to many places.# you can truncate this because it’s only used# for plotting in this example# As of the Jan. 2024 build in some data returned with SWEEP or SCAN calls there is error data.# https://groups.io/g/tinysa/topic/tinasa_ultra_sweep_command/104194367# this shows up as "-:.000000e+01".# TEMP fix - replace the colon character with a -10. This puts the 'filled in' points around the noise floor.# more advanced filtering should be applied for actual analysis.data1=bytearray(data.replace(b"-:.0",b"-10.0"))# get both values in each row returned (for reference)#data_arr = [list(map(float, line.split())) for line in data.decode('utf-8').split('\n') if line.strip()]# get first value in each returned rowdata_arr= [float(line.split()[0])forlineindata1.decode('utf-8').split('\n')ifline.strip()]returnfreq_arr,data_arr# create a new tinySA objecttsa=tinySA()# set the return message preferencestsa.set_verbose(True)#detailed messagestsa.set_error_byte_return(True)#get explicit b'ERROR' if error thrown# attempt to autoconnectfound_bool,connected_bool=tsa.autoconnect()# if port closed, then return error messageifconnected_bool==False:print("ERROR: could not connect to port")else:# if port found and connected, then complete task(s) and disconnect# set scan valuesstart=int(1e9)# 1 GHzstop=int(3e9)# 3 GHzpts=450# sample pointsoutmask=2# get measured data (y axis)# scandata_bytes=tsa.scan(start,stop,pts,outmask)print(data_bytes)tsa.resume()#resume so screen isn't still frozentsa.disconnect()# processing after disconnect (just for this example)# convert data to 2 arraysfreq_arr,data_arr=convert_data_to_arrays(start,stop,pts,data_bytes)# plotplt.plot(freq_arr,data_arr)plt.xlabel("Frequency (Hz)")plt.ylabel("Measured Data (dBm)")plt.title("tinySA Scan Plot")plt.show()

Plot of Scan Data

Plotted Scan Data of a Frequency Sweep from 1 GHz to 3 GHz

Example 3: Plot using SCAN and SCANRAW Data and Calculated Frequencies

This example usesscan() andscanraw() to take a data measurement of data that DOES NOT need to been on the screen, unlikeExample 1 above. Then, the frequencies on the x-axis are calculated between thestart andstop frequencies using thenumber of points. This is done becausefrequencies() would have the values of the last scan, which are connected toRBW and not thenumber of points.

Extra processing needs to be done to getdBm power fromscanraw().

NOTE FOR LINUX USERS: the serial read with SCANRAW is finicky. It's also ONLY with this function on Linux. Reading the serial buffer after SCANRAW failed in several situations:

  1. Requesting data too quickly after the last read
    • Expected, as the tinySA needs to resume and re-measure.
  2. Requesting data when the screen is frozen
    • Mildly expected, user error can trigger this too. Turns out in some situations, the frozen screen is not the same as apause, and there is no data to flush from the buffer because no more data has been taken. This is either a safe error state, a feature of how SCANRAW works, or potentially a bug with the device/firmware/this library. Using theresume() function after this will restart measurements.
  3. {UNKNOWN}. There are several conditions that can cause issues, but it's unclear what 'symptoms' go to which problems
    • On the first few reads after the tinySA has been turned on and operational for at least 1 minute.
    • After sitting unused for more than a few minutes the returned buffer is < 50% the expected size or more than 5x the expected size. This is AFTER the flush command.
# import tinySA library# (NOTE: check library path relative to script path)fromsrc.tinySA_pythonimporttinySA# imports FOR THE EXAMPLEimportnumpyasnpimportmatplotlib.pyplotaspltimportstructdefconvert_data_to_arrays(start,stop,pts,data):# FOR PLOTTING# using the start and stop frequencies, and the number of points,freq_arr=np.linspace(start,stop,pts)# note that the decimals might go out to many places.# you can truncate this because its only used# for plotting in this example# As of the Jan. 2024 build in some data returned with SWEEP or SCAN calls there is error data.# https://groups.io/g/tinysa/topic/tinasa_ultra_sweep_command/104194367# this shows up as "-:.000000e+01".# TEMP fix - replace the colon character with a -10. This puts the 'filled in' points around the noise floor.# more advanced filtering should be applied for actual analysis.data1=bytearray(data.replace(b"-:.0",b"-10.0"))# get both values in each row returned (for reference)#data_arr = [list(map(float, line.split())) for line in data.decode('utf-8').split('\n') if line.strip()]# get first value in each returned rowdata_arr= [float(line.split()[0])forlineindata1.decode('utf-8').split('\n')ifline.strip()]# NOTE: if repeated read errors with utf-8 occur, uncomment the below as an alternative to the# line above. This will show you what value is being returned that caused the problem. It may# indicate a different problem with the serial connection permissions# data_arr = []# for i, line in enumerate(data1.decode('utf-8').split('\n')):#     print(f"Line {i}: '{line}'")  # Show the raw line#     line = line.strip()#     if line:#         try:#             value = float(line.split()[0])#             data_arr.append(value)#             # print(f"  Parsed float: {value}")#         except ValueError as e:#             print(f"  Could not convert line to float: {line} — Error: {e}")returnfreq_arr,data_arr# create a new tinySA objecttsa=tinySA()# set the return message preferencestsa.set_verbose(True)#detailed messagestsa.set_error_byte_return(True)#get explicit b'ERROR' if error thrown# attempt to autoconnectfound_bool,connected_bool=tsa.autoconnect()# if port closed, then return error messageifconnected_bool==False:print("ERROR: could not connect to port")else:# if port found and connected, then complete task(s) and disconnect# set scan valuesstart=int(150e6)# 150 MHzstop=int(500e6)# 500 MHzpts=450# for tinySA Ultraoutmask=2# get measured data (y axis)# scan raw call - reads until end of stream# this CAN be run in a loop. the limiting factor is time to plot.# SCANscan_data_bytes=tsa.scan(start,stop,pts,outmask)# SCAN RAWscanraw_data_bytes=tsa.scan_raw(start,stop,pts,outmask)# for subsequent reads, the tinySA does freeze while preforming SCANRAW# if there's an error, the screen will stay frozen (for reading).# So start it again so new data can be takentsa.resume()# disconnect because we don't need the tinySA to process datatsa.disconnect()# process the SCAN data (this is already in dBm)# convert data to 2 arrays for X and Yfreq_arr,data_arr=convert_data_to_arrays(start,stop,pts,scan_data_bytes)# PROCESS SCANRAW into an array & reuse the FREQ_ARR value# remove the intro curly brace ({)bin_scanraw=scanraw_data_bytes[1:]#skip the first char because it's the raminaing curly brace# use struct.unpack() because of the repeating pattern# <: indicates little-endian byte order, meaning the least significant byte is stored first# 'xH'*pts: a repetition of the format 'xH' once per point.# 'x': represents a pad byte, which is ignored# 'H': represents an unsigned short integer (2 bytes)expected_len=3*ptsactual_len=len(bin_scanraw)print(f"Expected length:{expected_len}, Actual length:{actual_len}")ifactual_len==expected_len:# SCANRAW has returned the expected amount of data for the read.# sometimes this function (and not SCAN) does not read the buffer properly# a fix is in progress for LINUX systems. it works fine for Windowsprocessed_scanraw=struct.unpack('<'+'xH'*pts,bin_scanraw )# ignore trailing '}ch> 'processed_scanraw=np.array(processed_scanraw,dtype=np.uint16 ).reshape(-1,1)#unit8 has overflow error# CONVERT to dBm Power# take the processed binary data and convert it to dBm.# The equation is from tinySA.org & official documentationSCALE_FACTOR=174# tinySA Basic: 128, tinySA Ultra and newer is 174dBm_data=processed_scanraw/32-SCALE_FACTORprint(dBm_data)# plotplt.plot(freq_arr,data_arr,label='SCAN data')plt.plot(freq_arr,dBm_data,label='SCANRAW data')plt.xlabel("frequency (hz)")plt.ylabel("measured data (dBm)")plt.title("tinySA SCAN and SCANRAW data")plt.legend()plt.show()else:print("SCANRAW did not return the expected amount of data for the read")

Plot of SCAN and SCANRAW  Data

Plotted SCAN and SCANRAW Data of a Frequency Sweep from 150 MHz to 500 MHz

Example 4: Plot a Waterfall using SCAN and Calculated Frequencies

# import tinySA library# (NOTE: check library path relative to script path)fromsrc.tinySA_pythonimporttinySA# imports FOR THE EXAMPLEimportcsvimportnumpyasnpimportmatplotlib.pyplotaspltimporttimefromdatetimeimportdatetimedefconvert_data_to_arrays(start,stop,pts,data):# using the start and stop frequencies, and the number of points,freq_arr=np.linspace(start,stop,pts)# note that the decimals might go out to many places.# you can truncate this because its only used# for plotting in this example# As of the Jan. 2024 build in some data returned with SWEEP or SCAN calls there is error data.# https://groups.io/g/tinysa/topic/tinasa_ultra_sweep_command/104194367# this shows up as "-:.000000e+01".# TEMP fix - replace the colon character with a -10. This puts the 'filled in' points around the noise floor.# more advanced filtering should be applied for actual analysis.data1=bytearray(data.replace(b"-:.0",b"-10.0"))# get both values in each row returned (for reference)#data_arr = [list(map(float, line.split())) for line in data.decode('utf-8').split('\n') if line.strip()]# get first value in each returned rowdata_arr= [float(line.split()[0])forlineindata1.decode('utf-8').split('\n')ifline.strip()]returnfreq_arr,data_arrdefcollect_waterfall_data(tsa,start,stop,pts,outmask,num_scans,scan_interval):waterfall_data= []# 2D array of scan data (time x frequency)timestamps= []freq_arr=Noneprint(f"Collecting{num_scans} scans with{scan_interval}s intervals...")foriinrange(num_scans):print(f"Scan{i+1}/{num_scans}")# Perform scandata_bytes=tsa.scan(start,stop,pts,outmask)# Convert to arraysiffreq_arrisNone:freq_arr,data_arr=convert_data_to_arrays(start,stop,pts,data_bytes)else:_,data_arr=convert_data_to_arrays(start,stop,pts,data_bytes)# Store data and timestampwaterfall_data.append(data_arr)timestamps.append(datetime.now())# Wait before next scan (except for last scan)ifi<num_scans-1:time.sleep(scan_interval)returnfreq_arr,np.array(waterfall_data),timestampsdefplot_waterfall(freq_arr,waterfall_data,timestamps,start,stop):# Create figure with subplotsfig, (ax1,ax2)=plt.subplots(2,1,figsize=(12,10))# Waterfall plot (main plot)# Create time array for y-axis (scan number or elapsed time)time_arr=np.arange(len(timestamps))# Create meshgrid for pcolormeshfreq_mesh,time_mesh=np.meshgrid(freq_arr,time_arr)# Plot waterfallim=ax1.pcolormesh(freq_mesh/1e9,time_mesh,waterfall_data,shading='nearest',cmap='viridis')ax1.set_xlabel('Frequency (GHz)')ax1.set_ylabel('Scan Number')ax1.set_title(f'Waterfall Plot:{start/1e9:.1f} -{stop/1e9:.1f} GHz')# Add colorbarcbar=plt.colorbar(im,ax=ax1)cbar.set_label('Signal Strength (dBm)')# Latest scan plot (bottom subplot)ax2.plot(freq_arr/1e9,waterfall_data[-1])ax2.set_xlabel('Frequency (GHz)')ax2.set_ylabel('Signal Strength (dBm)')ax2.set_title('Latest Scan')ax2.grid(True,alpha=0.3)plt.tight_layout()returnfig# create a new tinySA objecttsa=tinySA()# set the return message preferencestsa.set_verbose(True)#detailed messagestsa.set_error_byte_return(True)#get explicit b'ERROR' if error thrown# attempt to autoconnectfound_bool,connected_bool=tsa.autoconnect()# if port closed, then return error messageifconnected_bool==False:print("ERROR: could not connect to port")else:# if port found and connected, then complete task(s) and disconnecttry:# set scan valuesstart=int(1e9)# 1 GHzstop=int(3e9)# 3 GHzpts=450# sample pointsoutmask=2# get measured data (y axis)# waterfall parametersnum_scans=50# number of scans to collectscan_interval=0.5# seconds between scans# collect waterfall datafreq_arr,waterfall_data,timestamps=collect_waterfall_data(tsa,start,stop,pts,outmask,num_scans,scan_interval)print("Data collection complete!")# resume and disconnecttsa.resume()#resume so screen isn't still frozentsa.disconnect()# processing after disconnectprint("Creating waterfall plot...")# create waterfall plotfig=plot_waterfall(freq_arr,waterfall_data,timestamps,start,stop)# Save data out to .csvfilename="waterfall_1_sample.csv"# Create CSV with frequency headers and time/scan datawithopen(filename,'w',newline='')ascsvfile:writer=csv.writer(csvfile)# Write header row with frequencies (in Hz)header= ['Scan_Number','Timestamp']+ [f'{freq:.0f}'forfreqinfreq_arr]writer.writerow(header)# Write data rowsfori, (scan_data,timestamp)inenumerate(zip(waterfall_data,timestamps)):row= [i+1,timestamp.strftime('%Y-%m-%d %H:%M:%S.%f')[:-3]]+scan_data.tolist()writer.writerow(row)print(f"Data saved to{filename}")print(f"CSV contains{len(waterfall_data)} scans with{len(freq_arr)} frequency points each")# show plotplt.show()exceptKeyboardInterrupt:print("\nScan interrupted by user")tsa.resume()tsa.disconnect()exceptExceptionase:print(f"Error occurred:{e}")tsa.resume()tsa.disconnect()

Waterfall Plot for SCAN Data Over 50 Readings

Waterfall Plot for SCAN Data Over 50 Readings

Saving SCAN Data to CSV

# import tinySA library# (NOTE: check library path relative to script path)fromsrc.tinySA_pythonimporttinySA# imports FOR THE EXAMPLEimportcsvimportnumpyasnpdefconvert_data_to_arrays(start,stop,pts,data):# using the start and stop frequencies, and the number of points,freq_arr=np.linspace(start,stop,pts)# note that the decimals might go out to many places.# you can truncate this because its only used# for plotting in this example# As of the Jan. 2024 build in some data returned with SWEEP or SCAN calls there is error data.# https://groups.io/g/tinysa/topic/tinasa_ultra_sweep_command/104194367# this shows up as "-:.000000e+01".# TEMP fix - replace the colon character with a -10. This puts the 'filled in' points around the noise floor.# more advanced filtering should be applied for actual analysis.data1=bytearray(data.replace(b"-:.0",b"-10.0"))# get both values in each row returned (for reference)#data_arr = [list(map(float, line.split())) for line in data.decode('utf-8').split('\n') if line.strip()]# get first value in each returned rowdata_arr= [float(line.split()[0])forlineindata1.decode('utf-8').split('\n')ifline.strip()]returnfreq_arr,data_arr# create a new tinySA objecttsa=tinySA()# set the return message preferencestsa.set_verbose(True)#detailed messagestsa.set_error_byte_return(True)#get explicit b'ERROR' if error thrown# attempt to autoconnectfound_bool,connected_bool=tsa.autoconnect()# if port closed, then return error messageifconnected_bool==False:print("ERROR: could not connect to port")else:# if port found and connected, then complete task(s) and disconnect# set scan valuesstart=int(1e9)# 1 GHzstop=int(3e9)# 3 GHzpts=450# sample pointsoutmask=2# get measured data (y axis)# scandata_bytes=tsa.scan(start,stop,pts,outmask)print(data_bytes)tsa.resume()#resume so screen isn't still frozentsa.disconnect()# processing after disconnect (just for this example)# convert data to 2 arraysfreq_arr,data_arr=convert_data_to_arrays(start,stop,pts,data_bytes)# Save the data to CSVfilename="scan_sample.csv"# Write out to csv where column 1 is frequency and col 2 is datawithopen(filename,'w',newline='')ascsvfile:writer=csv.writer(csvfile)# Write header rowwriter.writerow(['Frequency_Hz','Signal_Strength_dBm'])# Write data rows (frequency, signal strength pairs)forfreq,signalinzip(freq_arr,data_arr):writer.writerow([f'{freq:.0f}',signal])print(f"Data saved to{filename}")print(f"CSV contains{len(freq_arr)} frequency/signal pairs")print(f"Data saved to{filename}")

Accessing the tinySA Directly

In some cases, this library may not cover all possible command versions, or new features might not be included yet. The tinySA can be accessed directly using thecommand() function. There is NO ERROR CHECKING on this function. It takes the full argument, just as if arguments were entered on the command line.

# import tinySA library# (NOTE: check library path relative to script path)fromsrc.tinySA_pythonimporttinySA# create a new tinySA objecttsa=tinySA()# set the return message preferencestsa.set_verbose(True)#detailed messagestsa.set_error_byte_return(True)#get explicit b'ERROR' if error thrown# attempt to autoconnectfound_bool,connected_bool=tsa.autoconnect()# if port closed, then return error messageifconnected_bool==False:print("ERROR: could not connect to port")else:# if port found and connected, then complete task(s) and disconnect# set scan valuesstart=150e6# 150 MHzstop=200e6# 200 MHzpts=450# for tinySA Ultraoutmask=1# get measured data (y axis)# scandata_bytes=tsa.command("scan 150e6 200e6 5 2")print(data_bytes)tsa.resume()#resumetsa.disconnect()

List of tinySA Commands and their Library Commands

Library functions are organized based on the command passed to the device. For example, any functions with shortcuts for using thesweep command will be grouped undersweep. This list and the following list in theAdditional Library Commands section describe the functions in this library.

This section is sorted by the tinySA (Ultra) commands, and includes:

  • A brief description of what the command does
  • What the original usage looked like
  • The tinySA_python function call, or calls if multiple options exist
  • Example return, or example format of return
  • Any additional notes about the usage

All of the listed commands are included in this API to some degree, but error checking may be incomplete.

Quick Link Table:

abortactual_freqagcattenuatebulkcalccaloutput
captureclearconfigcolorcorrectiondacdatadeviceid
directext_gainfillfreqfreq_corrfrequencieshelp
hopifif1infolevellevelchangeleveloffset
lineloadlnalna2markermenumode
modulationoutputpauserbwrecallrefreshrelease
remarkrepeatresetrestartresumesavesaveconfig
scanscanrawsd_deletesd_listsd_readselftestspur
statussweepsweeptimesweep_voltagetextthreadstouch
touchcaltouchtesttracetriggerultrausart_cfgvbat
vbat_offsetversionwaitzero

abort

  • Description: Sets the abortion enabled status (on/off) or aborts the previous command.
  • Original Usage:abort [off|on]
  • Direct Library Function Call:abort(val=None|"off"|"on")
  • Example Return: ????
  • Alias Functions:
    • enable_abort()
    • disable_abort()
    • abort_action()
  • CLI Wrapper Usage:
  • Notes: WARNING: DOES NOT ON DEVELOPER'S DUT. When used without parameters the previous command still running will be aborted. Abort must be enabled before using the "abort on" command. Additional error checking has been added with the 'verbose' option.

actual_freq

  • Description: Sets and gets the frequency correction set by CORRECT FREQUENCY menu in the expert menu settings
  • Original Usage:actual_freq [{frequency}]
  • Direct Library Function Call:actual_freq(val=None|Int)
  • Example Return: 3000000000
  • Alias Functions:
    • set_actual_freq(val=Int)
    • set_actual_freq()
  • CLI Wrapper Usage:
  • Notes: freq in Hz going by the returns. Should be able to set the value with this, according to documentation, but it doesn't appear to set with the development DUT.

agc

  • Description: Enables/disables the build in Automatic Gain Control
  • Original Usage:agc 0..7|auto
  • Direct Library Function Call:agc(val="auto"|0..7)
  • Example Return: empty bytearray
  • Alias Functions:
    • set_agc(val="auto"|Int 0..7)
  • CLI Wrapper Usage:
  • Notes:

attenuate

  • Description: Sets the internal attenuation
  • Original Usage:attenuate [auto|0-31]
  • Direct Library Function Call:attenuate(val="auto"|0..31)
  • Example Return: empty bytearray
  • Alias Functions:
    • set_attenuation(val="auto"|Int 0..31)
  • CLI Wrapper Usage:
  • Notes:

bulk

  • Description: Sent by tinySA when in auto refresh mode
  • Original Usage:bulk
  • Direct Library Function Call:bulk()
  • Example Return:format: "bulk\r\n{X}{Y}{Width}{Height} {Pixeldata}\r\n"
  • Alias Functions:
    • get_bulk_data()
  • CLI Wrapper Usage:
  • Notes:All numbers are binary coded 2 bytes little endian. The pixel data is encoded as 2 bytes per pixel. This is data returned by the device when in AUTO REFRESH mode. NOTE: may need to be paired with a continious buffer read and dump, which will be tested in the next

calc

  • Description: Sets or cancels one of the measurement modes
  • Original Usage:calc off|minh|maxh|maxd|aver4|aver16|quasip
  • Direct Library Function Call:calc(val="off"|"minh"|"maxh"|"maxd"|"aver4"|"aver16"|"quasip")
  • Example Return: empty bytearray
  • Alias Functions:
    • set_calc_off()
    • set_calc_minh()
    • set_calc_maxh()
    • set_calc_maxd()
    • set_calc_aver4()
    • set_calc_aver16()
    • set_calc_quasip()
  • CLI Wrapper Usage:
  • Notes:
    • the commands are the same as those listed in the MEASURE menu
    • tinySA Calc Menu:
      • OFF disables any calculation
      • MIN HOLD sets the display to hold the minimum value measured. Reset the hold by selecting again. This setting is used to see stable signals that are within the noise
      • MAX HOLD sets the display to hold the maximum value measured. Reset the hold by selecting again. This setting can be used for many measurements such as showing the power envelope of a modulated signal.
      • MAX DECAY sets the display to hold the maximum value measured for a certain number of scans after which the maximum will start to decay. The default number of scans to hold is 20. This default can be changed in the SETTINGS menu. This setting is used instead of MAX HOLD to reduce the impact of spurious signals
      • AVER 4 sets the averaging to new_measurement = old_measurement*3/4+measured_value/4. By default the averaging is linear power averaging
      • AVER 16 sets the averaging to new_measurement = old_measurement*15/16+measured_value/16. By default the averaging is linear power averaging
      • QUASSIP sets a quasi peak hold mode
      • Official CALC documentation

caloutput

  • Description: Disables or sets the caloutput to a specified frequency in MHz. Reference signal.
  • Original Usage:caloutput off|30|15|10|4|3|2|1
  • Library Function :cal_output(val="off"|30|15|10|4|3|2|1)
  • Example Return: empty bytearray
  • Alias Functions:
    • set_cal_output_off()
    • set_cal_output_30()
    • set_cal_output_15()
    • set_cal_output_10()
    • set_cal_output_4()
    • set_cal_output_3()
    • set_cal_output_2()
    • set_cal_output_1()
  • CLI Wrapper Usage:
  • Notes: "controls the build in calibration reference generator. The output of the reference generator is connected to CAL connector. The output frequency can be 1,2,4,10,15 and 30MHz and the output level of the fundamental at 30MHz is -35.6dBm" - Fromhttps://tinysa.org/wiki/pmwiki.php?n=TinySA4.MODE

capture

  • Description: Requests a screen dump to be sent in binary format of HEIGHTxWIDTH pixels of each 2 bytes
  • Original Usage:capture
  • Direct Library Function Call:capture()
  • Example Return:format:'\x00\x00\x00\x00\x00\x00\x00\...x00\x00\x00'
  • Alias Functions:
    • capture_screen()
  • CLI Wrapper Usage:
  • Notes: tinySA original: 320x240, tinySA Ultra and newer: 480x320

clearconfig

  • Description: Resets the configuration data to factory defaults
  • Original Usage:clear config
  • Direct Library Function Call:clear_config()
  • Example Return:b'Config and all calibration data cleared. \r\n Do reset manually to take effect. Then do touch calibration and save.\r'
  • Alias Functions:
    • clear_and_reset()
  • CLI Wrapper Usage:
  • Notes: Requires password '1234'. Hardcoded. Other functions need to be used with this to complete the process.

color

  • Description: Sets or gets colors of traces and other elements on the spectrum analyzer display. Colors must be in 24-bit RGB color value format.
  • Original Usage:color [{id} {rgb24}]
  • Direct Library Function Call:color(ID=None|0..31, RGB=None(default:'0xF8FCF8')|'0x000000'..'0xFFFFFF')
  • Example Return:
    • If ID='None' used:
      0: 0x000000\r\n 1: 0xF8FCF8\r\n 2: 0x808080\r\n 3: 0xE0E4E0\r\n 4: 0x000000\r\n 5: 0xD0D0D0\r\n 6: 0xF8FC00\r\n 7: 0x40FC40\r\n 8: 0xF800F8\r\n 9: 0xF84040\r\n 10: 0x18E000\r\n 11: 0xF80000\r\n 12: 0x0000F8\r\n 13: 0xF8FCF8\r\n 14: 0x808080\r\n 15: 0x00FC00\r\n 16: 0x808080\r\n 17: 0x000000\r\n 18: 0xF8FCF8\r\n 19: 0x0000F8\r\n 20: 0xF88080\r\n 21: 0x00FC00\r\n 22: 0x888C88\r\n 23: 0xD8DCD8\r\n 24: 0x282828\r\n 25: 0xC0C4C0\r\n 26: 0xF8FCF8\r\n 27: 0x00FC00\r\n 28: 0x00FCF8\r\n 29: 0xF8FC00\r\n 30: 0x000000\r\n 31: 0x000000\r'
    • If ID = '15' used:0x00FC00``
  • Alias Functions:
    • get_all_colors()
    • get_marker_color(ID=Int|0..31)
    • set_marker_color(ID=Int|0..31, col=rgb24)
  • CLI Wrapper Usage:
  • Notes: the rgb24 hex value currently must be passed in as a string

correction

  • Description: Sets or gets the frequency level correction table
  • Original 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)}]
  • Direct Library Function Call:correction(tableName, slot, freq, val)
  • Example Return: empty bytearray
  • Alias Functions:
    • This function is complex enough that it is recommended to use thecommand() function for options not covered by thecorrection(...) library function
  • CLI Wrapper Usage:
  • Notes: SeeCorrection Wiki. The current content of the table is shown by enteringcorrection low without any arguments. The data in the table can be modified by specifying the slot number and the new values. ThereMUST be one entry in the low table for 30MHz and the correction for that frequencyMUST be zero.
  • Future Work:Confirm table format across devices. Value currently limited between -10 and 35, but this needs to be more specific.

dac

  • Description: Sets or gets the dac value
  • Original Usage:dac [0..4095]
  • Library Function Call(s):dac(val=None/Int|0..4095)
  • Example Return:b'usage: dac {value(0-4095)}\r\ncurrent value: 1922\r'
  • Alias Functions:
    • set_dac(val=Int|0...4095)
    • get_dac()
  • CLI Wrapper Usage:
  • Notes:

data

  • Description: Gets the trace data
  • Original Usage:data 0..2
  • Direct Library Function Call:data(val=0|1|2)
  • Example Return:format bytearray(b'7.593750e+00\r\n-8.437500e+01\r\n-8.693750e+01\r\n...\r')
  • Alias Functions:
    • get_temporary_data()
    • get_stored_trace_data()
    • dump_measurement_data()
  • CLI Wrapper Usage:
  • Notes:
    • 0 = temp value, 1 = stored trace, 2 = measurement. strength in decibels (dB)
    • get_temporary_data not to be confused withget_temp, which returns temperature

device_id

  • Description: Sets or gets a user settable integer number ID that can be use to identify a specific tinySA connected to the PC
  • Original Usage:deviceid [{number}]
  • Direct Library Function Call:deviceid(ID=None/Int)
  • Example Return:'deviceid 0\r'
  • Alias Functions:
    • get_device_id()
    • set_device_id(ID=Int|0....)
  • CLI Wrapper Usage:
  • Notes:

direct

  • Description: Output mode for generating a square wave signal between 830MHz and 1130MHz
  • Original Usage:direct {start|stop|on|off} {freq(Hz)}
  • Direct Library Function Call:direct(val, freq=None|Int)
  • Example Return: empty bytearray
  • Alias Functions:
    • set_direct_on()
    • set_direct_off()
    • set_direct_start(freq=Int)
    • set_direct_stop(freq=Int)
  • CLI Wrapper Usage:
  • Notes:

ext_gain

  • Description: Sets the external attenuation/amplification
  • Original Usage:ext_gain -100..100
  • Direct Library Function Call:ext_gain(val=Int|-100...100)
  • Example Return: empty bytearray
  • Alias Functions:
    • set_ext_gain(val=Int|-100...100)
  • CLI Wrapper Usage:
  • Notes: * Works in both input and output mode

fill

  • Description: Sent by tinySA when in auto refresh mode
  • Original Usage:
  • Direct Library Function Call:
  • Example Return:format: "fill\r\n{X}{Y}{Width}{Height} {Color}\r\n"
  • Alias Functions:
    • get_fill_data()
  • CLI Wrapper Usage:
  • Notes: All numbers returned are binary coded 2 bytes little endian. Similar tobulk

freq

  • Description: Pauses the sweep and sets the measurement frequency
  • Original Usage:freq {frequency}
  • Direct Library Function Call:freq(val=Int)
  • Example Return: empty bytearray
  • Alias Functions:
    • set_freq(val=Int)
  • CLI Wrapper Usage:
  • Notes: Might need toresume the sweep after this. Could be device dependent.

freq_corr

  • Description: Gets the frequency correction.
  • Original Usage:freq_corr
  • Direct Library Function Call:freq_corr()
  • Example Return:b'0 ppb\r'
  • Alias Functions:
    • get_frequency_correction()
  • CLI Wrapper Usage:
  • Notes: This command returns the frequency correction, in parts per billion (ppb).

frequencies

  • Description: Gets the frequencies used by the last sweep
  • Original Usage:frequencies
  • Direct Library Function Call:frequencies()
  • Example Return:b'1500000000\r\n... \r\n3000000000\r'
  • Alias Functions:
    • get_last_freqs()
  • CLI Wrapper Usage:
  • Notes:

help

  • Description: Gets a list of the available commands. Can be used to call tiySA help directly, or the library help
  • Original Usage:help
  • Direct Library Function Call:help(val=None|0|1)
  • Example Return:
  • Alias Functions:
    • tinySAHelp()
  • Related Functions:
    • libraryHelp()
  • CLI Wrapper Usage:
  • Notes: 0 = tinySAHelp(), 1=libraryHelp(). Both functions can also be called directly. libraryHelp() has more information about this library and the inputs.

hop

  • Description: Measures the input level at each of the indicated frequencies. This is a measurement over a range (ends inclusive), with a specified number of samples.
  • Original Usage:hop {start(Hz)} {stop(Hz)} {step(Hz) | points} [outmask]
  • Direct Library Function Call:hop(start=Int, stop=Int, inc=Int, use_pts=Bool)
  • Example Return: e
  • Alias Functions:
    • get_sample_pts(start=Int, stop=Int, inc=Int, use_pts=Bool)
  • CLI Wrapper Usage:
  • Notes:Ultra only. Fromtinysa-org: if the 3rd parameter is below 450 it is assumed to be points, otherwise as step frequency Outmask selects if the frequency (1) or level (2) is output.

if

  • Description: Sets the intermediate frequency (IF) to automatic or a specific value, 433 Mhz to 435 MHz
  • Original Usage:if (0|433M..435M )
  • Direct Library Function Call:set_IF(val=Int|0|433M..435M|'auto')
  • Example Return: empty bytearray
  • Alias Functions:
    • None
  • CLI Wrapper Usage:
  • Notes: Val input of 0 is 'auto'. Added explicit 'auto' to match other library funcs.

if1

  • Description: Sets the intermediate frequency (IF) to automatic or a specific value, 975 Mhz to 979 MHz
  • Original Usage:if1 (975M..979M )
  • Direct Library Function Call:set_IF1(val=0|975M..979M|'auto')
  • Example Return: empty bytearray
  • Alias Functions:
    • None
  • CLI Wrapper Usage:
  • Notes: Val input of 0 is 'auto'. Added explicit 'auto' to match other library funcs.

info

  • Description: Displays various software/firmware and hardware information
  • Original Usage:info
  • Direct Library Function Call:info()
  • Example Return:b'tinySA ULTRA\r\n2019-2024 Copyright @Erik Kaashoek\r\n2016-2020 Copyright edy555\r\nSW licensed under GPL. See: https://github.com/erikkaashoek/tinySA\r\nVersion: tinySA4_v1.-143-g864bb27\r\nBuild Time: Jan 10 2024 - 11:14:08\r\nKernel: 4.0.0\r\nCompiler: GCC 7.2.1 20170904 (release) [ARM/embedded-7-branch revision 255204]\r\nArchitecture: ARMv7E-M Core Variant: Cortex-M4F\r\nPort Info: Advanced kernel mode\r\nPlatform:STM32F303xC Analog & DSP\r'
  • Alias Functions:
    • get_info()
  • CLI Wrapper Usage:
  • Notes:

level

  • Description: Sets the output level
  • Original Usage:level -76..13
  • Direct Library Function Call:level(val=Int|-76...13)
  • Example Return: empty bytearray
  • Alias Functions:
    • set_level()
  • CLI Wrapper Usage:
  • Notes: Not all values in the range are available. Might be device dependent.

levelchange

  • Description: Sets the output level delta for low output mode level sweep
  • Original Usage:levelchange -70..+70
  • Direct Library Function Call:level_change(val=Int|-70...70)
  • Example Return: empty bytearray
  • Alias Functions:
    • set_level_change()
  • CLI Wrapper Usage:
  • Notes:

leveloffset

  • Description: Sets or gets the level calibration data
  • Original Usage:leveloffset low|high|switch [output] {error}
  • Direct Library Function Call:level_offset()
  • Example Return: empty bytearray
  • Alias Functions:
    • None
  • CLI Wrapper Usage:
  • Notes: TODO. error checking needed

line

  • Description: Disables the horizontal line or sets it to a specific level.
  • Original Usage:line off|{level}
  • Direct Library Function Call:line(val="off"|)
  • Example Return: empty bytearray
  • Alias Functions:
    • line_off()
    • set_line(val=Int|Float)
  • CLI Wrapper Usage:
  • Notes:

load

  • Description: Loads a previously stored preset to the connected device
  • Original Usage:load 0..4
  • Direct Library Function Call:load(val=0|1|2|3|4)
  • Example Return: empty bytearray
  • Alias Functions:
    • None
  • CLI Wrapper Usage:
  • Notes: 0 is the startup preset

lna

  • Description: Set LNA usage off/on. The Ultra Plus devices have a 2nd LNA at a higher frequency range.
  • Original Usage:lna off|on
  • Direct Library Function Call:lna(val="off"|"on")
  • Example Return: empty bytearray
  • Alias Functions:
    • set_lna_on()
    • set_lna_off()
  • CLI Wrapper Usage:
  • Notes: Should not be enabled when AGC is enabled -tinySA wiki SETTINGS2

lna2

  • Description: Set the second LNA usage off/on. The Ultra Plus devices have a 2nd LNA at a higher frequency range.
  • Original Usage:lna2 0..7|auto
  • Direct Library Function Call:lna2(val="auto"|0..7)
  • Example Return: empty bytearray
  • Alias Functions:
    • set_lna2(val="auto"|0..7)
  • CLI Wrapper Usage:
  • Notes:

marker

  • Description: sets or dumps marker info
  • Original Usage:marker {id} on|off|peak|{freq}|{index}
  • Direct Library Function Call:marker(ID=Int|0..4, val="on"|"off"|"peak")
  • Example Return: empty bytearray
  • Alias Functions:
    • marker_on(ID=Int|1..4)
    • marker_off(ID=Int|1..4)
    • marker_peak(ID=Int|1..4)
    • marker_freq(ID=Int|1..4)
    • marker_index(ID=Int|1..4)
  • CLI Wrapper Usage:
  • Notes: where id=1..4 index=0..num_points-1Marker levels will use the selected unit Marker peak will activate the marker (if not done already), position the marker on the strongest signal and display the marker info The frequency must be within the selected sweep range mode. Alias functions need error checking.

menu

  • Description: The menu command can be used to activate any menu item based on the index of the menu item. Numbers start with 1 at the top.
  • Original Usage:menu {#} [{#} [{#} [{#}]]]
  • Direct Library Function Call:menu(val=Str)
  • Example Input:
    • menu "6 2" will toggle the waterfall option
  • Example Return: unknown. depends on menu button 'clicked'
  • Alias Functions:
    • None
  • CLI Wrapper Usage:
  • Notes:tinySA Menu Tree for more information. There's no error checking on this function due to the number of nested menus and buttons.

mode

  • Description: Sets the mode of the tinySA
  • Original Usage:mode low|high input|output
  • Direct Library Function Call:mode(val1="low"|"high", val2="input"|"output")
  • Example Return: empty bytearray
  • Alias Functions: Currently no error checking.
    • set_low_input_mode()
    • set_low_output_mode()
    • set_high_input_mode()
    • set_high_output_mode()
  • CLI Wrapper Usage:
  • Notes:tinySA Wiki MODE
    • LOW INPUT activates the 0.1-350MHz input mode
    • HIGH INPUT activates the 240MHz-960MHz input mode
    • LOW OUTPUT activates the 0.1-350MHz output mode
    • HIGH OUTPUT activates the 240MHz-960MHz output mode

modulation

  • Description: Set the modulation in output mode
  • Original Usage:modulation off|AM_1kHz|AM_10Hz|NFM|WFM|extern
  • Direct Library Function Call:modulation(val=off|AM_1kHz|AM_10Hz|NFM|WFM|extern)
  • Example Return: empty bytearray
  • Alias Functions:
    • set_mod_off()
    • set_mod_AM_1khz()
    • set_mod_AM_10Hz()
    • set_mod_NFM()
    • set_mod_WFM()
    • set_mod_extern()
  • CLI Wrapper Usage:
  • Notes:
    • OFF - Turns modulation off. NO modulation
    • AM_1kHz - Set AM modulation 1 kHz
    • AM_10Hz - Set AM modulation 10 Hz
    • NFM - Narrow FM. sets narrow FM modulation. Width is about 3kHz.
    • WFM - wide FM modulation.
    • extern - disables the internal LO driving the mixer and enables the high input as mixer LO input. Minimum external LO input frequency is 5MHz.
    • https://tinysa.org/wiki/pmwiki.php?n=Main.MODULATION

nf

  • Description: get the noise floor in dB
  • Original Usage:nf {val=None|??}
  • Direct Library Function Call:nf(val=None)
  • Example Return:b'usage: nf {value}\r\n4.000000000\r'
  • Alias Functions:
    • get_nf()
  • CLI Wrapper Usage:
  • Notes:
  • The tinySA Ultra can measure, store, and validate the tinySA noise figure (NF). It can also measure amplifier (AMP) NF.
  • While it is possible to set this value programmatically, until more documentation is online it is recommended to only GET the nf value.
  • "The NF is the degradation in dB of the SNR after the amplifier compared to before the amplifier." -https://tinysa.org/wiki/pmwiki.php?n=Main.NoiseFactor

output

  • Description: Sets the output mode on or off
  • Original Usage:output on|off
  • Direct Library Function Call:output(val="off"|"on")
  • Example Return: empty bytearray
  • Alias Functions:
    • set_output_on()
    • set_output_off()
  • CLI Wrapper Usage:
  • Notes:

pause

  • Description: Pauses the sweeping in either input or output mode
  • Original Usage:pause
  • Direct Library Function Call:pause()
  • Example Return: empty bytearray
  • Alias Functions:
    • None
  • CLI Wrapper Usage:
  • Notes:

rbw

  • Description: sets the rbw to either automatic or a specific value
  • Original Usage:rbw auto|3..600 orrbw 0.2..850|auto
  • Direct Library Function Call:rbw(val="auto"|Int)
  • Example Return: empty bytearray
  • Alias Functions:
    • set_rbw_auto()
  • CLI Wrapper Usage:
  • Notes:
  • The number specifies the target rbw in kHz.
  • Frequencies listed in tinySA Basic documentation: 3 kHz, 10 kHz, 30 kHz, 100 kHz, 300 kHz, 600 kHz.https://tinysa.org/wiki/pmwiki.php?n=Main.RBW
  • Frequencies listed in the tinySA Ultra documentation: auto, 200Hz, 1kHz 3 kHz, 10 kHz, 30 kHz, 100 kHz, 300 kHz, 600 kHz 850 kHz.https://tinysa.org/wiki/pmwiki.php?n=TinySA4.RBW
  • If you set a value not in the list, the tinySA (NOT this library) will default to the next highest value.

recall

  • Description: Loads a previously stored preset from the device
  • Original Usage: recall 0..4
  • Direct Library Function Call:recal(val=0|1|2|3|4)
  • Example Return: empty bytearray
  • Alias Functions:
    • None
  • CLI Wrapper Usage:
  • Notes: Same functionality asload(). 0 is the startup preset.

refresh

  • Description: Enables or disables the auto refresh mode
  • Original Usage:refresh on|off
  • Direct Library Function Call:refresh(val="off"|"on")
  • Example Return: empty bytearray
  • Alias Functions:
    • refresh_on()
    • refresh_off()
  • CLI Wrapper Usage:
  • Notes:

release

  • Description: Triggers a signal for the removal/release of the touch screen
  • Original Usage:release
  • Direct Library Function Call:release()
  • Example Return: empty bytearray
  • Alias Functions:
    • None
  • CLI Wrapper Usage:
  • Notes:

remark

  • Description: does nothing, per official documentation
  • Original Usage:remark [use any text]
  • Direct Library Function Call:remark(val=Str)
  • Example Return: empty bytearray
  • Alias Functions:
    • None
  • CLI Wrapper Usage:
  • Notes:
  • https://tinysa.org/wiki/pmwiki.php?n=Main.USBInterface
  • potential use: adding comments to scripts and denoting that the line does nothing withremark as the first word.

repeat

  • Description: Sets the number of (re)measurements that should be taken at every frequency
  • Original Usage: repeat 1..1000
  • Direct Library Function Call:repeat(val=Int|1..1000)
  • Example Return: empty bytearray
  • Alias Functions:
    • None
  • CLI Wrapper Usage:
  • Notes: increasing the repeat reduces the noise per frequency, repeat 1 is the normal scanning mode. Has int(val) conversion.

reset

  • Description: Resets the tinySA
  • Original Usage:reset
  • Direct Library Function Call:reset()
  • Example Return: empty bytearray, serial error message. depends on the system.
  • Alias Functions:
    • reset_device()
  • CLI Wrapper Usage:
  • Notes: Disconnects the serial too.

restart

  • Description: Restarts the tinySA after the specified number of seconds
  • Original Usage:restart {seconds}
  • Direct Library Function Call:restart(val=0...)
  • Example Return: empty bytearray
  • Alias Functions:
    • restart_device()
    • cancel_restart()
  • CLI Wrapper Usage:
  • Notes:
    • Has not worked in testing on development DUT, but appears to work on some devices online.
    • 0 seconds stops the restarting process.

resume

  • Description: Resumes the sweeping in either input or output mode
  • Original Usage:resume
  • Direct Library Function Call:resume()
  • Example Return: empty bytearray
  • Alias Functions:
    • None
  • CLI Wrapper Usage:
  • Notes:

save

  • Description: Saves the current setting to a preset
  • Original Usage:save 0..4
  • Direct Library Function Call:save(val=0..4)
  • Example Return: empty bytearray
  • Alias Functions:
    • None
  • CLI Wrapper Usage:
  • Notes: where 0 is the startup preset

saveconfig

  • Description: Saves the device configuration data
  • Original Usage:saveconfig
  • Direct Library Function Call:save_config()
  • Example Return: empty bytearray
  • Alias Functions:
    • None
  • CLI Wrapper Usage:
  • Notes: Takes no arguments.

scan

  • Description: Performs a scan and optionally outputs the measured data
  • Original Usage:scan {start(Hz)} {stop(Hz)} [points] [outmask]
  • Direct Library Function Call:scan(start, stop, pts, outmask)
  • Example Return:
    • Example arg:scan 0 2e6 5 1
    • Results:bytearray(b'0 \r\n1 \r\n1 \r\n2 \r\n2 \r')
    • Example arg:scan 0 2e6 5 2
    • Results:bytearray(b'5.843750e+00 0.000000000 \r\n5.343750e+00 0.000000000 \r\n4.843750e+00 0.000000000 \r\n4.843750e+00 0.000000000 \r\n4.843750e+00 0.000000000 \r')
    • Example arg:scan 0 2e6 5 3
    • Results:bytearray(b'0 5.375000e+00 0.000000000 \r\n1 5.875000e+00 0.000000000 \r\n1 5.375000e+00 0.000000000 \r\n2 5.375000e+00 0.000000000 \r\n2 5.375000e+00 0.000000000 \r')
    • Example arg:scan 0 2e6 5 4
    • Results:bytearray(b'5.343750e+00 0.000000000 \r\n5.843750e+00 0.000000000 \r\n5.843750e+00 0.000000000 \r\n5.343750e+00 0.000000000 \r\n5.843750e+00 0.000000000 \r')
  • Alias Functions:
    • None, but seeplotting_scan.py example
  • CLI Wrapper Usage:
  • Notes:
    • [points] is the number of points in the scan. The MAX points is device dependent. Basic is 290, Ultra is 450 .
    • [outmask] 1=frequencies, 2=measured data, 4=stored data. 3 not in documentation, but appears to blend 1 and 2.
    • Documentation says outmask is "a binary OR of.", but there doesn't appear to be any binary math involved.

scanraw

  • Description: Performs a scan of unlimited amount of points and sends the data in binary form
  • Original Usage:scanraw {start(Hz)} {stop(Hz)} [points][option] orscanraw {start(Hz)} {stop(Hz)} [points] [unbuffered] depending on the source
  • Direct Library Function Call:scan_raw(start=Int|Float, stop=Int|Float, pts=Int|Float, unbuf=1)
  • Example Return:
    • Raw, unprocessed return for 15 pts:b'scanraw 150000000 200000000 15 2\r\n{x"\nx3\nx4\nx\x15\nx6\nx\x07\nx)\nxj\nx\xfb\txm\nx]\nxO\nxp\nx\xb2\x0bx3\x0c}ch>'
    • Example arg:scanraw 150e6 200e6 5 1
    • Results:bytearray(b'{xS\nxd\nx\x98\nx]\nx\x02\x0c')
    • Example arg:scanraw 150e6 200e6 2
    • Results:bytearray(b'{xs\nxu\nx\x8a\nx^\nx\xf2\x0b')
  • Alias Functions:
    • None, but seeplotting_scanraw.py example
  • CLI Wrapper Usage:
  • Notes:
    • WARNING: the parsing documentation doesn't appear to return data consistent with measurements on the tinySA screen. UNDERGROING TESTING
    • "The measured data is the level in dBm and is send as '{' ('x' MSB LSB)*points '}'. To get the dBm level from the 16 bit data, divide by 32 and subtract 128 for the tinySA and 174 for the tinySA Ultra. The option, when present, can be either 0,1,2 or 3 being the sum of 1=unbuffered and 2=continuous." -https://tinysa.org/wiki/pmwiki.php?n=Main.USBInterface

sd_delete

  • Description: Deletes a specific file on the sd card
  • Original Usage:sd_delete {filename}
  • Direct Library Function Call:sd_delete(val=Str)
  • Example Return:
    • For successful delete:bytearray(b'delete: -0.bmp OK\r'
    • If a file is not deleted:bytearray(b'')
  • Alias Functions:
    • None
  • CLI Wrapper Usage:
  • Notes:

sd_list

  • Description: Displays list of filenames with extension and sizes
  • Original Usage:sd_list
  • Direct Library Function Call:sd_list()
  • Example Return: format example:-0.bmp 307322
  • Alias Functions:
    • None
  • CLI Wrapper Usage:
  • Notes:

sd_read

  • Description: Reads a specific file on the sd card
  • Original Usage:sd_read {filename}
  • Direct Library Function Call:sd_read(val=Str)
  • Example Return:
    • bytearray(b'z\xb0\x04\x00BMz\xb0\x04\x00\x00\x00\x00\x00z\x00\x00\x00l\x00......x10\x84\x10')
    • If file does not exist on SD card, thenbytearray(b'err: (4) no file\r') will be returned.
  • Alias Functions:
    • None
  • CLI Wrapper Usage:
  • Notes: The error return message is built into the device, but has not been exhaustively tested with this library.

selftest

  • Description: performs one or all selftests.
  • Original Usage:selftest 0 0..9,selftest (1-3) [arg]
  • Direct Library Function Call:selftest(val=0..9)
  • Example Return: empty bytearray
  • Alias Functions:
    • all_self_tests()
  • CLI Wrapper Usage:
  • Notes:
    • MUST have cable connected to RF and CAL.
    • The prompt for TOUCH still happens after
    • 0 runs all self tests.
    • Upper number of tests is likely tied to whatever the device actually has. Limited documentation.
    • Other integers appear to rerun specific tests, but there is no confirmation on the screen or returned information.

spur

  • Description: Enables or disables spur reduction
  • Original Usage:spur on|off
  • Direct Library Function Call:spur(val="off"|"on")
  • Example Return: empty bytearray
  • Alias Functions:
    • spur_on()
    • spur_off()
  • CLI Wrapper Usage:
  • Notes:

status

  • Description: Displays the current device status (paused/resumed)
  • Original Usage:status
  • Direct Library Function Call:status()
  • Example Return:b'Resumed'
  • Alias Functions:
    • get_status()
  • CLI Wrapper Usage:
  • Notes:

sweep

  • Description: Set sweep boundaries or execute a sweep
  • Original Usage:sweep [(start|stop|center|span|cw {frequency}) | ({start(Hz)} {stop(Hz)} [0..MAX PTS] ) ]
  • Direct Library Function Call:config_sweep(argName=start|stop|center|span|cw, val=Int|Float) ANDpreform_sweep(start, stop, pts)
  • Example Return:
    • empty bytearrayb''
    • bytearray(b'0 800000000 450\r')
  • Alias Functions:
    • get_sweep_params()
    • set_sweep_start(val=FREQ)
    • set_sweep_stop(val=FREQ)
    • set_sweep_center(val=FREQ)
    • set_sweep_span(val=Int|Float)
    • set_sweep_cw(val=Int|Float)
    • run_sweep(start=FREQ, stop=FREQ, pts=INT)
  • CLI Wrapper Usage:
  • Notes: sweep without arguments lists the current sweep settings, the frequencies specified should be within the permissible range. The sweep commands apply both to input and output modes. MAX PTS is device dependent; 290 for tinySA Basic and 450 for tinySA Ultra and newer
  • sweep start {frequency}: sets the start frequency of the sweep.
  • sweep stop {frequency}: sets the stop frequency of the sweep.
  • sweep center {frequency}: sets the center frequency of the sweep.
  • sweep span {frequency}: sets the span of the sweep.
  • sweep cw {frequency}: sets the continuous wave frequency (zero span sweep).
  • sweep {start(Hz)} {stop(Hz)} [0..MAX PTS]: sets the start and stop frequencies, and optionally the number of points in the sweep

sweeptime

  • Description: Sets the time between each sweep.
  • Original Usage:sweeptime {time(Seconds)}
  • Direct Library Function Call:
  • Example Return: empty bytearray
  • Alias Functions:
    • None
  • CLI Wrapper Usage:
  • Notes: the time specified may end in a letter where m=mili and u=micro

temperature

  • Description: Get the temperature from the device
  • Original Usage:k
  • Direct Library Function Call:temp()
  • Example Return:bytearray(b'43.25\r')
  • Alias Functions:
    • get_temp()
  • CLI Wrapper Usage:
  • Notes: single letter command. might not work on tinySA Basic model.

text

  • Description: specifies the text entry for the active keypad
  • Original Usage:text keypadtext
  • Direct Library Function Call:text(val="")
  • Example Return: empty bytearray
  • Alias Functions:
    • None
  • CLI Wrapper Usage:
  • Notes: where keypadtext is the text used. Example: text 12M. Currently does not work for entering file names.

threads

  • Description: lists information of the threads in the tinySA
  • Original Usage:threads
  • Direct Library Function Call:threads()
  • Example Return:b'stklimit| |stk free| addr|refs|prio| state| name\r\n20000200|2000054C|00000248|200016A8| 0| 128| CURRENT| main\r\n20001530|2000157C|0000008C|20001650| 0| 1| READY| idle\r\n200053D8|200056C4|00000250|200059B0| 0| 127| READY| sweep\r'
  • Alias Functions:
    • None
  • CLI Wrapper Usage:
  • Notes:

touch

  • Description: sends the coordinates of a touch
  • Original Usage:touch {X coordinate} {Y coordinate}
  • Direct Library Function Call:touch(x=0,y=0)
  • Example Return: empty bytearray
  • Alias Functions:
    • preform_touch(x=Int, y=Int)
  • CLI Wrapper Usage:
  • Notes: The upper left corner of the screen is "0 0"

touchcal

  • Description: starts the touch calibration
  • Original Usage:touchcal
  • Direct Library Function Call:touch_cal()
  • Example Return: empty bytearray
  • Alias Functions:
    • start_touch_cal()
  • CLI Wrapper Usage:
  • Notes:

touchtest

  • Description: starts the touch test
  • Original Usage:touchtest
  • Direct Library Function Call:touch_test()
  • Example Return: empty bytearray
  • Alias Functions:
    • start_touch_test()
  • CLI Wrapper Usage:
  • Notes: instructions on screen "touch panel, draw lines, press button to complete"

trace

  • Description: displays all or one trace information or sets trace related information. INCOMPLETE due to how many combinations are possible.
  • Original Usage:
    • from help message returnbytearray(b'trace {dBm|dBmV|dBuV|RAW|V|Vpp|W}\r\ntrace {scale|reflevel} auto|{value}\r\ntrace [{trace#}] value\r\ntrace [{trace#}] {copy|freeze|subtract|view|value} {trace#}|off|on|[{index} {value}]\r')
    • general structure for commands:trace [{trace#}] {copy|freeze|subtract|view|value} {trace#}|off|on|[{index} {value}]
    • from earlier documentation:trace [{0..2} | dBm|dBmV|dBuV| V|W |store|clear|subtract | (scale|reflevel) auto|{level}]
  • Direct Library Function Call:
    • trace_toggle(ID=Int|0..2..4, val="on"|"off")
    • trace_select(ID=Int|0..2..4)
    • trace_units(val="dBm"|"dBmV"|"dBuV"|"RAW"|"V"|"Vpp"|"W")
    • trace_scale(val="auto"|Int|Float)
    • trace_reflevel(val="auto"|Int|Float)
    • trace_value(ID=Int)
    • trace_subtract(ID1=Int, ID2=Int)
    • trace_copy(ID1=Int, ID2=Int)
  • Example Return:
    • empty bytearrayb''
    • select_trace(1):
      • bytearray(b'1: dBm 0.000000000 10.000000000 \r')
    • trace_value(1):
      • bytearray(b'trace 1 value 0 -91.13\r\ntrace 1 value 1 -92.59\r\ntrace 1 value 2 -93.09\r\ntrace 1 value 3 -89.59.....\r\ntrace 1 value 448 -84.78\r\ntrace 1 value 449 -85.25\r') (returns MAX POINTS number of readings. PTS not currently settable)
  • Alias Functions:
    • None, see direct library function calls
    • it is also suggested to use thecommand() function to preform more complex actions because this is a complicated command structure
  • CLI Wrapper Usage:
  • Notes: For readability, this command was split into multiple functions intitially rather than using complex alias functions. There is a mismatch of information of commands between versions, so this library uses the documentation returned by the device.
    • select_trace(): tinySA Ultra has 4 traces to choose from. Other devices may have other numbers of traces.
    • trace_reflevel(...) : adjusts the reference level of a trace. Levels are specified in dB(m) and can be specified using a floating point notation. E.g. 10 or 2.5https://tinysa.org/wiki/pmwiki.php?n=Main.USBInterface

trigger

  • Description: sets the trigger type or level
  • Original Usage:trigger auto|normal|single|{level(dBm)} ortrigger {value}\r\ntrigger {auto|normal|single}\r
  • Direct Library Function Call:trigger(val="auto"|"normal"|"single"|None, freq=None|Int)
  • Example Return: empty bytearray
  • Alias Functions:
    • trigger_auto()
    • trigger_normal()
    • trigger_single()
    • trigger_level(FREQ)
  • CLI Wrapper Usage:
  • Notes: the trigger level is always set in dBm

ultra

  • Description: turn on/off/config tiny SA ultra mode features
  • Original Usage:ultra off|on|auto|start|harm {freq}
  • Direct Library Function Call:ultra(val="on"|"off")
  • Example Return: empty bytearray
  • Alias Functions:
    • set_ultra_on()
    • set_ultra_off()
    • set_ultra_auto()
    • set_ultra_start(val=FREQ)
    • set_ultra_harmonic(val=FREQ)
  • CLI Wrapper Usage:
  • Notes:
    • ultra on: enable ultra mode
    • ultra off {freq}: disable ultra mode
    • ultra auto: let the tinySA decide
    • ultra start {freq}: set ultra start frequency to a specific frequency in MHz
    • ultra harm {freq}: enables harmonic mode and set the frequency to which the harmonic filter is tuned. NO ERROR CHECKING FOR THIS in library

usart_cfg

  • Description: Get port current baud rate/ gets the current serial config
  • Original Usage:usart_cfg
  • Direct Library Function Call:usart_cfg()
  • Example Return:b'Serial: 115200 baud\r'
  • Alias Functions:
    • usart_cfg()
  • CLI Wrapper Usage:
  • Notes: default is 115,200

vbat

  • Description: Get the current battery voltage
  • Original Usage:vbat
  • Direct Library Function Call:
  • Example Return: empty bytearray
  • Alias Functions:
    • get_vbat()
  • CLI Wrapper Usage:
  • Notes:

vbat_offset

  • Description: Sets or gets the battery offset value
  • Original Usage:vbat_offset [{0..4095}]
  • Direct Library Function Call:vbat_offset(val=None|0..4095)
  • Example Return:b'300\r'
  • Alias Functions:
    • get_vbat_offset()
    • set_vbat_offset(val=Int)
  • CLI Wrapper Usage:
  • Notes:

version

  • Description: returns the version text
  • Original Usage:version
  • Direct Library Function Call:version()
  • Example Return: empty bytearray
  • Alias Functions:
    • get_version()
  • CLI Wrapper Usage:
  • Notes:

wait

  • Description: wait for a single sweep to finish and pauses sweep or waits for specified number of seconds
  • Original Usage:wait [{seconds}]
  • Direct Library Function Call:
  • Example Return: empty bytearray
  • Alias Functions:
    • None
  • CLI Wrapper Usage:
  • Notes: Without an argument, this puts device in the WAIT state and it needs to manually RESUME

zero

  • Description: get or set the zero offset in dBm
  • Original Usage:zero {level}\r\n174dBm
  • Direct Library Function Call:zero(val=None|Int)
  • Example Return: empty bytearray
  • Alias Functions:
    • get_zero_offset()
  • CLI Wrapper Usage:
  • Notes: If unfamiliar with device and operation, DO NOT CHANGE THIS VALUE.
Fulllistofhelpcommandscommands:freqtimedacnfsaveconfigclearconfigzerosweeppauseresumewaitrepeatstatuscaloutputsaverecalltracetriggermarkerlineusart_cfgvbat_offsetcolorifif1lna2agcactual_freqfreq_corrattenuatelevelsweeptimeleveloffsetlevelchangemodulationrbwmodespurlnadirectultraloadext_gainoutputdeviceidcorrectioncalcmenutextremarkOthercommands:versionresetdatafrequenciesscanhopscanrawtesttouchcaltouchtestusartcapturerefreshtouchreleasevbathelpinfoselftestsd_listsd_readsd_deletethreads

List of Commands Removed from Library

sweep_voltage

  • Description: Sets the sweep voltage
  • Original Usage:sweep_voltage {0-3.3}
  • Direct Library Function Call:sweep_voltage()
  • Example Return: empty bytearray
  • Notes: device does not recognize this

Additional Library Functions for Advanced Use

command

  • Description: override library functions to run commands on the tinySA device directly.
  • Original Usage: None.
  • Direct Library Function Call:command(val=Str)
  • Example Usage::
    • example:command("version")
    • return:b'tinySA4_v1.4-143-g864bb27\r\nHW Version:V0.4.5.1.1 \r'
    • example:command("trace 1")
    • return:b'1: dBm 0.000000000 10.000000000 \r'
    • example:command("scan 150e6 200e6 5 2")
    • return:b'5.750000e+00 0.000000000 \r\n6.250000e+00 0.000000000 \r\n6.750000e+00 0.000000000 \r\n6.250000e+00 0.000000000 \r\n6.750000e+00 0.000000000 \r'
  • Example Return: command dependent
  • Alias Functions:
    • None
  • CLI Wrapper Usage:
  • Notes: If unfamiliar with device and operation, DO NOT USE THIS. There is no error checking and you will be interfacing with the tinySA device directly.

Notes for Beginners

This is a brief section for anyone that might have jumped in with a bit too much ambition. It is highly suggested toread the manual.

Very useful, important documentation can be found at:

Vocab Check

Running list of words and acronyms that get tossed around with little to no explanation. Googling is recommended if you are not familiar with these terms as they're essential to understanding device usage.

  • AGC - Automatic Gain Control. This controls the overall dynamic range of the output when the input level(s) changes.
  • Baud - Baud, or baud rate. The rate that information is transferred in a communication channel. A baud rate of 9600 means a max of 9600 bits per second is transmitted.
  • DANL - Displayed Average Noise Level (DANL) refers to the average noise level displayed on a spectrum analyzer.
  • dB - dB (decibel) and dBm (decibel-milliwatts). dB (unitless) quantifies the ratio between two values, whereas dBm expresses the absolute power level (always relative to 1mW).
  • DUT - Device Under Test. Used here to refer to the singular device used while initially writing the API.
  • IF - Intermediate Frequency. A frequency to which a carrier wave is shifted as an intermediate step in transmission or reception -Wikipedia
  • LNA - Low Noise Amplifier. An electronic component that amplifies a very low-power signal without significantly degrading its signal-to-noise ratio -Wikipedia
  • Outmask - "outmask" refers to a setting that determines additional formatting or optional features that are not a core argument for a command.
    • For example, with thehop command, this value controls whether the device's output is a frequency or a level (power) signal. When the outmask is set to "1", the tinySA will output a frequency signal. When set to "2", the outmask will cause the tinySA to output a level signal, which is a measure of the signal's power or intensity
  • RBW - Resolution Bandwidth. Frequency span of the final filter (IF filter) that is applied to the input signal. Determines the fast-Fourier transform (FFT) bin size.
  • SDR* - Software Defined Radio. This is a software (computer) controlled radio system capable of sending and receiving RF signals. This type of device uses software to control functions such as modulation, demodulation, filtering, and other signal processing tasks. Messages (packets) can be sent and received with this device.
  • Signal Generator - used to create various types of repeating or non-repeating electronic signals for testing and evaluating electronic devices and systems.
  • S-parameters - are a way to characterize the behavior of radio frequency (RF) networks and components. They describe how much of a signal is reflected, transmitted or transferred between PORTS. In case of s11 (s-one-one), the return loss of a single antenna or port is measured. In s12 (s-one-two) or s21 (s-two-one), the interaction between ports is measured.
  • SA - Spectrum Analyzer. A device that measures the (power) magnitude of an input signal vs frequency. It shows signal as a spectrum.* This is what the 'SA' in 'tinySA' is!
  • SA - Signal Analyzer. A device that measures the properties of a single frequency signal. This can include power, magnitude, phase, and other features such as modulation.
  • SNA - Scalar Network Analyzer. A device that measures amplitude as it passes through the device. It can be used to determine gain, attenuation, or frequency response.
  • VNA - Vector Network Analyzer. A device that measures the network parameters of electrical networks (typically, s-parameters). Can measure both measures both amplitude and phase properties. Thewiki article on network analyzers covers the topic in detail.

VNA vs. SA vs. LNA vs. SNA vs. SDR vs Signal Generator

aka “what am I looking at and did I buy the right thing?”

**tinySA Vs. NanoVNA **: The tinySA and NanoVNA look a lot alike, and have some similar code, but they are NOT the same device. They are designed to measure different things. The tinySA is a spectrum analyzer (SA) while the v is a vector network analyzer (VNA). Both have signal generation capabilities, but the tinySA (currently) has expanded features for generating signals. This library was made for the tinySA line of devices. There might be some compatibility with the NanoVNA, but this is not currently supported or under development. To avoid confusion, there is ananoVNA_python library.

SA - This one is context dependent. SA can mean either 'Spectrum Analyzer' (multiple frequencies) or 'Signal Analyzer' (single frequency). In the case of the tinySA it is 'Spectrum Analyzer' because multiple frequencies are being measured. A spectrum analyzer measures the magnitude of an external input signal vs frequency. It shows signal as a spectrum. The signal source does not need to be directly physically connected to the SA, which allows for analysis of the wireless spectrum. This is the primary functionality of the tinySA, but it does have other features (such as signal generation).

VNA – a vector network analyzer (VNA) measures parameters such as s-parameters, impedance and reflection coefficient of a radio frequency (RF) device under test (DUT). A VNA is used to characterize the transmission and reflection properties of the DUT by generating a stimulus signal and then measuring the device's response. This can be used to characterize and measure the behavior of RF devices and individual components.*"What is a Vector Network Analyzer and How Does it Work?" - Tektronix*NanoVNA @ https://nanovna.com/

Signal Generator - A signal generator is used to create various types of repeating or non-repeating electronic signals for testing and evaluating electronic devices and systems. These can be used for calibration, design, or testing. Some signal generators will only have sine, square, or pulses, while others allow for AM and FM modulation (which begins to crossover into SDR territory)

SNA – a scalar network analyzer (SNA) measures amplitude as it passes through the device. It can be used to determine gain, attenuation, or frequency response. scalar network analyzers are less expensive than VNAs because they only measure the magnitude of the signal, not the phase.

SDR - a software defined radio (SDR) is a software (computer) controlled radio system capable of sending and receiving RF signals. This type of device uses software to control functions such as modulation, demodulation, filtering, and other signal processing tasks. Messages can be sent and received with this device.

LNA - an electronic component designed to amplify weak incoming signals with minimal noise addition, thus improving the signal-to-noise ratio (SNR). This hardware is often attached (or built in) to the devices above. It is not a stand-alone device for signal generation or analysis.

Calibration Setup

Some tips:

  • The cable MUST be connected between the two ports BEFORE starting the calibration.
  • The cable should be finger tight. If the connector will not turn, there's a high risk of cross threading if it's forced.

Some General tinySA Notes

These are notes collected from various references as this README documentation is built out. Some are obvious, some were not at the time.

tinySA Ultra

  • In the tinySA Ultra mode, there are four output modes: Normal (below 830 MHz), Direct (between 830MHz and 1130MHz), Ultra, and Scan.

FAQs

How should I be using this?

Right now, this library is set up as a class that can be added to a Python program. I recommend adding the contents of the./src folder on the same level (or lower) than the main program you're writing. If that doesn't make a lot of sense, check out thehello_world.py file in this repo. Because that example file is at the same level as the./src folder, we aren't dealing with path imports or checking. This works well for beginners, which is whom the bulk of the documentation is intended for.

Will this be made into a REAL Python library I can import into my project?

That's the plan! Right now, the core library is made of functions for directly interfacing with the tinySA series of devices. There are several examples in this README, which will be integrated into the core library as the error checking and features are stabilized. We're probably 3-6 months of development and testing away from an official release or library creation.

How often is this library updated?

This library is updated in spurts. June-August are going to be the most active development months, but it will get monthly-ish updates otherwise. Development is pretty constant on the backend, but only stable code is released publicly. Bug fixes will be addressed as they happen.

References

Licensing

The code in this repository has been released under GPL-2.0 for right now (and to have something in place rather than nothing). This licensing does NOT take priority over the official releases and the decisions of the tinySA team. This licensing does NOT take priority for any of their products, including the devices that can be used with this software.

This software is released AS-IS, meaning that there may be bugs (especially as it is under development).

This software is UNOFFICIAL, meaning that the tinySA team does not offer tech support for it, does not maintain it, and has no responsibility for any of the contents.

About

An unofficial Python API for the tinySA device line

Topics

Resources

License

Stars

Watchers

Forks

Languages


[8]ページ先頭

©2009-2025 Movatter.jp