oscilloscope 0.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/bin/oscilloscope +3 -0
- data/lib/analog_input.rb +70 -0
- data/lib/arduino_reader.rb +56 -0
- data/lib/display.rb +62 -0
- data/lib/oscilloscope.rb +10 -0
- data/lib/window.rb +46 -0
- metadata +83 -0
data/bin/oscilloscope
ADDED
data/lib/analog_input.rb
ADDED
@@ -0,0 +1,70 @@
|
|
1
|
+
class AnalogInput
|
2
|
+
attr_reader :data, :pin, :value, :window
|
3
|
+
attr_accessor :visible
|
4
|
+
|
5
|
+
COLORS = [Gosu::Color::GREEN,Gosu::Color::CYAN,Gosu::Color::YELLOW,Gosu::Color::FUCHSIA,Gosu::Color::BLUE,Gosu::Color::WHITE,Gosu::Color::GRAY]
|
6
|
+
|
7
|
+
def self.[](p)
|
8
|
+
i=@@inputs.select {|x| x.pin == p }.first
|
9
|
+
return i || nil
|
10
|
+
end
|
11
|
+
|
12
|
+
def self.all
|
13
|
+
@@inputs ||= []
|
14
|
+
@@inputs
|
15
|
+
end
|
16
|
+
|
17
|
+
def initialize(args={})
|
18
|
+
@@inputs ||=[]
|
19
|
+
|
20
|
+
@window = args[:window]
|
21
|
+
@pin = args[:pin]
|
22
|
+
@data = []
|
23
|
+
@value = 0
|
24
|
+
@visible = args[:visible]||false
|
25
|
+
@font_large ||= Gosu::Font.new(30)
|
26
|
+
@font_small ||= Gosu::Font.new(20)
|
27
|
+
@yscale = @window.yscale
|
28
|
+
@height = @window.height
|
29
|
+
|
30
|
+
@@inputs << self
|
31
|
+
end
|
32
|
+
|
33
|
+
def callback(v)
|
34
|
+
@value = v
|
35
|
+
end
|
36
|
+
|
37
|
+
def update
|
38
|
+
@data.shift if @data.count > (@window.scope_width / @window.update_interval)
|
39
|
+
@data << {
|
40
|
+
voltage: @value/204.6,
|
41
|
+
value: @value,
|
42
|
+
time: Gosu::milliseconds
|
43
|
+
}
|
44
|
+
end
|
45
|
+
|
46
|
+
def draw
|
47
|
+
draw_line if visible
|
48
|
+
draw_label
|
49
|
+
end
|
50
|
+
|
51
|
+
def draw_label
|
52
|
+
margin = 60*self.pin
|
53
|
+
@font_large.draw("Analog #{self.pin}",@window.scope_width+5,10+margin,0,1.0,1.0, COLORS[self.pin])
|
54
|
+
@font_small.draw("#{sprintf('%.2fv',@data[-1][:voltage])} #{ self.visible ? @data[-1][:value] : "(hidden)"}",@window.scope_width+5,40+margin,0,1.0,1.0, COLORS[self.pin])
|
55
|
+
return true
|
56
|
+
end
|
57
|
+
|
58
|
+
def draw_line
|
59
|
+
(0..self.data.length - 2).each do |i|
|
60
|
+
x1=self.data[i][:time] - self.data[0][:time]
|
61
|
+
y1=@height-(self.data[i][:voltage]*@yscale)
|
62
|
+
|
63
|
+
x2=@data[i+1][:time] - @data[0][:time]
|
64
|
+
y2=@height-(self.data[i+1][:voltage]*@yscale)
|
65
|
+
|
66
|
+
@window.draw_line(x1,y1,COLORS[self.pin],x2,y2,COLORS[self.pin])
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
end
|
@@ -0,0 +1,56 @@
|
|
1
|
+
|
2
|
+
class ArduinoReader
|
3
|
+
def initialize(window)
|
4
|
+
@window = window
|
5
|
+
|
6
|
+
@inputs = []
|
7
|
+
connect
|
8
|
+
pwm
|
9
|
+
setup_callbacks
|
10
|
+
end
|
11
|
+
|
12
|
+
private
|
13
|
+
|
14
|
+
def pwm
|
15
|
+
# Setup PWM on pin 9 for 50% cycle to produce a square wave for testing.
|
16
|
+
@arduino.analog_write 9,127
|
17
|
+
end
|
18
|
+
|
19
|
+
def connect
|
20
|
+
# Use first arduino found
|
21
|
+
@arduino = ArduinoFirmata.connect nil, :nonblock_io => true
|
22
|
+
end
|
23
|
+
|
24
|
+
def setup_callbacks
|
25
|
+
@arduino.on :analog_read do |pin, value|
|
26
|
+
AnalogInput.new(window: @window, pin: pin) unless AnalogInput[pin]
|
27
|
+
AnalogInput[pin].callback(value)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
end
|
32
|
+
|
33
|
+
class FakeArduinoReader < ArduinoReader
|
34
|
+
|
35
|
+
def connect
|
36
|
+
@inputs << AnalogInput.new(window: @window, pin: 0)
|
37
|
+
@inputs << AnalogInput.new(window: @window, pin: 1)
|
38
|
+
end
|
39
|
+
|
40
|
+
def pwm
|
41
|
+
return true
|
42
|
+
end
|
43
|
+
|
44
|
+
def setup_callbacks
|
45
|
+
Thread.new {
|
46
|
+
loop do
|
47
|
+
AnalogInput[0].callback(0)
|
48
|
+
AnalogInput[1].callback(rand(1023))
|
49
|
+
sleep 0.09
|
50
|
+
AnalogInput[0].callback(1023)
|
51
|
+
sleep 0.09
|
52
|
+
end
|
53
|
+
}
|
54
|
+
end
|
55
|
+
|
56
|
+
end
|
data/lib/display.rb
ADDED
@@ -0,0 +1,62 @@
|
|
1
|
+
class MinMaxText
|
2
|
+
def initialize(w,min=0,max=5)
|
3
|
+
@window = w
|
4
|
+
@width = @window.scope_width
|
5
|
+
@height = @window.height
|
6
|
+
@font = Gosu::Font.new(12)
|
7
|
+
|
8
|
+
@min = min
|
9
|
+
@max = max
|
10
|
+
|
11
|
+
end
|
12
|
+
|
13
|
+
def draw
|
14
|
+
@font.draw("#{@max}v", @width-20, 10, 0, 1.0, 1.0, 0xff_ffff00)
|
15
|
+
@font.draw("#{@min}v", @width-20, @height-20, 0, 1.0, 1.0, 0xff_ffff00)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
class CenterLine
|
20
|
+
def initialize(w)
|
21
|
+
@window = w
|
22
|
+
@interval = @window.update_interval
|
23
|
+
@height = @window.height
|
24
|
+
@width = @window.scope_width
|
25
|
+
@font = Gosu::Font.new(12)
|
26
|
+
end
|
27
|
+
|
28
|
+
def draw
|
29
|
+
line
|
30
|
+
time
|
31
|
+
end
|
32
|
+
|
33
|
+
private
|
34
|
+
|
35
|
+
def line
|
36
|
+
@window.draw_line(0,@height/2,Gosu::Color::RED, @width,@height/2,Gosu::Color::RED)
|
37
|
+
end
|
38
|
+
|
39
|
+
def time
|
40
|
+
(0..@width/@interval).each do |i|
|
41
|
+
t=(@interval*i)
|
42
|
+
@font.draw("#{t.to_i}", @width-8-(@width/@interval)*i,@height/2+10,0,1.0,1.0,Gosu::Color::GRAY)
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
class RightLine
|
48
|
+
def initialize(w)
|
49
|
+
@window = w
|
50
|
+
@width = @window.scope_width
|
51
|
+
@height = @window.height
|
52
|
+
end
|
53
|
+
|
54
|
+
def draw
|
55
|
+
line
|
56
|
+
end
|
57
|
+
|
58
|
+
private
|
59
|
+
def line
|
60
|
+
@window.draw_line(@width,0,Gosu::Color::RED, @width, @height,Gosu::Color::RED)
|
61
|
+
end
|
62
|
+
end
|
data/lib/oscilloscope.rb
ADDED
data/lib/window.rb
ADDED
@@ -0,0 +1,46 @@
|
|
1
|
+
class ScopeWindow < Gosu::Window
|
2
|
+
attr_reader :max_volts, :yscale, :clock, :scope_width
|
3
|
+
attr_accessor :display_pins
|
4
|
+
def initialize
|
5
|
+
super 1024+124,768
|
6
|
+
|
7
|
+
@scope_width = 1023
|
8
|
+
self.caption = "Oscilloscope"
|
9
|
+
|
10
|
+
@font = Gosu::Font.new(18)
|
11
|
+
|
12
|
+
@max_volts = 5
|
13
|
+
@yscale=(self.height/@max_volts)
|
14
|
+
@paused = false
|
15
|
+
|
16
|
+
@center_line = CenterLine.new(self)
|
17
|
+
@minmaxtext = MinMaxText.new(self)
|
18
|
+
@right_line = RightLine.new(self)
|
19
|
+
@ar = ArduinoReader.new(self)
|
20
|
+
# @ar = FakeArduinoReader.new(self)
|
21
|
+
AnalogInput[0].visible = true
|
22
|
+
end
|
23
|
+
|
24
|
+
def button_down(id)
|
25
|
+
close if id == Gosu::KbEscape or id == Gosu::KbQ
|
26
|
+
@paused = ! @paused if id == Gosu::KbP
|
27
|
+
|
28
|
+
[Gosu::Kb0,Gosu::Kb1,Gosu::Kb2,Gosu::Kb3,Gosu::Kb4,Gosu::Kb5].each_with_index {|b,i|
|
29
|
+
AnalogInput[i].visible = ! AnalogInput[i].visible if AnalogInput[i] if id == b
|
30
|
+
}
|
31
|
+
|
32
|
+
end
|
33
|
+
|
34
|
+
def update
|
35
|
+
return if @paused
|
36
|
+
AnalogInput.all.each {|i| i.update }
|
37
|
+
end
|
38
|
+
|
39
|
+
def draw
|
40
|
+
# Draw interface
|
41
|
+
@center_line.draw
|
42
|
+
@right_line.draw
|
43
|
+
@minmaxtext.draw
|
44
|
+
AnalogInput.all.each {|i| i.draw }
|
45
|
+
end
|
46
|
+
end
|
metadata
ADDED
@@ -0,0 +1,83 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: oscilloscope
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.1
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- James Paterni
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2015-11-18 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: gosu
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ~>
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: 0.10.4
|
22
|
+
type: :runtime
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ~>
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: 0.10.4
|
30
|
+
- !ruby/object:Gem::Dependency
|
31
|
+
name: arduino_firmata
|
32
|
+
requirement: !ruby/object:Gem::Requirement
|
33
|
+
none: false
|
34
|
+
requirements:
|
35
|
+
- - ~>
|
36
|
+
- !ruby/object:Gem::Version
|
37
|
+
version: 0.3.7
|
38
|
+
type: :runtime
|
39
|
+
prerelease: false
|
40
|
+
version_requirements: !ruby/object:Gem::Requirement
|
41
|
+
none: false
|
42
|
+
requirements:
|
43
|
+
- - ~>
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
version: 0.3.7
|
46
|
+
description: A poor man oscilloscope using ruby and an arduino.
|
47
|
+
email: james@ruby-code.com
|
48
|
+
executables:
|
49
|
+
- oscilloscope
|
50
|
+
extensions: []
|
51
|
+
extra_rdoc_files: []
|
52
|
+
files:
|
53
|
+
- lib/analog_input.rb
|
54
|
+
- lib/arduino_reader.rb
|
55
|
+
- lib/display.rb
|
56
|
+
- lib/oscilloscope.rb
|
57
|
+
- lib/window.rb
|
58
|
+
- bin/oscilloscope
|
59
|
+
homepage:
|
60
|
+
licenses: []
|
61
|
+
post_install_message:
|
62
|
+
rdoc_options: []
|
63
|
+
require_paths:
|
64
|
+
- lib
|
65
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
66
|
+
none: false
|
67
|
+
requirements:
|
68
|
+
- - ! '>='
|
69
|
+
- !ruby/object:Gem::Version
|
70
|
+
version: '0'
|
71
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
72
|
+
none: false
|
73
|
+
requirements:
|
74
|
+
- - ! '>='
|
75
|
+
- !ruby/object:Gem::Version
|
76
|
+
version: '0'
|
77
|
+
requirements: []
|
78
|
+
rubyforge_project:
|
79
|
+
rubygems_version: 1.8.25
|
80
|
+
signing_key:
|
81
|
+
specification_version: 3
|
82
|
+
summary: Osilloscope
|
83
|
+
test_files: []
|