Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add RFSG attenuation example #888

Merged
merged 29 commits into from
Jun 23, 2023
Merged
Changes from 26 commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
775cef4
New example showing user download waveform.
Feb 1, 2023
758a71d
Python style with ni-python-styleguide.
Feb 1, 2023
a3c1f8b
second attempt to validte ni-python-styliguides
Feb 1, 2023
c4c387f
Still trying to format based on the output of the pipeline.
Feb 1, 2023
ef986c8
I will keep trying to make formatting changes
Feb 1, 2023
be66e00
Using online black checker I think I know the form
Feb 2, 2023
f0cfb47
Fixing D401
Feb 2, 2023
a357db6
BLK100 Fix
Feb 2, 2023
748edf7
using black online to fix this formatting.
Feb 2, 2023
5808ab9
Black formatting
Feb 2, 2023
9fcb4fa
Trying Black with 95 lengh
Feb 2, 2023
5839e52
Used Brad feedback to know is 100 character line.
Feb 2, 2023
b04322a
fixed datatype assignment
Feb 2, 2023
7159db4
Fixing all suggested edits and trying signing
Feb 3, 2023
cbe956c
New example to show how to use attenuation tables in rfsg
Mar 20, 2023
9aee35a
Example to show how to use att tables with RFSG
Mar 20, 2023
a6c9f28
Changed math into standard group of imports.
Mar 20, 2023
0b1e325
Update examples/nirfsg/attenuation-tables-generation.py
yardov Mar 21, 2023
92148c2
Delete nidevice_pb2.py
yardov Mar 21, 2023
1d4bab9
Delete nidevice_pb2_grpc.py
yardov Mar 21, 2023
b2ed7c6
Delete session_pb2_grpc.py
yardov Mar 21, 2023
b55d6aa
Delete session_pb2.py
yardov Mar 21, 2023
fe3a961
matching the other examples error handling
Mar 21, 2023
12a0f20
Merge branch 'users/gorozco/attenuationexample' of https://github.com…
Mar 21, 2023
b81e803
Merge remote-tracking branch 'origin/main' into users/gorozco/attenua…
Mar 22, 2023
9edb661
Merge branch 'users/gorozco/attenuationexample' of https://github.com…
Mar 22, 2023
5516f7d
changed S12 to S variable. Added the -X sign
Mar 22, 2023
baa2fef
Update examples/nirfsg/attenuation-tables-generation.py
yardov Mar 22, 2023
da7e5e2
Update examples/nirfsg/attenuation-tables-generation.py
yardov Mar 22, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
159 changes: 159 additions & 0 deletions examples/nirfsg/attenuation-tables-generation.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,159 @@
r"""Download S-parameters from an attenuation per frequency table.

The code shows how to convert attenuation into simple s-parameter table to be used with RFSG.

The gRPC API is built from the C API. NI-RFSG documentation is installed with the driver at:
C:\Program Files (x86)\IVI Foundation\IVI\Drivers\niRFSG\documentation\English\RFSG.chm

Getting Started:

To run this example, install "NI-RFSG Driver" on the server machine:
https://www.ni.com/en-us/support/downloads/drivers/download.ni-rfsg.html

For instructions on how to use protoc to generate gRPC client interfaces, see our "Creating a gRPC
Client" wiki page:
https://github.com/ni/grpc-device/wiki/Creating-a-gRPC-Client

Refer to the NI-RFSG gRPC Wiki for the latest C Function Reference:
https://github.com/ni/grpc-device/wiki/NI-RFSG-C-Function-Reference

Running from command line:

Server machine's IP address, port number, and physical channel name can be passed as separate
command line arguments.
> python getting-started-single-tone-generation.py <server_address> <port_number> <resource_name>
yardov marked this conversation as resolved.
Show resolved Hide resolved
If they are not passed in as command line arguments, then by default the server address will be
"localhost:31763", with "SimulatedRFSG" as the physical channel name.
""" # noqa: W505

import math
import sys

import grpc
import nidevice_pb2 as nidevice_grpc
import nirfsg_pb2 as nirfsg_types
import nirfsg_pb2_grpc as grpc_nirfsg
import numpy as np

SERVER_ADDRESS = "localhost"
SERVER_PORT = "31763"
SESSION_NAME = "NI-RFSG-Session"

# Resource name, channel name and options for a VST client.
RESOURCE = "5840_1"
OPTIONS = ""

