farmbot-serial 0.0.6 → 0.0.7

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 968bffc9904f9b3d733c91107ec83caeb632353a
4
- data.tar.gz: 0eb0a17a2e6923e3e0ef2ec8228c5ebf2d99cd09
3
+ metadata.gz: 52d9fa1d6b06912cce708e6ef54f9b07035678d1
4
+ data.tar.gz: 665482bd2b934eea96f01a820b886f07df5c3170
5
5
  SHA512:
6
- metadata.gz: fd10320b1219e6001c2e5bb73ffc3cada2e4bd5e9efcaa35ba72476a2667c8969cf3b18eb3c493937c57c37605b5855b52606fd4c38bed5b2395eae0a68a7cd4
7
- data.tar.gz: fe5fc6bead0a8fb4d39ab7a1235f3436f3730b2505d2b01e94f9792258136b6ba8bd29b5a884e1c2d09938eefc2de34a286c1a86b7f37b1e58ffe82771c40387
6
+ metadata.gz: 75aefd6382c999e9af8d5417cfbb540122c2bcbe3808c522bef641731ba586ec9fbb4452a1cc42f1356a765b219318f37c8208fc5c31c74581b05070dcd08f73
7
+ data.tar.gz: 09c86b75932a49c9dbd486e15b906a3ce7982dd243bfcee092584014c6910e3fd8e59fcca3d1f1cac88fda5c8f128f615d0d6fe2d9f581f4c95e7682d774f590
data/README.md CHANGED
@@ -9,22 +9,38 @@ gem install farmbot-serial, '0.0.5'
9
9
  ```
10
10
 
11
11
  ```ruby
12
+ require 'farmbot-serial'
13
+
12
14
  bot = FB::Arduino.new # Defaults to '/dev/ttyACM0', can be configured.
13
15
 
14
16
  EM.run do
15
17
  FB::ArduinoEventMachine.connect(bot)
16
18
 
17
19
  # Example 1: Writing to the serial line the "correct way" every 1.5 seconds.
18
- command = FB::Gcode.new('G01 X01 Y01 Z01')
19
- EventMachine::PeriodicTimer.new(1.5) { bot.commands.move_relative(command) }
20
+ EventMachine::PeriodicTimer.new(1.5) do
21
+ bot.commands.move_relative(x: 100, y: 50)
22
+ end
20
23
 
21
- # Example 2: Writing raw strings to serial every 2.5
22
- EventMachine::PeriodicTimer.new(2.5) { bot.write("F31 P8") }
24
+ # Example 2: Writing raw gcode object to serial every 2.5
25
+ EventMachine::PeriodicTimer.new(2.5) { bot.write FB::Gcode.new("F31 P8") }
23
26
 
24
27
  # This will execute after status has been updated / internal code.
25
- bot.onmessage { |gcode| puts "SERIAL IN: #{gcode.name}" }
28
+ bot.onmessage { |gcode| puts "Message just came in." }
26
29
 
27
30
  # Try pulling the USB cable out to test this one.
28
- bot.onclose { EM.stop }
31
+ bot.onclose { puts "bye!"; EM.stop }
29
32
  end
