class LadderDrive::Protocol::Mitsubishi::FxProtocol
Constants
- ACK
- CR
- DELIMITER
- ENQ
- EOT
- ETX
- LF
- NAK
- STX
Attributes
baudrate[RW]
pc_no[RW]
station_no[RW]
wait_time[RW]
Public Class Methods
new(options={})
click to toggle source
Calls superclass method
# File lib/ladder_drive/protocol/mitsubishi/fx_protocol.rb, line 46 def initialize options={} super @port = options[:port] || `ls /dev/tty.usb*`.split("\n").map{|l| l.chomp}.first @pc_no = 0xff @baudrate = 19200 @station_no = 0 @wait_time = 0 @comm = nil #prepare_device_map end
Public Instance Methods
available_bits_range(device=nil)
click to toggle source
# File lib/ladder_drive/protocol/mitsubishi/fx_protocol.rb, line 201 def available_bits_range device=nil 1..256 end
available_words_range(device=nil)
click to toggle source
# File lib/ladder_drive/protocol/mitsubishi/fx_protocol.rb, line 205 def available_words_range device=nil 1..64 end
body_for_get_bit_from_deivce(device)
click to toggle source
# File lib/ladder_drive/protocol/mitsubishi/fx_protocol.rb, line 209 def body_for_get_bit_from_deivce device body_for_get_bits_from_device 1, device end
body_for_get_bits_from_device(count, device)
click to toggle source
# File lib/ladder_drive/protocol/mitsubishi/fx_protocol.rb, line 213 def body_for_get_bits_from_device count, device body = header_with_command "BR" body += "#{device.name}#{count.to_s(16).rjust(2, '0')}" body += check_sum(body) body += DELIMITER body.upcase end
body_for_get_words_from_device(count, device)
click to toggle source
# File lib/ladder_drive/protocol/mitsubishi/fx_protocol.rb, line 221 def body_for_get_words_from_device count, device body = header_with_command "WR" body += "#{device.name}#{count.to_s(16).rjust(2, '0')}" body += check_sum(body) body += DELIMITER body.upcase end
body_for_set_bits_to_device(bits, device)
click to toggle source
# File lib/ladder_drive/protocol/mitsubishi/fx_protocol.rb, line 229 def body_for_set_bits_to_device bits, device body = header_with_command "BW" body += "#{device.name}#{bits.count.to_s(16).rjust(2, '0')}" body += bits.map{|b| b ? "1" : "0"}.join("") body += check_sum(body) body += DELIMITER body.upcase end
Also aliased as: body_for_set_bit_to_device
body_for_set_words_to_device(words, device)
click to toggle source
# File lib/ladder_drive/protocol/mitsubishi/fx_protocol.rb, line 239 def body_for_set_words_to_device words, device body = header_with_command "WW" body += "#{device.name}#{words.count.to_s(16).rjust(2, '0')}" body += words.map{|w| w.to_s(16).rjust(4, "0")}.join("") body += check_sum(body) body += DELIMITER body.upcase end
close()
click to toggle source
# File lib/ladder_drive/protocol/mitsubishi/fx_protocol.rb, line 76 def close @comm.close if @comm @comm = nil end
device_by_name(name)
click to toggle source
# File lib/ladder_drive/protocol/mitsubishi/fx_protocol.rb, line 173 def device_by_name name case name when String d = FxDevice.new name d.valid? ? d : nil when EscDevice local_device_of name else # it may be already QDevice name end end
dump_packet(packet)
click to toggle source
def data_for_device device
a = data_for_int device.number a[3] = device.suffix_code a
end
def data_for_short value
[value].pack("v").unpack("C*")
end
def data_for_int value
[value].pack("V").unpack("C*")
end
# File lib/ladder_drive/protocol/mitsubishi/fx_protocol.rb, line 265 def dump_packet packet packet.inspect end
get_bits_from_device(count, device)
click to toggle source
# File lib/ladder_drive/protocol/mitsubishi/fx_protocol.rb, line 81 def get_bits_from_device count, device raise ArgumentError.new("A count #{count} must be between #{available_bits_range.first} and #{available_bits_range.last} for #{__method__}") unless available_bits_range.include? count device = device_by_name device packet = body_for_get_bits_from_device(count, device) + DELIMITER @logger.debug("> #{dump_packet packet}") open @comm.write(packet) @comm.flush res = receive bits = [] if res if check_sum(res[0..-5]) == res[-4,2] bits = res[5..-6].each_char.map do |c| c == "1" ? true : false end else end end @logger.debug("> #{dump_packet ack_packet}") @comm.write(ack_packet) @logger.debug("get #{device.name} => #{bits}") bits end
get_words_from_device(count, device)
click to toggle source
# File lib/ladder_drive/protocol/mitsubishi/fx_protocol.rb, line 127 def get_words_from_device(count, device) raise ArgumentError.new("A count #{count} must be between #{available_words_range.first} and #{available_words_range.last} for #{__method__}") unless available_words_range.include? count device = device_by_name device packet = body_for_get_words_from_device(count, device) + DELIMITER @logger.debug("> #{dump_packet packet}") open @comm.write(packet) @comm.flush res = receive words = [] if res if check_sum(res[0..-5]) == res[-4,2] words = res[5..-6].scan(/.{4}/).map do |v| v.to_i(16) end else end end @logger.debug("> #{dump_packet ack_packet}") @comm.write(ack_packet) @logger.debug("get #{device.name} => #{words}") words end
open()
click to toggle source
# File lib/ladder_drive/protocol/mitsubishi/fx_protocol.rb, line 57 def open open! rescue nil end
open!()
click to toggle source
# File lib/ladder_drive/protocol/mitsubishi/fx_protocol.rb, line 63 def open! return false unless @port begin # port, baudrate, bits, stop bits, parity(0:none, 1:even, 2:odd) @comm ||= SerialPort.new(@port, @baudrate, 7, 1, 2).tap do |s| s.read_timeout = (TIMEOUT * 1000.0).to_i end rescue => e p e nil end end
receive()
click to toggle source
# File lib/ladder_drive/protocol/mitsubishi/fx_protocol.rb, line 187 def receive res = "" begin Timeout.timeout(TIMEOUT) do res = @comm.gets end res rescue Timeout::Error puts "*** ERROR: TIME OUT : #{res} ***" end @logger.debug("< #{dump_packet res}") res end
set_bits_to_device(bits, device)
click to toggle source
# File lib/ladder_drive/protocol/mitsubishi/fx_protocol.rb, line 109 def set_bits_to_device bits, device raise ArgumentError.new("A count #{count} must be between #{available_bits_range.first} and #{available_bits_range.last} for #{__method__}") unless available_bits_range.include? bits.size device = device_by_name device packet = body_for_set_bits_to_device(bits, device) @logger.debug("> #{dump_packet packet}") open @comm.write(packet) @comm.flush res = receive @logger.debug("set #{bits} to:#{device.name}") # error checking unless res == ack_packet raise "ERROR: return #{res} for set_bits_to_device(#{bits}, #{device.name})" end end
set_words_to_device(words, device)
click to toggle source
# File lib/ladder_drive/protocol/mitsubishi/fx_protocol.rb, line 155 def set_words_to_device words, device raise ArgumentError.new("A count of words #{words.size} must be between #{available_words_range.first} and #{available_words_range.last} for #{__method__}") unless available_bits_range.include? words.size device = device_by_name device packet = body_for_set_words_to_device(words, device) @logger.debug("> #{dump_packet packet}") open @comm.write(packet) @comm.flush res = receive @logger.debug("set #{words} to: #{device.name}") # error checking unless res == ack_packet raise "ERROR: return #{res} for set_bits_to_device(#{words}, #{device.name})" end end
Private Instance Methods
ack_packet()
click to toggle source
# File lib/ladder_drive/protocol/mitsubishi/fx_protocol.rb, line 313 def ack_packet "#{ACK}#{station_no.to_s.rjust(2,'0')}#{pc_no.to_s(16).rjust(2, '0')}#{DELIMITER}".upcase end
check_sum(packet)
click to toggle source
def local_device_of device
return device if device.is_a? QDevice d, c = @conv_dev_dict[device.suffix] return nil unless device.number < c ld = QDevice.new(d.suffix, d.number + device.number) device_by_name ld.name
end
# File lib/ladder_drive/protocol/mitsubishi/fx_protocol.rb, line 305 def check_sum packet packet[1..-1].upcase.unpack("C*").inject(0){|s,c| s + c}.to_s(16).rjust(2, "0")[-2, 2].upcase end
header_with_command(command)
click to toggle source
# File lib/ladder_drive/protocol/mitsubishi/fx_protocol.rb, line 309 def header_with_command command "#{ENQ}#{station_no.to_s.rjust(2,'0')}#{pc_no.to_s(16).rjust(2, '0')}#{command}#{wait_time.to_s}".upcase end