farmbot-serial 0.0.6 → 0.0.7

Sign up to get free protection for your applications and to get access to all the features.
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