33
+
30
34
  ```
35
+
36
+ # Upgrading to Ruby 2.2
37
+
38
+ This gem requires Ruby 2.2. As of this writing, a Pi is loaded with 1.9.3 by default.
39
+
40
+ To upgrade your ruby version, try this:
41
+
42
+ ```
43
+ curl -L https://get.rvm.io | bash -s stable --ruby
44
+ ```
45
+
46
+ This will take about 2 hours on a standard pi.
data/Rakefile CHANGED
@@ -1,9 +1,9 @@
1
- require 'rake/testtask'
1
+ # require 'rake/testtask'
2
2
 
3
- Rake::TestTask.new do |t|
4
- t.libs << 'test'
5
- t.test_files = Dir.glob('test/**/*_test.rb')
6
- end
3
+ # Rake::TestTask.new do |t|
4
+ # t.libs << 'test'
5
+ # t.test_files = Dir.glob('test/**/*_test.rb')
6
+ # end
7
7
 
8
- desc "Run tests"
9
- task :default => :test
8
+ # desc "Run tests"
9
+ # task :default => :test
data/example.rb CHANGED
@@ -3,19 +3,47 @@ require 'pry'
3
3
 
4
4
  bot = FB::Arduino.new # Defaults to '/dev/ttyACM0', can be configured.
5
5
 
6
- EM.run do
7
- FB::ArduinoEventMachine.connect(bot)
6
+ puts """
7
+ FARMBOT SERIAL SANDBOX. WELCOME!
8
+ ================================"""
9
+ $commands = {
10
+ "q" => "bot.commands.emergency_stop",
11
+ "w" => "bot.commands.move_relative(x: 600)",
12
+ "s" => "bot.commands.move_relative(x: -600)",
13
+ "e" => "bot.commands.home_x",
14
+ "r" => "bot.commands.home_y",
15
+ "t" => "bot.commands.home_z",
16
+ "y" => "bot.commands.home_all",
17
+ "u" => "bot.commands.read_parameter(8)",
18
+ "i" => "bot.commands.write_parameter",
19
+ "p" => "bot.commands.read_status(8)",
20
+ }
21
+
22
+ $commands.each { |k, v| puts "#{k}: #{v}" }
8
23
 
9
- # Example 1: Writing to the serial line the "correct way" every 1.5 seconds.
10
- command = FB::Gcode.new('G01 X01 Y01 Z01')
11
- EventMachine::PeriodicTimer.new(1.5) { bot.commands.move_relative(command) }
24
+ class KeyboardHandler < EM::Connection
25
+ include EM::Protocols::LineText2
12
26
 
13
- # Example 2: Writing raw strings to serial every 2.5
14
- EventMachine::PeriodicTimer.new(2.5) { bot.write("F31 P8") }
27
+ attr_reader :bot
15
28
 
16
- # This will execute after status has been updated / internal code.
17
- bot.onmessage { |gcode| puts "SERIAL IN: #{gcode.name}" }
29
+ def initialize(bot)
30
+ @bot = bot
31
+ end
18
32
 
19
- # Try pulling the USB cable out to test this one.
20
- bot.onclose { EM.stop }
33
+ def receive_line(data)
34
+ cmd = $commands[data] || ""
35
+ eval(cmd)
36
+ end
21
37
  end
38
+
39
+ puts "Starting now."
40
+
41
+ EM.run do
42
+ FB::ArduinoEventMachine.connect(bot)
43
+ bot.onmessage { |gcode| print "#{gcode.name}; " }
44
+ bot.onchange { |diff| print "#{diff}; " }
45
+ bot.onclose { puts "bye!"; EM.stop } # Unplug the bot and see
46
+ # EventMachine::PeriodicTimer.new(2) { bot.serial_port.puts "G82" }
47
+ EM.open_keyboard(KeyboardHandler, bot)
48
+ end
49
+
@@ -1,6 +1,7 @@
1
1
  require 'serialport'
2
2
  require_relative 'default_serial_port'
3
- require_relative 'arduino/command_set'
3
+ require_relative 'arduino/incoming_handler'
4
+ require_relative 'arduino/outgoing_handler'
4
5
  require_relative 'arduino/event_machine'
5
6
  require_relative 'arduino/status'
6
7
  # Communicate with the arduino using a serial interface
@@ -8,14 +9,23 @@ module FB
8
9
  class Arduino
9
10
  class EmergencyStop < StandardError; end # Not yet used.
10
11
 
11
- attr_reader :serial_port, :logger, :commands, :queue, :status
12
+ attr_reader :serial_port, :logger, :commands, :inbound_queue, :status,
13
+ :inputs, :outbound_queue
12
14
 
13
- # Initial and provide a serial object, as well as an IO object to send
15
+ # Initialize and provide a serial object, as well as an IO object to send
14
16
  # log messages to. Default SerialPort is DefaultSerialPort. Default logger
15
17
  # is STDOUT
16
- def initialize(serial_port = DefaultSerialPort.new, logger = STDOUT)
17
- @serial_port, @logger, @queue = serial_port, logger, EM::Channel.new
18
- @commands, @status = FB::ArduinoCommandSet.new(self), FB::Status.new(self)
18
+ def initialize(serial_port: DefaultSerialPort.new, logger: STDOUT)
19
+ @outbound_queue = [] # Pi -> Arduino Gcode
20
+ @inbound_queue = EM::Channel.new # Pi <- Arduino
21
+
22
+ @serial_port = serial_port
23
+ @logger = logger
24
+ @commands = FB::OutgoingHandler.new(self)
25
+ @inputs = FB::IncomingHandler.new(self)
26
+ @status = FB::Status.new(self)
27
+
28
+ start_event_listeners
19
29
  end
20
30
 
21
31
  # Log to screen/file/IO stream
@@ -23,36 +33,62 @@ module FB
23
33
  logger.puts(message)
24
34
  end
25
35
 
26
- # Highest priority message when processing incoming Gcode. Use for system
27
- # level status changes.
28
- def parse_incoming(gcode)
29
- commands.execute(gcode)
36
+ # Send outgoing test to arduino from pi
37
+ def write(string)
38
+ @outbound_queue.unshift string
39
+ execute_command_next_tick
40
+ end
41
+
42
+ def onchange(&blk)
43
+ @onchange = blk
30
44
  end
31
45
 
32
46
  # Handle incoming text from arduino into pi
33
47
  def onmessage(&blk)
34
- raise 'read() requires a block' unless block_given?
35
- @queue.subscribe do |gcodes|
36
- gcodes.each do |gcode|
37
- parse_incoming(gcode)
38
- blk.call(gcode)
39
- end
40
- end
48
+ @onmessage = blk
41
49
  end
42
50
 
43
51
  def onclose(&blk)
44
52
  @onclose = blk
45
53
  end
46
54
 
47
- # Send outgoing test to arduino from pi
48
- def write(string)
49
- serial_port.puts string
50
- end
51
-
52
55
  # Handle loss of serial connection
53
56
  def disconnect
54
57
  log "Connection to device lost"
55
58
  @onclose.call if @onclose
56
59
  end
60
+
61
+ private
62
+
63
+ # Highest priority message when processing incoming Gcode. Use for system
64
+ # level status changes.
65
+ def parse_incoming(gcode)
66
+ inputs.execute(gcode)
67
+ end
68
+
69
+ def execute_command_next_tick
70
+ EM.next_tick do
71
+ if status.ready?
72
+ diff = (Time.now - (@time || Time.now)).to_i
73
+ log "Sending queue after #{diff}s delay" if diff > 0
74
+ serial_port.puts @outbound_queue.pop
75
+ @time = nil
76
+ else
77
+ @time ||= Time.now
78
+ serial_port.puts "F31 P8"
79
+ execute_command_next_tick
80
+ end
81
+ end
82
+ end
83
+
84
+ def start_event_listeners
85
+ status.onchange { |diff| @onchange.call(diff) if @onchange }
86
+ inbound_queue.subscribe do |gcodes|
87
+ gcodes.each do |gcode|
88
+ parse_incoming(gcode)
89
+ @onmessage.call(gcode) if @onmessage
90
+ end
91
+ end
92
+ end
57
93
  end
58
94
  end
@@ -7,12 +7,9 @@ module FB
7
7
  attr_accessor :arduino
8
8
  end
9
9
 
10
- def self.poll(interval, &blk)
11
- EventMachine::PeriodicTimer.new(interval.to_f, &blk)
12
- end
13
-
14
10
  def initialize
15
- @q, @buffer = self.class.arduino.queue, ''
11
+ @bot = self.class.arduino
12
+ @q, @buffer = @bot.inbound_queue, ''
16
13
  end
17
14
 
18
15
  # Gets called when data arrives.
@@ -23,7 +20,7 @@ module FB
23
20
  send_buffer
24
21
  clear_buffer
25
22
  else
26
- add_to_buffer(chunk)
23
+ add_to_buffer(chunk) # Keep RXing the buffer until chunk completes.
27
24
  end
28
25
  end
29
26
  end
@@ -32,7 +29,7 @@ module FB
32
29
  # splits the data on \r\n. Unlike Ruby's split() method, this method will
33
30
  # preserve the \r\n.
34
31
  def split_into_chunks(data)
35
- data.gsub("\r\n", '!@').split('@').map{ |d| d.gsub('!', "\r\n") }
32
+ data.gsub("\r\n", '\b\a').split('\a').map{ |d| d.gsub('\b', "\r\n") }
36
33
  end
37
34
 
38
35
  def clear_buffer
@@ -0,0 +1,50 @@
1
+ module FB
2
+ # Handles Gcode that moves from the Arduino to the Pi (Arduino -> Pi).
3
+ class IncomingHandler
4
+ attr_reader :bot
5
+
6
+ class UnhandledGcode < StandardError; end
7
+
8
+ def initialize(bot)
9
+ @bot = bot
10
+ end
11
+
12
+ def execute(gcode)
13
+ self.send(gcode.name, gcode)
14
+ rescue NoMethodError
15
+ bot.log "#{gcode.name} is a valid GCode, but no input handler method exists"
16
+ end
17
+
18
+ def unknown(gcode)
19
+ bot.log "Don't know how to parse incoming GCode: #{gcode}"
20
+ end
21
+
22
+ def received(gcode)
23
+ bot.status[:busy] = 1
24
+ end
25
+
26
+ def reporting_end_stops(gcode)
27
+ bot.status.gcode_update(gcode)
28
+ end
29
+
30
+ def report_current_position(gcode)
31
+ bot.status.gcode_update(gcode)
32
+ end
33
+
34
+ def done(gcode)
35
+ bot.status[:busy] = 0
36
+ end
37
+
38
+ def busy(gcode)
39
+ bot.status[:busy] = 1
40
+ end
41
+
42
+ def report_status_value(gcode)
43
+ bot.status.gcode_update(gcode)
44
+ end
45
+
46
+ def report_software_version(gcode)
47
+ nil # Don't need the info right now.
48
+ end
49
+ end
50
+ end
@@ -0,0 +1,57 @@
1
+ module FB
2
+ # Responsible for writing to the serial line. Sends Gcode from the pi to the
3
+ # arduino. (Pi -> Arduino)
4
+ class OutgoingHandler
5
+ attr_reader :bot
6
+
7
+ class UnhandledGcode < StandardError; end
8
+
9
+ def initialize(bot)
10
+ @bot = bot
11
+ end
12
+
13
+ def emergency_stop(*)
14
+ bot.outbound_queue = [] # Dump pending commands.
15
+ bot.serial_port.puts "E" # Don't queue this one- write to serial line.
16
+ end
17
+
18
+ def move_relative(x: 0, y: 0, z: 0, s: 100)
19
+ write "G00 X#{x} Y#{y} Z#{z}"
20
+ end
21
+
22
+ def home_x
23
+ write "F11"
24
+ end
25
+
26
+ def home_y
27
+ write "F12"
28
+ end
29
+
30
+ def home_z
31
+ write "F13"
32
+ end
33
+
34
+ def home_all
35
+ write "G28"
36
+ end
37
+
38
+ def read_parameter(num)
39
+ write "F21 P#{num}"
40
+ end
41
+
42
+ def write_parameter(num, val)
43
+ write "F22 P#{num} V#{val}"
44
+ end
45
+
46
+ def read_status(pin)
47
+ write "F31 P#{pin}"
48
+ end
49
+
50
+ private
51
+
52
+ def write(str)
53
+ bot.write(FB::Gcode.new(str))
54
+ end
55
+ end
56
+ end
57
+
@@ -3,23 +3,48 @@ module FB
3
3
  # Map of informational status and default values for status within Arduino.
4
4
  DEFAULT_INFO = {X: 0, Y: 0, Z: 0, S: 10, Q: 0, T: 0, C: '', P: 0, V: 0,
5
5
  W: 0, L: 0, E: 0, M: 0, XA: 0, XB: 0, YA: 0, YB: 0, ZA: 0,
6
- ZB: 0, busy: 1}
7
- # Put it into a struct.
6
+ ZB: 0,YR: 0, R: 0, BUSY: 0}
8
7
  Info = Struct.new(*DEFAULT_INFO.keys)
9
8
 
10
9
  attr_reader :bot
11
10
 
12
11
  def initialize(bot)
12
+ @changes = EM::Channel.new
13
13
  @bot, @info = bot, Info.new(*DEFAULT_INFO.values)
14
14
  end
15
15
 
16
+ def transaction(&blk)
17
+ old = @info.to_h
18
+ yield
19
+ emit_updates(old)
20
+ end
21
+
16
22
  def []=(register, value)
17
- # Add event broadcasts here!!!
18
- @info[value.upcase.to_sym] = value
23
+ transaction { @info[register.upcase.to_sym] = value }
19
24
  end
20
25
 
21
26
  def [](value)
22
27
  @info[value.upcase.to_sym]
23
28
  end
29
+
30
+ def gcode_update(gcode)
31
+ transaction do
32
+ gcode.params.each { |p| @info.send("#{p.head}=", p.tail) }
33
+ end
34
+ end
35
+
36
+ def onchange
37
+ @changes.subscribe { |diff| yield(diff) }
38
+ end
39
+
40
+ def ready?
41
+ self[:BUSY] == 0
42
+ end
43
+
44
+ def emit_updates(old)
45
+ # calculate a diff between the old status and new status
46
+ diff = (@info.to_h.to_a - old.to_a).to_h
47
+ @changes << diff unless diff.empty?
48
+ end
24
49
  end
25
50
  end
@@ -8,7 +8,7 @@ module FB
8
8
  def initialize(str)
9
9
  @str = str
10
10
  @params = str.split(' ').map{|line| GcodeToken.new(line)}
11
- @cmd = @params.shift
11
+ @cmd = @params.shift || 'NULL'
12
12
  end
13
13
 
14
14
  # Turns a string of many gcodes into an array of many gcodes. Used to parse
@@ -22,6 +22,10 @@ module FB
22
22
  GCODE_DICTIONARY[cmd.to_sym] || :unknown
23
23
  end
24
24
 
25
+ def to_s
26
+ [@cmd, *@params].map(&:to_s).join(" ")
27
+ end
28
+
25
29
  # A head/tail pair of a single node of GCode. Ex: R01 = [:R, '01']
26
30
  class GcodeToken
27
31
  attr_reader :head, :tail, :name
@@ -29,10 +33,16 @@ module FB
29
33
  def initialize(str)
30
34
  nodes = str.scan(/\d+|\D+/) # ["R", "01"]
31
35
  @head, @tail = nodes.shift.to_sym, nodes.join(" ")
36
+ # Coerce to ints if possible, since serial line is all string types.
37
+ @tail = @tail.to_i if @tail.match(/^\d+$/)
32
38
  end
33
39
 
34
40
  def to_sym
35
- "#{head}#{tail}".to_sym
41
+ to_s.to_sym
42
+ end
43
+
44
+ def to_s
45
+ "#{head}#{tail}"
36
46
  end
37
47
  end
38
48
  end
@@ -26,10 +26,10 @@
26
26
  :F82: :report_current_position
27
27
  :F83: :report_software_version
28
28
  :E: :emergency_stop
29
- :R01: :received
30
- :R02: :done
31
- :R03: :error
32
- :R04: :busy
29
+ :R1: :received
30
+ :R2: :done
31
+ :R3: :error
32
+ :R4: :busy
33
33
  :R21: :report_parameter_value
34
34
  :R31: :report_status_value
35
35
  :R41: :report_pin_value
@@ -1,17 +1,6 @@
1
1
  ## SERIAL PORT SIMULATION
2
2
  ## **********************
3
- module FB
4
- # Used for unit tests
5
- class StubSerialPort # TODO: Inherit from StringIO?
6
- def initialize(comm_port, parameters)
7
- end
8
-
9
- def write(text)
10
- text
11
- end
12
-
13
- def read(characters)
14
- characters
15
- end
3
+ class StubSerialPort < StringIO
4
+ def initialize(comm_port, parameters)
16
5
  end
17
6
  end
@@ -0,0 +1,26 @@
1
+ require 'spec_helper'
2
+
3
+ describe FB::Arduino do
4
+ let(:logger) { StringIO.new("") }
5
+ let(:bot) do
6
+ FB::Arduino.new(StubSerialPort.new(0, 0), logger)
7
+ end
8
+
9
+ it "initializes" do
10
+ expect(bot).to be_kind_of(FB::Arduino)
11
+ expect(bot.serial_port).to be_kind_of(StubSerialPort)
12
+ expect(bot.logger).to be_kind_of(StringIO)
13
+ expect(bot.commands).to be_kind_of(FB::OutgoingHandler)
14
+ expect(bot.queue).to be_kind_of(EM::Channel)
15
+ expect(bot.status).to be_kind_of(FB::Status)
16
+ expect(bot.inputs).to be_kind_of(FB::IncomingHandler)
17
+ end
18
+
19
+ it 'prints to the logger object' do
20
+ bot.log "Hello, World!"
21
+ bot.logger.rewind
22
+ expect(bot.logger.gets.chomp).to eq("Hello, World!")
23
+ end
24
+
25
+ end
26
+
@@ -0,0 +1,41 @@
1
+ require 'spec_helper'
2
+ describe FB::Gcode do
3
+ let(:gcode) { FB::Gcode.new("F31 P8 ")}
4
+
5
+ it("initializes from string") { expect(gcode).to be_kind_of(FB::Gcode) }
6
+
7
+ it("infers Gcode name") { expect(gcode.name).to eq(:read_status) }
8
+
9
+ it "returns :unknown for bad Gcode tokens" do
10
+ unknown = FB::Gcode.new("QQQ31 F32 ").name
11
+ expect(unknown).to eq(:unknown)
12
+ end
13
+
14
+ it("sets the original input string") { expect(gcode.str).to eq("F31 P8 ") }
15
+
16
+ it("sets @cmd using the first Gcode node") do
17
+ expect(gcode.cmd).to be_kind_of(FB::Gcode::GcodeToken)
18
+ expect(gcode.cmd.head).to eq(:F)
19
+ expect(gcode.cmd.tail).to eq(31)
20
+ end
21
+
22
+ it("sets @params using the last Gcode node(s)") do
23
+ expect(gcode.params).to be_kind_of(Array)
24
+ expect(gcode.params[0]).to be_kind_of(FB::Gcode::GcodeToken)
25
+ expect(gcode.params[0].head).to eq(:P)
26
+ expect(gcode.params[0].tail).to eq(8)
27
+ end
28
+
29
+ it("serializes back to string via #to_s") do
30
+ expect(gcode.to_s).to eq("F31 P8")
31
+ end
32
+
33
+ it "parses multiple Gcodes in a single string via parse_lines" do
34
+ codes = FB::Gcode.parse_lines("A12 B34\nC56 D78\r\n")
35
+ expect(codes.count).to eq(2)
36
+ expect(codes.first).to be_kind_of(FB::Gcode)
37
+ expect(codes.last.cmd.head).to eq(:C)
38
+ expect(codes.first.params.first.tail).to eq(34)
39
+ end
40
+ end
41
+
@@ -5,13 +5,6 @@ SimpleCov.start do
5
5
  end
6
6
  require 'pry'
7
7
  require 'farmbot-serial'
8
-
8
+ require_relative 'fixtures/stub_serial_port'
9
9
  RSpec.configure do |config|
10
- config.expect_with :rspec do |expectations|
11
- expectations.include_chain_clauses_in_custom_matcher_descriptions = true
12
- end
13
-
14
- config.mock_with :rspec do |mocks|
15
- mocks.verify_partial_doubles = true
16
- end
17
10
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: farmbot-serial
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.6
4
+ version: 0.0.7
5
5
  platform: ruby
6
6
  authors:
7
7
  - Tim Evers
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2015-03-27 00:00:00.000000000 Z
12
+ date: 2015-04-01 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: bundler
@@ -122,18 +122,18 @@ files:
122
122
  - Rakefile
123
123
  - example.rb
124
124
  - lib/arduino.rb
125
- - lib/arduino/command_set.rb
126
125
  - lib/arduino/event_machine.rb
126
+ - lib/arduino/incoming_handler.rb
127
+ - lib/arduino/outgoing_handler.rb
127
128
  - lib/arduino/status.rb
128
129
  - lib/default_serial_port.rb
129
130
  - lib/farmbot-serial.rb
130
131
  - lib/gcode.rb
131
132
  - lib/gcode.yml
132
- - lib/param.yml
133
133
  - spec/fixtures/stub_serial_port.rb
134
- - spec/lib/ramps_arduino_values_received_spec.rb
134
+ - spec/lib/arduino_spec.rb
135
+ - spec/lib/gcode_spec.rb
135
136
  - spec/spec_helper.rb
136
- - testcommands.csv
137
137
  homepage: http://github.com/farmbot/farmbot-serial
138
138
  licenses:
139
139
  - MIT
@@ -146,7 +146,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
146
146
  requirements:
147
147
  - - ">="
148
148
  - !ruby/object:Gem::Version
149
- version: '0'
149
+ version: 2.2.0
150
150
  required_rubygems_version: !ruby/object:Gem::Requirement
151
151
  requirements:
152
152
  - - ">="
@@ -160,5 +160,6 @@ specification_version: 4
160
160
  summary: Serial library for Farmbot
161
161
  test_files:
162
162
  - spec/fixtures/stub_serial_port.rb
163
- - spec/lib/ramps_arduino_values_received_spec.rb
163
+ - spec/lib/arduino_spec.rb
164
+ - spec/lib/gcode_spec.rb
164
165
  - spec/spec_helper.rb
@@ -1,39 +0,0 @@
1
- module FB
2
- # Composes all logic related to controlling a bot into a single object.
3
- # Responsible for writing to the serial line.
4
- class ArduinoCommandSet
5
- attr_reader :bot
6
-
7
- def initialize(bot)
8
- @bot = bot
9
- end
10
-
11
- def execute(gcode)
12
- puts "SERIAL OUT: #{gcode.name}"
13
- self.send(gcode.name, gcode)
14
- end
15
-
16
- def emergency_stop(*)
17
- bot.write("E")
18
- end
19
-
20
- def move_relative(gcode)
21
- end
22
-
23
- def received(gcode)
24
- end
25
-
26
- def reporting_end_stops(gcode)
27
- end
28
-
29
- def report_current_position(gcode)
30
- end
31
-
32
- def done(gcode)
33
- end
34
-
35
- def report_status_value(gcode)
36
- end
37
- end
38
- end
39
-
@@ -1,21 +0,0 @@
1
- # ---
2
- # X: :x_movement
3
- # Y: :y_movement
4
- # Z: :z_movement
5
- # S: :speed
6
- # Q: :quanity
7
- # T: :time
8
- # C: :comment
9
- # P: :parameter
10
- # V: :value_number
11
- # W: :secondary_value
12
- # L: :number
13
- # E: :element
14
- # M: :pin_mode
15
- # M: :read_write_mode
16
- # XA: :end_stop_1_x_axis
17
- # XB: :end_stop_2_x_axis
18
- # YA: :end_stop_1_y_axis
19
- # YB: :end_stop_2_y_axis
20
- # ZA: :end_stop_1_z_axis
21
- # ZB: :end_stop_2_z_axis
@@ -1,54 +0,0 @@
1
- require 'spec_helper'
2
- describe FB::HardwareInterfaceArduinoValuesReceived do
3
-
4
- before do
5
- @ramps = FB::HardwareInterfaceArduinoValuesReceived.new
6
- end
7
-
8
- it "load parameters" do
9
-
10
- p = rand(9999999).to_i
11
- v = rand(9999999).to_i
12
-
13
- x = rand(9999999).to_i
14
- y = rand(9999999).to_i
15
- z = rand(9999999).to_i
16
-
17
- xa = rand(9999999).to_i
18
- xb = rand(9999999).to_i
19
- ya = rand(9999999).to_i
20
- yb = rand(9999999).to_i
21
- za = rand(9999999).to_i
22
- zb = rand(9999999).to_i
23
-
24
- @ramps.load_parameter("P", p)
25
- @ramps.load_parameter("V", v)
26
- @ramps.load_parameter("X", x)
27
- @ramps.load_parameter("Y", y)
28
- @ramps.load_parameter("Z", z)
29
-
30
- @ramps.load_parameter("XA", xa)
31
- @ramps.load_parameter("XB", xb)
32
- @ramps.load_parameter("YA", ya)
33
- @ramps.load_parameter("YB", yb)
34
- @ramps.load_parameter("ZA", za)
35
- @ramps.load_parameter("ZB", zb)
36
-
37
- expect(@ramps.p).to eq(p)
38
- expect(@ramps.v).to eq(v)
39
-
40
- expect(@ramps.x).to eq(x)
41
- expect(@ramps.y).to eq(y)
42
- expect(@ramps.z).to eq(z)
43
-
44
- expect(@ramps.xa).to eq(xa)
45
- expect(@ramps.xb).to eq(xb)
46
- expect(@ramps.ya).to eq(ya)
47
- expect(@ramps.yb).to eq(yb)
48
- expect(@ramps.za).to eq(za)
49
- expect(@ramps.zb).to eq(zb)
50
-
51
- end
52
-
53
- end
54
-
@@ -1,25 +0,0 @@
1
- HOME Y,0,0,0
2
- HOME X,0,0,0
3
- MOVE ABSOLUTE, 0, 30, 0, 0
4
-
5
- MOVE ABSOLUTE, 30, 30, 0, 0
6
- DOSE WATER, 0, 0, 0, 5
7
- MOVE ABSOLUTE, 60, 30, 0, 0
8
- DOSE WATER, 0, 0, 0, 5
9
- MOVE ABSOLUTE, 90, 30, 0, 0
10
- DOSE WATER, 0, 0, 0, 5
11
- MOVE ABSOLUTE,120, 30, 0, 0
12
- DOSE WATER, 0, 0, 0, 5
13
-
14
- MOVE ABSOLUTE,120, 60, 0, 0
15
- DOSE WATER, 0, 0, 0, 5
16
- MOVE ABSOLUTE, 90, 60, 0, 0
17
- DOSE WATER, 0, 0, 0, 5
18
- MOVE ABSOLUTE, 60, 60, 0, 0
19
- DOSE WATER, 0, 0, 0, 5
20
- MOVE ABSOLUTE, 30, 60, 0, 0
21
- DOSE WATER, 0, 0, 0, 5
22
-
23
-
24
- HOME Y,0,0,0
25
- HOME X,0,0,0