oscilloscope 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
data/bin/oscilloscope ADDED
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'oscilloscope'
@@ -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
@@ -0,0 +1,10 @@
1
+ require "gosu"
2
+ require "arduino_firmata"
3
+
4
+ require 'display.rb'
5
+ require 'arduino_reader.rb'
6
+ require 'analog_input.rb'
7
+ require 'window.rb'
8
+
9
+ window = ScopeWindow.new
10
+ window.show
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: []