oscope 0.2.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/Gemfile +15 -0
- data/LICENSE +22 -0
- data/README.md +45 -0
- data/Rakefile +36 -0
- data/VERSION.yml +5 -0
- data/oscope.gemspec +66 -0
- data/oscope/relation.rb +10 -0
- data/oscope/relation/base.rb +53 -0
- data/oscope/relation/channel.rb +32 -0
- data/oscope/relation/group.rb +31 -0
- data/oscope/relation/key.rb +37 -0
- data/oscope/relation/query.rb +10 -0
- data/oscope/relation/write.rb +10 -0
- data/oscope/rigol/ds1102d.rb +420 -0
- metadata +130 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 62f3fea7c558c554da6c06e07596148818615f16
|
4
|
+
data.tar.gz: f8b970dd6433c4a38b32ea4eb7098a92358d934c
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 3ce59ab95c5ab2820c292459c89c92ccf4121a170cdc2a19347f27511bb26eb4e2873c8651adfe66e7f24d6877d1325f711488b151106cf6bda8a9aefe9fd4ba
|
7
|
+
data.tar.gz: d52f3f2eaa740f8ac3aa1168d91397bb6394b389091f05eced8de8c0528276d02893d57404422368ff6f5a11ba237316da87140c1d2aac07fae0b1dcf785f72a
|
data/Gemfile
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
source "http://rubygems.org"
|
2
|
+
# Add dependencies required to use your gem here.
|
3
|
+
# Example:
|
4
|
+
# gem "activesupport", ">= 2.3.5"
|
5
|
+
|
6
|
+
gem 'airby', '~>0.1.0', git: 'git://github.chi.matasano.com/td/airby.git', branch: :master
|
7
|
+
gem "ffi", "~>1.9.6"
|
8
|
+
|
9
|
+
# Add dependencies to develop your gem here.
|
10
|
+
# Include everything needed to run rake, tests, features, etc.
|
11
|
+
group :development do
|
12
|
+
gem 'yard', '~>0.8.7'
|
13
|
+
gem "bundler", "~> 1.0"
|
14
|
+
gem "jeweler", "~> 1.8.7"
|
15
|
+
end
|
data/LICENSE
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
The MIT License (MIT)
|
2
|
+
|
3
|
+
Copyright (c) 2014 tduehr
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
7
|
+
in the Software without restriction, including without limitation the rights
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
10
|
+
furnished to do so, subject to the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
13
|
+
copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
21
|
+
SOFTWARE.
|
22
|
+
|
data/README.md
ADDED
@@ -0,0 +1,45 @@
|
|
1
|
+
oscope
|
2
|
+
======
|
3
|
+
|
4
|
+
SCPI driver for VISA instruments. Currently, only the ds1102d oscilloscope is defined. All other SCPI instruments should work if oscope is provided the commands.
|
5
|
+
|
6
|
+
### Example
|
7
|
+
|
8
|
+
```ruby
|
9
|
+
require 'oscope/rigol/ds1102d'
|
10
|
+
|
11
|
+
scope = Oscope::Rigol::Ds1102d.new
|
12
|
+
scope.open(scope.session.find_resources('USB*').first)
|
13
|
+
# get timebase settings
|
14
|
+
scope.timebase.scale.to_f
|
15
|
+
scope.timebase.offset.to_f
|
16
|
+
|
17
|
+
# get channel settings
|
18
|
+
scope.channel(1).scale.to_f
|
19
|
+
scope.channel(1).offset.to_f
|
20
|
+
scope.channel(2).scale.to_f
|
21
|
+
scope.channel(2).offset.to_f
|
22
|
+
scope.acquire.sampling_rate('chan2').to_f
|
23
|
+
|
24
|
+
# get channel waveforms
|
25
|
+
scope.waveform.data 'chan2'
|
26
|
+
scope.waveform.data 'chan1'
|
27
|
+
scope.waveform.data 'digital'
|
28
|
+
```
|
29
|
+
|
30
|
+
### Contributing to oscope
|
31
|
+
|
32
|
+
|
33
|
+
* Check out the latest master to make sure the feature hasn't been implemented or the bug hasn't been fixed yet.
|
34
|
+
* Check out the issue tracker to make sure someone already hasn't requested it and/or contributed it.
|
35
|
+
* Fork the project.
|
36
|
+
* Start a feature/bugfix branch.
|
37
|
+
* Commit and push until you are happy with your contribution.
|
38
|
+
* Make sure to add tests for it. This is important so I don't break it in a future version unintentionally.
|
39
|
+
* Please try not to mess with the Rakefile, version, or history. If you want to have your own version, or is otherwise necessary, that is fine, but please isolate to its own commit so I can cherry-pick around it.
|
40
|
+
|
41
|
+
#### Copyright
|
42
|
+
|
43
|
+
Copyright (c) 2015 tduehr. See LICENSE for
|
44
|
+
further details.
|
45
|
+
|
data/Rakefile
ADDED
@@ -0,0 +1,36 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require 'rubygems'
|
4
|
+
require 'bundler'
|
5
|
+
begin
|
6
|
+
Bundler.setup(:default, :development)
|
7
|
+
rescue Bundler::BundlerError => e
|
8
|
+
$stderr.puts e.message
|
9
|
+
$stderr.puts "Run `bundle install` to install missing gems"
|
10
|
+
exit e.status_code
|
11
|
+
end
|
12
|
+
require 'rake'
|
13
|
+
|
14
|
+
require 'jeweler'
|
15
|
+
Jeweler::Tasks.new do |gem|
|
16
|
+
gem.name = "oscope"
|
17
|
+
gem.homepage = "http://github.com/tduehr/oscope"
|
18
|
+
gem.license = "MIT"
|
19
|
+
gem.summary = %Q{SCPI command interface}
|
20
|
+
gem.description = %Q{SCPI (IEEE 488.2) interface. Only the Rigol DS1102D oscilloscope is implemented currently. All SCPI interfaces *should* be supported.}
|
21
|
+
gem.email = "tduehr@gmail.com"
|
22
|
+
gem.authors = ["tduehr"]
|
23
|
+
end
|
24
|
+
Jeweler::RubygemsDotOrgTasks.new
|
25
|
+
|
26
|
+
require 'rake/testtask'
|
27
|
+
Rake::TestTask.new(:test) do |test|
|
28
|
+
test.libs << 'lib' << 'test'
|
29
|
+
test.pattern = 'test/**/test_*.rb'
|
30
|
+
test.verbose = true
|
31
|
+
end
|
32
|
+
|
33
|
+
task :default => :test
|
34
|
+
|
35
|
+
require 'yard'
|
36
|
+
YARD::Rake::YardocTask.new
|
data/VERSION.yml
ADDED
data/oscope.gemspec
ADDED
@@ -0,0 +1,66 @@
|
|
1
|
+
# Generated by jeweler
|
2
|
+
# DO NOT EDIT THIS FILE DIRECTLY
|
3
|
+
# Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
|
4
|
+
# -*- encoding: utf-8 -*-
|
5
|
+
# stub: oscope 0.2.2 ruby lib
|
6
|
+
|
7
|
+
Gem::Specification.new do |s|
|
8
|
+
s.name = "oscope"
|
9
|
+
s.version = "0.2.2"
|
10
|
+
|
11
|
+
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
12
|
+
s.require_paths = ["lib"]
|
13
|
+
s.authors = ["tduehr"]
|
14
|
+
s.date = "2015-02-03"
|
15
|
+
s.description = "SCPI (IEEE 488.2) interface. Only the Rigol DS1102D oscilloscope is implemented currently. All SCPI interfaces *should* be supported."
|
16
|
+
s.email = "tduehr@gmail.com"
|
17
|
+
s.extra_rdoc_files = [
|
18
|
+
"LICENSE",
|
19
|
+
"README.md"
|
20
|
+
]
|
21
|
+
s.files = [
|
22
|
+
"Gemfile",
|
23
|
+
"LICENSE",
|
24
|
+
"README.md",
|
25
|
+
"Rakefile",
|
26
|
+
"VERSION.yml",
|
27
|
+
"oscope.gemspec",
|
28
|
+
"oscope/relation.rb",
|
29
|
+
"oscope/relation/base.rb",
|
30
|
+
"oscope/relation/channel.rb",
|
31
|
+
"oscope/relation/group.rb",
|
32
|
+
"oscope/relation/key.rb",
|
33
|
+
"oscope/relation/query.rb",
|
34
|
+
"oscope/relation/write.rb",
|
35
|
+
"oscope/rigol/ds1102d.rb"
|
36
|
+
]
|
37
|
+
s.homepage = "http://github.com/tduehr/oscope"
|
38
|
+
s.licenses = ["MIT"]
|
39
|
+
s.rubygems_version = "2.4.5"
|
40
|
+
s.summary = "SCPI command interface"
|
41
|
+
|
42
|
+
if s.respond_to? :specification_version then
|
43
|
+
s.specification_version = 4
|
44
|
+
|
45
|
+
if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
|
46
|
+
s.add_runtime_dependency(%q<airby>, ["~> 0.1.0"])
|
47
|
+
s.add_runtime_dependency(%q<ffi>, ["~> 1.9.6"])
|
48
|
+
s.add_development_dependency(%q<yard>, ["~> 0.8.7"])
|
49
|
+
s.add_development_dependency(%q<bundler>, ["~> 1.0"])
|
50
|
+
s.add_development_dependency(%q<jeweler>, ["~> 1.8.7"])
|
51
|
+
else
|
52
|
+
s.add_dependency(%q<airby>, ["~> 0.1.0"])
|
53
|
+
s.add_dependency(%q<ffi>, ["~> 1.9.6"])
|
54
|
+
s.add_dependency(%q<yard>, ["~> 0.8.7"])
|
55
|
+
s.add_dependency(%q<bundler>, ["~> 1.0"])
|
56
|
+
s.add_dependency(%q<jeweler>, ["~> 1.8.7"])
|
57
|
+
end
|
58
|
+
else
|
59
|
+
s.add_dependency(%q<airby>, ["~> 0.1.0"])
|
60
|
+
s.add_dependency(%q<ffi>, ["~> 1.9.6"])
|
61
|
+
s.add_dependency(%q<yard>, ["~> 0.8.7"])
|
62
|
+
s.add_dependency(%q<bundler>, ["~> 1.0"])
|
63
|
+
s.add_dependency(%q<jeweler>, ["~> 1.8.7"])
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
data/oscope/relation.rb
ADDED
@@ -0,0 +1,53 @@
|
|
1
|
+
class Oscope
|
2
|
+
module Relation
|
3
|
+
class Base
|
4
|
+
attr_reader :scope, :command
|
5
|
+
def initialize scope, command, commands
|
6
|
+
@scope = scope
|
7
|
+
@command = command
|
8
|
+
@subcommands = commands
|
9
|
+
end
|
10
|
+
|
11
|
+
def subcommands
|
12
|
+
@subcommands.keys
|
13
|
+
end
|
14
|
+
|
15
|
+
def inspect
|
16
|
+
"\#<Relation:0x#{(__id__ * 2).to_s(16).rjust(14, '0')} #{@command}>"
|
17
|
+
end
|
18
|
+
|
19
|
+
def method_missing meth, *args, &block
|
20
|
+
subs = @subcommands[meth.to_s]
|
21
|
+
super unless subs
|
22
|
+
meth = meth.to_s.split('_').join
|
23
|
+
if subs.kind_of?(::Hash) # sub-sub-commands
|
24
|
+
self.class.new @scope, "#{@command}:#{meth.upcase}", subs
|
25
|
+
else
|
26
|
+
raise ArgumentError unless subs.include? args.size
|
27
|
+
if meth.end_with? "=" # set something
|
28
|
+
write ["#{@command}:#{meth[0..-2]}", args.join(',')].join(" ")
|
29
|
+
else # get something
|
30
|
+
query_full ["#{@command}:#{meth}?", args.join(',')].join(" ")
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
def respond_to_missing? meth
|
36
|
+
subcommands.include? meth || super
|
37
|
+
end
|
38
|
+
|
39
|
+
private
|
40
|
+
def write comm
|
41
|
+
@scope.session.write comm
|
42
|
+
end
|
43
|
+
|
44
|
+
def query comm
|
45
|
+
@scope.session.query comm
|
46
|
+
end
|
47
|
+
|
48
|
+
def query_full comm
|
49
|
+
@scope.session.query_full comm
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
class Oscope
|
2
|
+
module Relation
|
3
|
+
class Channel < Base
|
4
|
+
# ZERO = [0]
|
5
|
+
# ONE = [1]
|
6
|
+
# ONE_ZERO = [0,1]
|
7
|
+
|
8
|
+
def initialize scope, command, commands, chan, chan_subcomm = nil
|
9
|
+
super scope, command, commands
|
10
|
+
@channel_commands = chan_subcomm || {
|
11
|
+
'acquire' => {'sampling_rate' => ZERO, 'sampling_rate=' => ONE},
|
12
|
+
'trigger' => {
|
13
|
+
'edge' => {'source' => ZERO},
|
14
|
+
'slope' => {'source' => ZERO},
|
15
|
+
'video' => {'source' => ZERO},
|
16
|
+
'pulse' => {'source' => ZERO},
|
17
|
+
'duration' => {'source' => ZERO},
|
18
|
+
'pattern' => {'source' => ZERO},
|
19
|
+
'alternation' => {'source' => ZERO}
|
20
|
+
},
|
21
|
+
'waveform' => {'data' => ZERO}
|
22
|
+
}
|
23
|
+
|
24
|
+
@channel = chan
|
25
|
+
end
|
26
|
+
|
27
|
+
def subcommands
|
28
|
+
@subcommands + @channel_commands
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
class Oscope
|
2
|
+
module Relation
|
3
|
+
class Group < Base
|
4
|
+
SUBS = %w{state state= size size=}
|
5
|
+
def initialize scope, n
|
6
|
+
@scope = scope
|
7
|
+
@command = ":la:group#{n}"
|
8
|
+
end
|
9
|
+
|
10
|
+
def subcommands
|
11
|
+
SUBS
|
12
|
+
end
|
13
|
+
|
14
|
+
def state
|
15
|
+
query_full "#{@command}?"
|
16
|
+
end
|
17
|
+
|
18
|
+
def state= stat
|
19
|
+
write "#{@command} #{stat}"
|
20
|
+
end
|
21
|
+
|
22
|
+
def size
|
23
|
+
query_full "#{@command}:size?"
|
24
|
+
end
|
25
|
+
|
26
|
+
def size= len
|
27
|
+
write "#{@command}:size #{len}"
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
class Oscope
|
2
|
+
module Relation
|
3
|
+
class Key < Base
|
4
|
+
COMM = ":key"
|
5
|
+
SUBS = %w{
|
6
|
+
lock run auto channel1 channel2 math ref f1 f2 f3 f4 f5 menu_off measure
|
7
|
+
cursor acquire display storage utility menu_time menu_trig trig_50 force
|
8
|
+
v_pos_inc v_pos_dec v_scale_inc v_scale_dec h_scale_inc h_scale_dec
|
9
|
+
trig_lvl_inc trig_lvl_dec h_pos_inc h_pos_dec prompt_v prompt_h function
|
10
|
+
p_function n_function la prompt_v_pos prompt_h_pos prompt_trig_lvl off
|
11
|
+
}
|
12
|
+
|
13
|
+
def initialize scope
|
14
|
+
@scope = scope
|
15
|
+
@command = COMM
|
16
|
+
end
|
17
|
+
|
18
|
+
def subcommands
|
19
|
+
SUBS
|
20
|
+
end
|
21
|
+
|
22
|
+
def method_missing meth, *args, &block
|
23
|
+
super unless SUBS.include? meth.to_s
|
24
|
+
write ":key:#{meth}"
|
25
|
+
end
|
26
|
+
|
27
|
+
def lock= state; write ":key:lock #{state}"; end
|
28
|
+
def lock; query_full ":key:lock"; end
|
29
|
+
|
30
|
+
def menu_time; write ":key:mnutime"; end
|
31
|
+
def menu_trig; write ":key:mnutrig"; end
|
32
|
+
def menu_time; write ":key:trig%50"; end
|
33
|
+
def p_function; write ':key:+function'; end
|
34
|
+
def n_function; write ':key:-function'; end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
@@ -0,0 +1,420 @@
|
|
1
|
+
require 'airby'
|
2
|
+
|
3
|
+
module Oscope
|
4
|
+
module Rigol
|
5
|
+
# @note The command +display+ has been replaced with +sdisplay+
|
6
|
+
class Ds1102d
|
7
|
+
def self.mode_hash modes, mode_comm, addl_comm = {}
|
8
|
+
Hash.new{|h,k| h[k] = modes[k].merge(mode_comm) if modes.has_key? k}.merge(addl_comm)
|
9
|
+
end
|
10
|
+
|
11
|
+
ZERO = [0]
|
12
|
+
ONE = [1]
|
13
|
+
ONE_ZERO = [0,1]
|
14
|
+
|
15
|
+
ALTERNATION = {
|
16
|
+
'edge' => {'slope' => ZERO,'slope=' => ONE},
|
17
|
+
'slope' => {
|
18
|
+
'window' => ZERO,
|
19
|
+
'level_a' => ZERO,
|
20
|
+
'level_b' => ZERO,
|
21
|
+
'window=' => ONE,
|
22
|
+
'level_a=' => ONE,
|
23
|
+
'level_b=' => ONE
|
24
|
+
},
|
25
|
+
'video' => {
|
26
|
+
'polarity' => ZERO,
|
27
|
+
'standard' => ZERO,
|
28
|
+
'line' => ZERO,
|
29
|
+
'polarity=' => ONE,
|
30
|
+
'standard=' => ONE,
|
31
|
+
'line=' => ONE
|
32
|
+
}
|
33
|
+
}
|
34
|
+
|
35
|
+
MODE = {
|
36
|
+
'edge' => {
|
37
|
+
'slope' => ZERO,
|
38
|
+
'sensitivity' => ZERO,
|
39
|
+
'slope=' => ONE,
|
40
|
+
'sensitivity=' => ONE
|
41
|
+
},
|
42
|
+
'pulse' => {
|
43
|
+
'mode' => ZERO,
|
44
|
+
'sensitivity' => ZERO,
|
45
|
+
'width' => ZERO,
|
46
|
+
'mode=' => ONE,
|
47
|
+
'sensitivity=' => ONE,
|
48
|
+
'width=' => ONE
|
49
|
+
},
|
50
|
+
'video' => {
|
51
|
+
'line' => ZERO,
|
52
|
+
'mode' => ZERO,
|
53
|
+
'polarity' => ZERO,
|
54
|
+
'sensitivity' => ZERO,
|
55
|
+
'standard' => ZERO,
|
56
|
+
'line=' => ONE,
|
57
|
+
'mode=' => ONE,
|
58
|
+
'polarity=' => ONE,
|
59
|
+
'sensitivity=' => ONE,
|
60
|
+
'standard=' => ONE
|
61
|
+
},
|
62
|
+
'slope' => {
|
63
|
+
'level_a' => ZERO,
|
64
|
+
'level_b' => ZERO,
|
65
|
+
'mode' => ZERO,
|
66
|
+
'sensitivity' => ZERO,
|
67
|
+
'time' => ZERO,
|
68
|
+
'window' => ZERO,
|
69
|
+
'level_a=' => ONE,
|
70
|
+
'level_b=' => ONE,
|
71
|
+
'mode=' => ONE,
|
72
|
+
'sensitivity=' => ONE,
|
73
|
+
'time=' => ONE,
|
74
|
+
'window=' => ONE
|
75
|
+
},
|
76
|
+
'pattern' => {
|
77
|
+
'pattern' => ZERO,
|
78
|
+
'pattern=' => [2,4]
|
79
|
+
},
|
80
|
+
'duration' => {
|
81
|
+
'pattern' => ZERO,
|
82
|
+
'time' => ZERO,
|
83
|
+
'qualifier' => ZERO,
|
84
|
+
'pattern=' => [2],
|
85
|
+
'time=' => ONE,
|
86
|
+
'qualifier=' => ONE
|
87
|
+
},
|
88
|
+
'alternation' => mode_hash( ALTERNATION, {
|
89
|
+
'level' => ZERO,
|
90
|
+
'time' => ZERO,
|
91
|
+
'coupling' => ZERO,
|
92
|
+
'sensitivity' => ZERO,
|
93
|
+
'holdoff' => ZERO,
|
94
|
+
'level=' => ONE,
|
95
|
+
'time=' => ONE,
|
96
|
+
'coupling=' => ONE,
|
97
|
+
'sensitivity=' => ONE,
|
98
|
+
'holdoff=' => ONE
|
99
|
+
}, {
|
100
|
+
'type' => ZERO,
|
101
|
+
'source' => ZERO,
|
102
|
+
'time_scale' => ZERO,
|
103
|
+
'time_offset' => ZERO
|
104
|
+
}
|
105
|
+
)
|
106
|
+
}
|
107
|
+
attr_accessor :session, :options
|
108
|
+
|
109
|
+
def self.open resource, opts = {}
|
110
|
+
ret = self.new resource, opts = {}
|
111
|
+
if block_given?
|
112
|
+
begin
|
113
|
+
yield ret
|
114
|
+
ensure
|
115
|
+
ret.close
|
116
|
+
end
|
117
|
+
end
|
118
|
+
ret
|
119
|
+
end
|
120
|
+
|
121
|
+
def open resource = nil
|
122
|
+
@resource = resource if resource
|
123
|
+
@session.open @resource
|
124
|
+
|
125
|
+
self
|
126
|
+
end
|
127
|
+
|
128
|
+
def initialize resource = nil, opts = {}
|
129
|
+
if opts[:session]
|
130
|
+
@session = opts.delete(:session)
|
131
|
+
elsif resource
|
132
|
+
@session = Airby::Session.new(resource)
|
133
|
+
else
|
134
|
+
@session = Airby::Session.new
|
135
|
+
@session.open @session.find_resources("?*").first unless opts[:no_auto]
|
136
|
+
end
|
137
|
+
@resource = @session.address
|
138
|
+
|
139
|
+
@session.buffer_grow opts[:buffer_size] if opts[:buffer_size]
|
140
|
+
@options = opts
|
141
|
+
end
|
142
|
+
|
143
|
+
def mode_hash modes, mode_comm, addl_comm = {}
|
144
|
+
self.class.mode_hash modes, mode_comm, addl_comm
|
145
|
+
end
|
146
|
+
|
147
|
+
# @group General Commands
|
148
|
+
|
149
|
+
# get device identification string
|
150
|
+
# @return [String]
|
151
|
+
def ident
|
152
|
+
@session.ident
|
153
|
+
end
|
154
|
+
|
155
|
+
# Reset device parameters
|
156
|
+
# @return [void]
|
157
|
+
def reset
|
158
|
+
@session.reset
|
159
|
+
end
|
160
|
+
|
161
|
+
# @endgroup
|
162
|
+
|
163
|
+
# @group System Commands
|
164
|
+
|
165
|
+
# initiates ongoing data collection within the device
|
166
|
+
def run
|
167
|
+
@session.write ':RUN'
|
168
|
+
end
|
169
|
+
|
170
|
+
# instructs oscilloscope to determine optimal display parameters for waveform
|
171
|
+
def auto
|
172
|
+
@session.write ':AUTO'
|
173
|
+
end
|
174
|
+
|
175
|
+
# writes a bmp to the USB disk of the current screen information
|
176
|
+
def hardcopy
|
177
|
+
@session.write ':HARDCOPY'
|
178
|
+
end
|
179
|
+
|
180
|
+
# @endgroup
|
181
|
+
|
182
|
+
# @group Acquire Commands
|
183
|
+
|
184
|
+
def acquire
|
185
|
+
Relation::Base.new self, ":ACQUIRE", {
|
186
|
+
'type' => ZERO,
|
187
|
+
'type=' => ONE,
|
188
|
+
'mode' => ZERO,
|
189
|
+
'mode=' => ONE,
|
190
|
+
'averages' => ZERO,
|
191
|
+
'averages=' => ONE,
|
192
|
+
'sampling_rate' => ONE,
|
193
|
+
'memdepth' => ZERO,
|
194
|
+
'memdepth=' => ONE
|
195
|
+
}
|
196
|
+
end
|
197
|
+
|
198
|
+
# @endgroup
|
199
|
+
|
200
|
+
# @group Display Commands
|
201
|
+
|
202
|
+
def sdisplay
|
203
|
+
Relation::Base.new self, ':DISPLAY', {
|
204
|
+
'type' => ZERO,
|
205
|
+
'type=' => ONE,
|
206
|
+
'grid' => ZERO,
|
207
|
+
'grid=' => ONE,
|
208
|
+
'persist' => ZERO,
|
209
|
+
'persist=' => ONE,
|
210
|
+
'mnudisplay' => ZERO,
|
211
|
+
'mnudisplay=' => ONE,
|
212
|
+
'mnustatus' => ZERO,
|
213
|
+
'mnustatus=' => ONE,
|
214
|
+
'clear' => ZERO,
|
215
|
+
'brightness' => ZERO,
|
216
|
+
'brightness=' => ONE,
|
217
|
+
'intensity' => ZERO,
|
218
|
+
'intensity=' => ONE
|
219
|
+
}
|
220
|
+
end
|
221
|
+
|
222
|
+
# @endgroup
|
223
|
+
|
224
|
+
# @group Timebase Commands
|
225
|
+
def timebase
|
226
|
+
Relation::Base.new self, ':TIMEBASE', {
|
227
|
+
'mode' => ZERO,
|
228
|
+
'mode=' => ONE,
|
229
|
+
'delayed' => {
|
230
|
+
'offset' => ZERO,
|
231
|
+
'offset=' => ONE,
|
232
|
+
'scale' => ZERO,
|
233
|
+
'scale=' => ONE
|
234
|
+
},
|
235
|
+
'offset' => ZERO,
|
236
|
+
'offset=' => ONE,
|
237
|
+
'scale' => ZERO,
|
238
|
+
'scale=' => ONE,
|
239
|
+
'format' => ZERO,
|
240
|
+
'format=' => ONE
|
241
|
+
}
|
242
|
+
end
|
243
|
+
# @endgroup
|
244
|
+
|
245
|
+
# @group Trigger Commands
|
246
|
+
def trigger
|
247
|
+
hsh = mode_hash MODE, {
|
248
|
+
'source' => ZERO,
|
249
|
+
'level' => ZERO,
|
250
|
+
'sweep' => ZERO,
|
251
|
+
'coupling' => ZERO,
|
252
|
+
'source=' => ONE,
|
253
|
+
'level=' => ONE,
|
254
|
+
'sweep=' => ONE,
|
255
|
+
'coupling=' => ONE
|
256
|
+
},
|
257
|
+
{
|
258
|
+
'mode' => ZERO,
|
259
|
+
'holdoff' => ZERO,
|
260
|
+
'status' => ZERO,
|
261
|
+
'mode=' => ONE,
|
262
|
+
'holdoff=' => ONE
|
263
|
+
}
|
264
|
+
|
265
|
+
Relation::Base.new self, ':TRIGGER', hsh
|
266
|
+
end
|
267
|
+
|
268
|
+
def trig_50
|
269
|
+
@session.write(':TRIG%50')
|
270
|
+
end
|
271
|
+
|
272
|
+
def force_trig
|
273
|
+
@session.write ':FORCETRIG'
|
274
|
+
end
|
275
|
+
|
276
|
+
# @endgroup
|
277
|
+
|
278
|
+
# @group Storage Commands
|
279
|
+
def storage
|
280
|
+
Relation::Base.new self, ':STORAGE', {'factory' => {'load' => ZERO}}
|
281
|
+
end
|
282
|
+
# @endgroup
|
283
|
+
|
284
|
+
# @group Math Commands
|
285
|
+
def fft
|
286
|
+
Relation::Base.new self, ':FFT', {'sdisplay' => ZERO, 'sdisplay=' => ONE}
|
287
|
+
end
|
288
|
+
|
289
|
+
def math
|
290
|
+
Relation::Base.new self, ':MATH', {
|
291
|
+
'sdisplay' => ZERO,
|
292
|
+
'operate' => ZERO,
|
293
|
+
'sdisplay=' => ONE,
|
294
|
+
'operate=' => ONE
|
295
|
+
}
|
296
|
+
end
|
297
|
+
# @endgroup
|
298
|
+
|
299
|
+
# @group Channel Commands
|
300
|
+
def channel chan
|
301
|
+
raise ArgumentError 'channel must be 1 or 2' unless chan == 1 || chan == 2
|
302
|
+
Relation::Base.new self, ":CHANNEL#{chan}", {
|
303
|
+
'bw_limit' => ZERO,
|
304
|
+
'coupling' => ZERO,
|
305
|
+
'sdisplay' => ZERO,
|
306
|
+
'invert' => ZERO,
|
307
|
+
'offset' => ZERO,
|
308
|
+
'probe' => ZERO,
|
309
|
+
'scale' => ZERO,
|
310
|
+
'filter' => ZERO,
|
311
|
+
'memory_depth' => ZERO,
|
312
|
+
'vernier' => ZERO,
|
313
|
+
'bw_limit=' => ONE,
|
314
|
+
'coupling=' => ONE,
|
315
|
+
'sdisplay=' => ONE,
|
316
|
+
'invert=' => ONE,
|
317
|
+
'offset=' => ONE,
|
318
|
+
'probe=' => ONE,
|
319
|
+
'scale=' => ONE,
|
320
|
+
'filter=' => ONE,
|
321
|
+
'vernier=' => ONE
|
322
|
+
}
|
323
|
+
end
|
324
|
+
# @endgroup
|
325
|
+
|
326
|
+
# @group Measure Commands
|
327
|
+
def measure
|
328
|
+
ret = Relation::Base.new self, ':MEASURE', {
|
329
|
+
'vpp' => ONE_ZERO,
|
330
|
+
'vmax' => ONE_ZERO,
|
331
|
+
'vmin' => ONE_ZERO,
|
332
|
+
'vamplitude' => ONE_ZERO,
|
333
|
+
'vtop' => ONE_ZERO,
|
334
|
+
'vbase' => ONE_ZERO,
|
335
|
+
'vaverage' => ONE_ZERO,
|
336
|
+
'vrms' => ONE_ZERO,
|
337
|
+
'overshoot' => ONE_ZERO,
|
338
|
+
'preshoot' => ONE_ZERO,
|
339
|
+
'frequency' => ONE_ZERO,
|
340
|
+
'rise_time' => ONE_ZERO,
|
341
|
+
'fall_time' => ONE_ZERO,
|
342
|
+
'period' => ONE_ZERO,
|
343
|
+
'pwidth' => ZERO,
|
344
|
+
'nwidth' => ZERO,
|
345
|
+
'pduty_cycle' => ZERO,
|
346
|
+
'nduty_cycle' => ZERO,
|
347
|
+
'pdelay' => ZERO,
|
348
|
+
'ndelay' => ZERO,
|
349
|
+
'total' => ZERO,
|
350
|
+
'total=' => ONE,
|
351
|
+
'source' => ZERO,
|
352
|
+
'source=' => ONE
|
353
|
+
}
|
354
|
+
class << ret
|
355
|
+
def clear
|
356
|
+
@scope.write "#{@command}:CLEAR"
|
357
|
+
end
|
358
|
+
end
|
359
|
+
ret
|
360
|
+
end
|
361
|
+
|
362
|
+
# @endgroup
|
363
|
+
|
364
|
+
# @group Waveform Commands
|
365
|
+
def waveform
|
366
|
+
Relation::Base.new self, ':WAVEFORM', {'data' => ONE_ZERO, 'points' => {'mode' => ZERO, 'mode=' => ONE}}
|
367
|
+
end
|
368
|
+
# @endgroup
|
369
|
+
|
370
|
+
# @group Logic Analyzer Commands
|
371
|
+
def group(n)
|
372
|
+
raise ArgumentError 'group must be 1 or 2' unless n == 1 || n == 2
|
373
|
+
Relation::Group.new self, n
|
374
|
+
end
|
375
|
+
|
376
|
+
def logic_analyzer
|
377
|
+
Relation::Base.new self, ':la', {
|
378
|
+
'sdisplay' => ZERO,
|
379
|
+
'threshold' => ZERO,
|
380
|
+
'position' => {'reset' => ZERO},
|
381
|
+
'group1' => {'size' => ZERO},
|
382
|
+
'group2' => {'size' => ZERO},
|
383
|
+
'sdisplay=' => ONE,
|
384
|
+
'threshold=' => ONE,
|
385
|
+
}
|
386
|
+
end
|
387
|
+
|
388
|
+
def digital(m)
|
389
|
+
raise ArgumentError 'digital channel must be 0..15' unless (m && m >=0 && m < 16)
|
390
|
+
Relation::Base.new self, ":digital#{m}", {
|
391
|
+
'turn' => ZERO,
|
392
|
+
'turn=' => ONE,
|
393
|
+
'position' => ZERO,
|
394
|
+
'position=' => ONE
|
395
|
+
}
|
396
|
+
end
|
397
|
+
# @endgroup
|
398
|
+
|
399
|
+
# @group Key Commands
|
400
|
+
def key
|
401
|
+
Relation::Key.new self
|
402
|
+
end
|
403
|
+
# @endgroup
|
404
|
+
|
405
|
+
# @group Other Commands
|
406
|
+
def counter
|
407
|
+
Relation::Base.new self, ":COUNTER", {'value' => ZERO, 'enable' => ZERO, 'enable=' => ONE}
|
408
|
+
end
|
409
|
+
|
410
|
+
def beep
|
411
|
+
Relation::Base.new self, ':beep', {'enable' => ZERO, 'enable=' => ONE, 'action' => ZERO}
|
412
|
+
end
|
413
|
+
# @endgroup
|
414
|
+
|
415
|
+
def connected?; !!@session.connected?; end
|
416
|
+
end
|
417
|
+
end
|
418
|
+
end
|
419
|
+
|
420
|
+
require 'oscope/relation'
|
metadata
ADDED
@@ -0,0 +1,130 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: oscope
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.2.2
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- tduehr
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2015-02-03 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: airby
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: 0.1.0
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: 0.1.0
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: ffi
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: 1.9.6
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: 1.9.6
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: yard
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: 0.8.7
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: 0.8.7
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: bundler
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - "~>"
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '1.0'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - "~>"
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '1.0'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: jeweler
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - "~>"
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: 1.8.7
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - "~>"
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: 1.8.7
|
83
|
+
description: SCPI (IEEE 488.2) interface. Only the Rigol DS1102D oscilloscope is implemented
|
84
|
+
currently. All SCPI interfaces *should* be supported.
|
85
|
+
email: tduehr@gmail.com
|
86
|
+
executables: []
|
87
|
+
extensions: []
|
88
|
+
extra_rdoc_files:
|
89
|
+
- LICENSE
|
90
|
+
- README.md
|
91
|
+
files:
|
92
|
+
- Gemfile
|
93
|
+
- LICENSE
|
94
|
+
- README.md
|
95
|
+
- Rakefile
|
96
|
+
- VERSION.yml
|
97
|
+
- oscope.gemspec
|
98
|
+
- oscope/relation.rb
|
99
|
+
- oscope/relation/base.rb
|
100
|
+
- oscope/relation/channel.rb
|
101
|
+
- oscope/relation/group.rb
|
102
|
+
- oscope/relation/key.rb
|
103
|
+
- oscope/relation/query.rb
|
104
|
+
- oscope/relation/write.rb
|
105
|
+
- oscope/rigol/ds1102d.rb
|
106
|
+
homepage: http://github.com/tduehr/oscope
|
107
|
+
licenses:
|
108
|
+
- MIT
|
109
|
+
metadata: {}
|
110
|
+
post_install_message:
|
111
|
+
rdoc_options: []
|
112
|
+
require_paths:
|
113
|
+
- lib
|
114
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
115
|
+
requirements:
|
116
|
+
- - ">="
|
117
|
+
- !ruby/object:Gem::Version
|
118
|
+
version: '0'
|
119
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
120
|
+
requirements:
|
121
|
+
- - ">="
|
122
|
+
- !ruby/object:Gem::Version
|
123
|
+
version: '0'
|
124
|
+
requirements: []
|
125
|
+
rubyforge_project:
|
126
|
+
rubygems_version: 2.4.5
|
127
|
+
signing_key:
|
128
|
+
specification_version: 4
|
129
|
+
summary: SCPI command interface
|
130
|
+
test_files: []
|