# Read in cmd args
if len(sys.argv) >= 2:
SERVER_ADDRESS = sys.argv[1]
if len(sys.argv) >= 3:
SERVER_PORT = sys.argv[2]
if len(sys.argv) >= 4:
RESOURCE = sys.argv[3]
OPTIONS = ""
# Create a gRPC channel + client.
channel = grpc.insecure_channel(f"{SERVER_ADDRESS}:{SERVER_PORT}")
client = grpc_nirfsg.NiRFSGStub(channel)
vi = None


def raise_if_error(response):
"""Raise an exception if an error was returned."""
if response.status != 0:
response = client.ErrorMessage(nirfsg_types.ErrorMessageRequest(error_code=response.status))
raise Exception(f"Error: {response.error_string}")


def raise_if_initialization_error(response):
"""Raise an exception if an error was returned from Initialize."""
if response.status < 0:
raise RuntimeError(f"Error: {response.error_message or response.status}")
if response.status > 0:
sys.stderr.write(f"Warning: {response.error_message or response.status}\n")
return response


try:
response = client.InitWithOptions(
nirfsg_types.InitWithOptionsRequest(
session_name=SESSION_NAME, resource_name=RESOURCE, option_string=OPTIONS
)
)
raise_if_initialization_error(response)
vi = response.vi

client.ConfigureRefClock(
nirfsg_types.ConfigureRefClockRequest(
vi=vi,
ref_clock_source_mapped=nirfsg_types.REF_CLOCK_SOURCE_ONBOARD_CLOCK,
ref_clock_rate=10000000,
)
)

client.SetAttributeViString(
nirfsg_types.SetAttributeViStringRequest(
vi=vi,
channel_name="",
attribute_id=nirfsg_types.NIRFSG_ATTRIBUTE_REF_CLOCK_SOURCE,
value_mapped=nirfsg_types.NIRFSG_STRING_REF_CLOCK_SOURCE_ONBOARD_CLOCK,
)
)

raise_if_error(
client.ConfigureRF(nirfsg_types.ConfigureRFRequest(vi=vi, frequency=1e9, power_level=-10))
)

# Having a table of attenuations per frequency, we demo how to convert them to S parameters
# and download them to RFSG to be automatically set when we change the frequency
frequency_table_hz = [1e9, 6e9]
attenuation_table_db = [3, 3]

# Convert to S parameters: Linear attenuation
s12 = [math.pow(10, x / 20) for x in attenuation_table_db]
# We ned a table that it is frequencies x 2 x 2. Easier to fill it as a 3D matrix
sparam = np.zeros(shape=(len(frequency_table_hz), 2, 2))
for index in range(len(frequency_table_hz)):
sparam[index, 0, 1] = s12[index]
sparam[index, 1, 0] = s12[index]
# Now flatten into a list
sparam = sparam.reshape(np.prod(np.shape(sparam)))
sparam = sparam.tolist()
# Convert to NI datatype
sparam_ni = [nidevice_grpc.NIComplexNumber(real=x, imaginary=0) for x in sparam]
# Send them to the instrument
client.CreateDeembeddingSparameterTableArray(
nirfsg_types.CreateDeembeddingSparameterTableArrayRequest(
vi=vi,
port="",
table_name="myTable",
frequencies=frequency_table_hz,
sparameter_table=sparam_ni,
number_of_ports=2,
sparameter_orientation=nirfsg_types.S_PARAMETER_ORIENTATION_PORT1_TOWARDS_DUT,
)
)

raise_if_error(client.Initiate(nirfsg_types.InitiateRequest(vi=vi)))
print("Generating tone...")
# Wait for two seconds and change frequency
input("Press any key to stop generation")
raise_if_error(client.Abort(nirfsg_types.AbortRequest(vi=vi)))
except grpc.RpcError as rpc_error:
yardov marked this conversation as resolved.
Show resolved Hide resolved
error_message = rpc_error.details()
for entry in rpc_error.trailing_metadata() or []:
if entry.key == "ni-error":
value = entry.value if isinstance(entry.value, str) else entry.value.decode("utf-8")
error_message += f"\nError status: {value}"
if rpc_error.code() == grpc.StatusCode.UNAVAILABLE:
error_message = f"Failed to connect to server on {SERVER_ADDRESS}:{SERVER_PORT}"
elif rpc_error.code() == grpc.StatusCode.UNIMPLEMENTED:
error_message = (
"The operation is not implemented or is not supported/enabled in this service"
)
print(f"{error_message}")
finally:
if vi:
client.ConfigureOutputEnabled(
nirfsg_types.ConfigureOutputEnabledRequest(vi=vi, output_enabled=False)
)
client.Close(nirfsg_types.CloseRequest(vi=vi))