-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathvna_architecture.html
224 lines (199 loc) · 19.1 KB
/
vna_architecture.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
<!DOCTYPE html>
<html lang="en" data-content_root="./">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" /><meta name="viewport" content="width=device-width, initial-scale=1" />
<title>New skrf.vi.vna Module — scikit-rf</title>
<link rel="stylesheet" type="text/css" href="_static/pygments.css?v=fa44fd50" />
<link rel="stylesheet" type="text/css" href="_static/bootstrap-sphinx.css?v=284a2d1d" />
<script src="_static/documentation_options.js?v=5929fcd5"></script>
<script src="_static/doctools.js?v=888ff710"></script>
<script src="_static/sphinx_highlight.js?v=dc90522c"></script>
<link rel="author" title="About these documents" href="about.html" />
<link rel="search" title="Search" href="search.html" />
<script>
(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
})(window,document,'script','https://www.google-analytics.com/analytics.js','ga');
ga('create', 'UA-29068876-2', 'auto');
ga('send', 'pageview');
</script>
<script async src="//pagead2.googlesyndication.com/pagead/js/adsbygoogle.js"></script>
<script async src="//pagead2.googlesyndication.com/pagead/js/adsbygoogle.js"></script>
<script>
(adsbygoogle = window.adsbygoogle || []).push({
google_ad_client: "ca-pub-5050140118519400",
enable_page_level_ads: true
});
</script>
</head><body>
<div align ="center" >
<div class="gallery_image" style="margin-top: -2em; margin-left: -10em; margin-bottom: -1em;">
<a href="index.html"><img src="_static/scikit-rf-title-flat.svg"/></a>
</div>
<hr width = "90%">
<div style="margin-top: -1em; margin-left: -10em; margin-bottom: -1em;">
<h4>
<a href="index.html">Home</a> ·
<a href="install.html">Install</a> ·
<a href="http://scikit-rf.readthedocs.org/" target="_blank">Docs</a> ·
<a href="https://github.com/scikit-rf/scikit-rf" target="_blank">Source</a> ·
<a href="support.html">Support</a> ·
<!--- <a href="users.html">Users</a> · -->
<a href="merch.html">Merch</a> ·
<a href="about.html">About</a>
</h4>
</div>
</div>
<hr width = "90%">
<div class="container">
<div class="row">
<div class="body col-md-12 content" role="main">
<section id="new-skrf-vi-vna-module">
<h1>New skrf.vi.vna Module<a class="headerlink" href="#new-skrf-vi-vna-module" title="Link to this heading">¶</a></h1>
<p>As of 2017.02 a new architecture for vna drivers is being implemented.</p>
<ul class="simple">
<li><p>VNA drivers will now have a common high level functionality across all vendors implemented in an ABCVNA class.</p></li>
<li><p>Different vendor drivers will implement their own mid level functionality as needed to implement the ABC class</p></li>
<li><p>The low level functions are all implemented as SCPI commands which have a new way of being generated and called</p></li>
</ul>
<section id="legacy-vna-module">
<h2>Legacy vna module<a class="headerlink" href="#legacy-vna-module" title="Link to this heading">¶</a></h2>
<p>The old vna.py module containing drivers for PNA, PNA-X, HP8510, etc. will be available as vna_old.py and can be used as
follows:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="kn">from</span> <span class="nn">skrf.vi.vna_old</span> <span class="kn">import</span> <span class="n">PNA</span>
</pre></div>
</div>
</section>
<section id="scpi-commands">
<h2>SCPI Commands<a class="headerlink" href="#scpi-commands" title="Link to this heading">¶</a></h2>
<p>To learn about SCPI, you can read the <a class="reference external" href="http://www.ivifoundation.org/scpi/">IVI website</a>, or <a class="reference external" href="https://en.wikipedia.org/wiki/Standard_Commands_for_Programmable_Instruments">Wikipedia</a>. For this tutorial you only need to know that
SCPI comamnds are provided in a tree structure where similar commands are grouped in branches of the tree. All scpi
commands are either ‘set’ commands where the user writes something to instrument or ‘query’ commands where the user
is requesting data or information from the instrument and the syntax is like this:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span>:COMMAND:TREE:BRANCH(?) arg1,arg2
</pre></div>
</div>
<p>Each branch on the command tree is separated by a colon. Query commands provide a question mark at the end of the
command tree and arguments are provided as needed after the command. Here is an example of commands grouped in a
branch:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span>:CALC1:PAR:DEF:EXT 'my_meas','S11' # create a new S11 measurement on channel 1
:CALC2:PAR:CAT? # return a catalog of existing measurements on channel2
:CALC:PAR:SEL 'my_meas' # select 'my_meas' on the default channel (channel1)
</pre></div>
</div>
<p>With this structure in mind, scikit-rf is adopting a tool where SCPI commands are described in a yaml file, which
allows for a very compact and universal way to describe the SCPI command tree. The yaml file is then parsed in order
to generate a python script file that accesses the SCPI commands through object methods. See the snippet below from
the keysight_pna_scpi.yaml file:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">COMMAND_TREE</span><span class="p">:</span>
<span class="n">CALC</span><span class="o"><</span><span class="n">cnum</span><span class="o">=</span><span class="mi">1</span><span class="o">></span><span class="p">:</span>
<span class="n">DATA</span><span class="p">:</span>
<span class="n">command</span><span class="p">:</span> <span class="p">{</span><span class="n">name</span><span class="p">:</span> <span class="n">data</span><span class="p">,</span> <span class="nb">set</span><span class="p">:</span> <span class="s2">"<fmt=SDATA>,<data=None>"</span><span class="p">,</span> <span class="n">query_values</span><span class="p">:</span> <span class="o"><</span><span class="n">fmt</span><span class="o">=</span><span class="n">SDATA</span><span class="o">></span><span class="p">}</span>
<span class="n">branch</span><span class="p">:</span>
<span class="n">SNP</span><span class="p">:</span>
<span class="n">PORT</span><span class="p">:</span> <span class="p">{</span><span class="n">name</span><span class="p">:</span> <span class="n">snp_data</span><span class="p">,</span> <span class="n">query_values</span><span class="p">:</span> <span class="s2">"'<ports=(1, 2)>'"</span><span class="p">}</span>
<span class="n">PAR</span><span class="p">:</span>
<span class="n">CAT</span><span class="p">:</span>
<span class="n">EXT</span><span class="p">:</span> <span class="p">{</span><span class="n">name</span><span class="p">:</span> <span class="n">meas_name_list</span><span class="p">,</span> <span class="n">query</span><span class="p">:</span> <span class="s2">""</span><span class="p">,</span> <span class="n">csv</span><span class="p">:</span> <span class="kc">True</span><span class="p">}</span>
<span class="n">DEF</span><span class="p">:</span>
<span class="n">EXT</span><span class="p">:</span> <span class="p">{</span><span class="n">name</span><span class="p">:</span> <span class="n">create_meas</span><span class="p">,</span> <span class="nb">set</span><span class="p">:</span> <span class="s2">"'<mname>','<param>'"</span><span class="p">}</span>
<span class="n">DEL</span><span class="p">:</span> <span class="p">{</span><span class="n">name</span><span class="p">:</span> <span class="n">delete_meas</span><span class="p">,</span> <span class="nb">set</span><span class="p">:</span> <span class="s2">"'<mname>'"</span><span class="p">}</span>
<span class="n">SEL</span><span class="p">:</span> <span class="p">{</span><span class="n">name</span><span class="p">:</span> <span class="n">selected_meas</span><span class="p">,</span> <span class="nb">set</span><span class="p">:</span> <span class="s2">"'<mname>'"</span><span class="p">,</span> <span class="n">query</span><span class="p">:</span> <span class="s2">""</span><span class="p">}</span>
<span class="n">MNUM</span><span class="p">:</span> <span class="p">{</span><span class="n">name</span><span class="p">:</span> <span class="n">selected_meas_by_number</span><span class="p">,</span> <span class="nb">set</span><span class="p">:</span> <span class="o"><</span><span class="n">mnum</span><span class="o">></span><span class="p">,</span> <span class="n">query</span><span class="p">:</span> <span class="s2">""</span><span class="p">,</span> <span class="n">returns</span><span class="p">:</span> <span class="nb">int</span><span class="p">}</span>
<span class="n">FORM</span><span class="p">:</span> <span class="p">{</span><span class="n">name</span><span class="p">:</span> <span class="n">display_format</span><span class="p">,</span> <span class="nb">set</span><span class="p">:</span> <span class="o"><</span><span class="n">fmt</span><span class="o">=</span><span class="n">MLOG</span><span class="o">></span><span class="p">,</span> <span class="n">query</span><span class="p">:</span> <span class="s2">""</span><span class="p">}</span>
</pre></div>
</div>
<p>In the command tree, all nodes are either:</p>
<ol class="arabic simple">
<li><p>A new branch of the command tree</p></li>
<li><p>A command</p></li>
<li><p>Both a command and a branch, as in :CALC:DATA</p></li>
</ol>
<p>In the case that a node is both a branch and a command we need to explicitly mark the mappings of each with ‘branch’
and ‘command’. Otherwise, the presence of a mapping item ‘name’, which is a rational name for the command, indicates
that the node is a command. Absent that, the node is assumed to be a branch and is further parsed for more nodes.</p>
</section>
<section id="yaml-command-syntax">
<h2>yaml Command Syntax<a class="headerlink" href="#yaml-command-syntax" title="Link to this heading">¶</a></h2>
<p>For a node that is a command, there are only 2 requirements:</p>
<ol class="arabic simple">
<li><p>‘name’ must be provided</p></li>
<li><p>at least one of ‘set’, ‘query’ or ‘query_values’ must be provided.</p></li>
</ol>
<p>Optionally you may also specify the following options in the command for query processing:</p>
<ol class="arabic simple" start="3">
<li><p>‘returns’ : default ‘str’; specify the return type (int, float, str, bool) and the value returned from the functions will be converted into the appropriate python type.</p></li>
<li><p>‘csv’ : defalt False; if the return value is a csv list, parse it as such and return a python list where the members are individually converted to the type specified by ‘returns’</p></li>
<li><p>‘strip_outer_quotes’ : default True; check if the return value is a string literal encapsulated in quotes and strip these out for proper parsing of the return value.</p></li>
</ol>
<p>If a command is read or write only, then you specify only the query or set items. If it is read/write, then you
specify both. query_values is just a query command that returns a data set, and will then use the pyvisa
query_values convenience function that will automatically parse the returned data and place it in a list or numpy
array of floats.</p>
<p>The set/query items are merely the string of arguments that must be provided to the command. For example, the
‘create_meas’ example above looked like this:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="p">:</span><span class="n">CALC1</span><span class="p">:</span><span class="n">PAR</span><span class="p">:</span><span class="n">DEF</span><span class="p">:</span><span class="n">EXT</span> <span class="s1">'my_meas'</span><span class="p">,</span><span class="s1">'S11'</span>
</pre></div>
</div>
<p>If we placed this command in a python function and called it, it might look something like this:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="k">class</span> <span class="nc">SCPI</span><span class="p">:</span>
<span class="k">def</span> <span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">pyvisa_resource</span><span class="p">):</span>
<span class="bp">self</span><span class="o">.</span><span class="n">resource</span> <span class="o">=</span> <span class="n">pyvisa_resource</span>
<span class="k">def</span> <span class="nf">set_create_meas</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">cnum</span><span class="o">=</span><span class="mi">1</span><span class="p">,</span> <span class="n">mname</span><span class="o">=</span><span class="s2">""</span><span class="p">,</span> <span class="n">param</span><span class="o">=</span><span class="s2">""</span><span class="p">)</span>
<span class="n">scpi_command</span> <span class="o">=</span> <span class="s2">":CALC</span><span class="si">{:}</span><span class="s2">:PAR:DEF:EXT '</span><span class="si">{:}</span><span class="s2">','</span><span class="si">{:}</span><span class="s2">'"</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">cnum</span><span class="p">,</span> <span class="n">mname</span><span class="p">,</span> <span class="n">param</span><span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">resource</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="n">scpi_command</span><span class="p">)</span>
<span class="n">vna</span> <span class="o">=</span> <span class="n">SCPI</span><span class="p">(</span><span class="n">pyvisa_resource</span><span class="p">)</span>
<span class="n">vna</span><span class="o">.</span><span class="n">set_create_meas</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="s2">"my_meas"</span><span class="p">,</span> <span class="s2">"S11"</span><span class="p">)</span>
</pre></div>
</div>
<p>This illustrates what is going on with the yaml file. If we isolate only the create_meas command in the command tree
the yaml mapping looks like this:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">CALC</span><span class="o"><</span><span class="n">cnum</span><span class="o">=</span><span class="mi">1</span><span class="o">></span><span class="p">:</span>
<span class="n">PAR</span><span class="p">:</span>
<span class="n">DEF</span><span class="p">:</span>
<span class="n">EXT</span><span class="p">:</span> <span class="p">{</span><span class="n">name</span><span class="p">:</span> <span class="n">create_meas</span><span class="p">,</span> <span class="nb">set</span><span class="p">:</span> <span class="s2">"'<mname>','<param>'"</span><span class="p">}</span>
</pre></div>
</div>
<p>the python function <code class="docutils literal notranslate"><span class="pre">set_create_meas</span></code> is simply the write method of the create_meas SCPI command. The ‘set’ item
in the yaml mapping is the string: <code class="docutils literal notranslate"><span class="pre">"'<mname>','<param>'"</span></code> which is the the required arguments for the SCPI command.
The function has three keyword arguments, cnum, mname and param which are enclosed in <> brackets. If an argument
has a default parameter (int, float or string) then it can be specified with an ‘=’ sign.</p>
</section>
<section id="using-the-scpi-functions-to-write-a-driver">
<h2>Using the SCPI functions to write a Driver<a class="headerlink" href="#using-the-scpi-functions-to-write-a-driver" title="Link to this heading">¶</a></h2>
<p>The parser outputs a python file with a SCPI class. The current model for using this class is to initialize a VNA
class, which in turn initialized a pyvisa resource. The VNA object then initializes a SCPI object and assigns it to
self.scpi. See the abbreviated code from the keysight_pna.py PNA class __init__ method:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="k">def</span> <span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">address</span><span class="o">=</span><span class="n">DEFAULT_VISA_ADDRESS</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span>
<span class="nb">super</span><span class="p">(</span><span class="n">PNA</span><span class="p">,</span> <span class="bp">self</span><span class="p">)</span><span class="o">.</span><span class="fm">__init__</span><span class="p">(</span><span class="n">address</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">resource</span><span class="o">.</span><span class="n">timeout</span> <span class="o">=</span> <span class="n">kwargs</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">"timeout"</span><span class="p">,</span> <span class="mi">2000</span><span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">scpi</span> <span class="o">=</span> <span class="n">keysight_pna_scpi</span><span class="o">.</span><span class="n">SCPI</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">resource</span><span class="p">)</span>
</pre></div>
</div>
<p>Subsequently, the low-level instrument commands are contained with the .scpi namespace and can be called in the
following manner inside vna object methods:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">f_start</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">scpi</span><span class="o">.</span><span class="n">query_f_start</span><span class="p">(</span><span class="n">channel</span><span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">scpi</span><span class="o">.</span><span class="n">set_f_start</span><span class="p">(</span><span class="n">channel</span><span class="p">,</span> <span class="n">f_start</span><span class="p">)</span>
</pre></div>
</div>
</section>
</section>
</div>
</div>
</div>
<footer class="footer">
<div class="container">
<p class="pull-right">
<a href="#">Back to top</a>
<br/>
</p>
<p>
© Copyright 2024, the scikit-rf development team.<br/>
Created using <a href="http://sphinx-doc.org/">Sphinx</a> 7.2.6.<br/>
</p>
</div>
</footer>
</body>
</html>