ladder_drive 0.3.0

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.
Files changed (70) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +11 -0
  3. data/Gemfile +8 -0
  4. data/Gemfile.lock +41 -0
  5. data/LICENSE +21 -0
  6. data/README.md +191 -0
  7. data/README_jp.md +193 -0
  8. data/Rakefile +9 -0
  9. data/bin/console +14 -0
  10. data/bin/setup +8 -0
  11. data/exe/ladder_drive +28 -0
  12. data/ladder_drive.gemspec +33 -0
  13. data/lib/ladder_drive/asm.rb +211 -0
  14. data/lib/ladder_drive/cli.rb +55 -0
  15. data/lib/ladder_drive/config.rb +107 -0
  16. data/lib/ladder_drive/config_target.rb +93 -0
  17. data/lib/ladder_drive/console.rb +113 -0
  18. data/lib/ladder_drive/intel_hex.rb +79 -0
  19. data/lib/ladder_drive/ladder_drive.rb +36 -0
  20. data/lib/ladder_drive/plc_define.rb +35 -0
  21. data/lib/ladder_drive/plc_device.rb +171 -0
  22. data/lib/ladder_drive/protocol/emulator/emu_protocol.rb +54 -0
  23. data/lib/ladder_drive/protocol/emulator/emulator.rb +29 -0
  24. data/lib/ladder_drive/protocol/keyence/keyence.rb +31 -0
  25. data/lib/ladder_drive/protocol/keyence/kv_device.rb +51 -0
  26. data/lib/ladder_drive/protocol/keyence/kv_protocol.rb +187 -0
  27. data/lib/ladder_drive/protocol/mitsubishi/mc_protocol.rb +268 -0
  28. data/lib/ladder_drive/protocol/mitsubishi/mitsubishi.rb +30 -0
  29. data/lib/ladder_drive/protocol/mitsubishi/qdevice.rb +114 -0
  30. data/lib/ladder_drive/protocol/protocol.rb +107 -0
  31. data/lib/ladder_drive/tasks/build.rb +101 -0
  32. data/lib/ladder_drive/uploader.rb +101 -0
  33. data/lib/ladder_drive/version.rb +26 -0
  34. data/lib/ladder_drive.rb +32 -0
  35. data/lib/plc/LICENSE +21 -0
  36. data/lib/plc/emulator/emu_device.rb +121 -0
  37. data/lib/plc/emulator/emu_plc.rb +482 -0
  38. data/lib/plc/emulator/emu_plc_server.rb +71 -0
  39. data/lib/plc/emulator/emulator.rb +28 -0
  40. data/lib/plc/keyence/kv/kv-5000/DocumentWindowInfo.xml +91 -0
  41. data/lib/plc/keyence/kv/kv-5000/KvsMon.ini +0 -0
  42. data/lib/plc/keyence/kv/kv-5000/LadderDrive.mod +0 -0
  43. data/lib/plc/keyence/kv/kv-5000/LbkMdm.ini +0 -0
  44. data/lib/plc/keyence/kv/kv-5000/Main.mod +0 -0
  45. data/lib/plc/keyence/kv/kv-5000/MonEnv.kmu +1 -0
  46. data/lib/plc/keyence/kv/kv-5000/PlcSended.dky +0 -0
  47. data/lib/plc/keyence/kv/kv-5000/SensorMonitorInfo.xml +4 -0
  48. data/lib/plc/keyence/kv/kv-5000/TransInfo.tif +0 -0
  49. data/lib/plc/keyence/kv/kv-5000/UnitSet.ue2 +0 -0
  50. data/lib/plc/keyence/kv/kv-5000/UnitSet.ue2.old +0 -0
  51. data/lib/plc/keyence/kv/kv-5000/WsTreeEnv.xml +28 -0
  52. data/lib/plc/keyence/kv/kv-5000/kv-5000.cm1 +0 -0
  53. data/lib/plc/keyence/kv/kv-5000/kv-5000.cm2 +0 -0
  54. data/lib/plc/keyence/kv/kv-5000/kv-5000.ftc +0 -0
  55. data/lib/plc/keyence/kv/kv-5000/kv-5000.kpr +0 -0
  56. data/lib/plc/keyence/kv/kv-5000/kv-5000.lbl +0 -0
  57. data/lib/plc/keyence/kv/kv-5000/kv-5000.mil +0 -0
  58. data/lib/plc/keyence/kv/kv-5000/kv-5000.spl +0 -0
  59. data/lib/plc/keyence/kv/kv-5000/operand-history.txt +16 -0
  60. data/lib/plc/keyence/kv/kv-5000/sample.al2 +2 -0
  61. data/lib/plc/mitsubishi/iq-r/r08/r08.gx3 +0 -0
  62. data/lib/plc/plc.rb +27 -0
  63. data/sample/ladder_drive/sample1.esc +4 -0
  64. data/sample/ladder_drive/sample2.esc +28 -0
  65. data/sample/ladder_drive/sample2.png +0 -0
  66. data/template/escalator/config/plc.yml +27 -0
  67. data/template/ladder_drive/Rakefile +1 -0
  68. data/template/ladder_drive/asm/main.esc +70 -0
  69. data/template/ladder_drive/config/plc.yml +27 -0
  70. metadata +174 -0
@@ -0,0 +1,268 @@
1
+ # The MIT License (MIT)
2
+ #
3
+ # Copyright (c) 2016 ITO SOFT DESIGN Inc.
4
+ #
5
+ # Permission is hereby granted, free of charge, to any person obtaining
6
+ # a copy of this software and associated documentation files (the
7
+ # "Software"), to deal in the Software without restriction, including
8
+ # without limitation the rights to use, copy, modify, merge, publish,
9
+ # distribute, sublicense, and/or sell copies of the Software, and to
10
+ # permit persons to whom the Software is furnished to do so, subject to
11
+ # the following conditions:
12
+ #
13
+ # The above copyright notice and this permission notice shall be
14
+ # included in all copies or substantial portions of the Software.
15
+ #
16
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23
+
24
+ module LadderDrive
25
+ module Protocol
26
+ module Mitsubishi
27
+
28
+ class McProtocol < Protocol
29
+
30
+ def initialize options={}
31
+ super
32
+ @host = options[:host] || "192.168.0.10"
33
+ @port = options[:port] || 5010
34
+ prepare_device_map
35
+ end
36
+
37
+ def open
38
+ open!
39
+ rescue
40
+ nil
41
+ end
42
+
43
+ def open!
44
+ @socket ||= TCPSocket.open(@host, @port)
45
+ end
46
+
47
+ def close
48
+ @socket.close if @socket
49
+ @socket = nil
50
+ end
51
+
52
+ def get_bit_from_device device
53
+ device = device_by_name device
54
+ get_bits_from_device(1, device).first
55
+ end
56
+
57
+ def get_bits_from_device count, device
58
+ device = device_by_name device
59
+ packet = make_packet(body_for_get_bits_from_deivce(count, device))
60
+ @logger.debug("> #{dump_packet packet}")
61
+ open
62
+ @socket.write(packet.pack("c*"))
63
+ @socket.flush
64
+ res = receive
65
+ bits = []
66
+ count.times do |i|
67
+ v = res[11 + i / 2]
68
+ if i % 2 == 0
69
+ bits << ((v >> 4) != 0)
70
+ else
71
+ bits << ((v & 0xf) != 0)
72
+ end
73
+ end
74
+ @logger.debug("get #{device.name} => #{bits}")
75
+ bits
76
+ end
77
+
78
+ def set_bits_to_device bits, device
79
+ device = device_by_name device
80
+ packet = make_packet(body_for_set_bits_to_device(bits, device))
81
+ @logger.debug("> #{dump_packet packet}")
82
+ open
83
+ @socket.write(packet.pack("c*"))
84
+ @socket.flush
85
+ res = receive
86
+ @logger.debug("set #{bits} to:#{device.name}")
87
+ end
88
+
89
+
90
+ def get_word_from_device device
91
+ device = device_by_name device
92
+ get_words_from_device(1, device).first
93
+ end
94
+
95
+ def get_words_from_device(count, device)
96
+ device = device_by_name device
97
+ packet = make_packet(body_for_get_words_from_deivce(count, device))
98
+ @logger.debug("> #{dump_packet packet}")
99
+ open
100
+ @socket.write(packet.pack("c*"))
101
+ @socket.flush
102
+ res = receive
103
+ words = []
104
+ res[11, 2 * count].each_slice(2) do |pair|
105
+ words << pair.pack("c*").unpack("v").first
106
+ end
107
+ @logger.debug("get from: #{device.name} => #{words}")
108
+ words
109
+ end
110
+
111
+ def set_words_to_device words, device
112
+ device = device_by_name device
113
+ packet = make_packet(body_for_set_words_to_device(words, device))
114
+ @logger.debug("> #{dump_packet packet}")
115
+ open
116
+ @socket.write(packet.pack("c*"))
117
+ @socket.flush
118
+ res = receive
119
+ @logger.debug("set #{words} to: #{device.name}")
120
+ end
121
+
122
+
123
+ def device_by_name name
124
+ case name
125
+ when String
126
+ QDevice.new name
127
+ when EscDevice
128
+ local_device_of name
129
+ else
130
+ # it may be already QDevice
131
+ name
132
+ end
133
+ end
134
+
135
+
136
+ def receive
137
+ res = []
138
+ len = 0
139
+ begin
140
+ Timeout.timeout(1.0) do
141
+ loop do
142
+ c = @socket.read(1)
143
+ next if c.nil? || c == ""
144
+
145
+ res << c.bytes.first
146
+ len = res[7,2].pack("c*").unpack("v*").first if res.length >= 9
147
+ break if (len + 9 == res.length)
148
+ end
149
+ end
150
+ rescue Timeout::Error
151
+ puts "*** ERROR: TIME OUT ***"
152
+ end
153
+ @logger.debug("< #{dump_packet res}")
154
+ res
155
+ end
156
+
157
+ private
158
+
159
+ def make_packet body
160
+ header = [0x50, 0x00, 0x00, 0xff, 0xff, 0x03, 0x00, 0x00, 0x00, 0x10, 0x00]
161
+ header[7..8] = data_for_short(body.length + 2)
162
+ header + body
163
+ end
164
+
165
+ def body_for_get_bit_from_deivce device
166
+ body_for_get_bits_from_deivce 1, device
167
+ end
168
+
169
+ def body_for_get_bits_from_deivce count, device
170
+ body_for_get_words_from_deivce count, device, false
171
+ end
172
+
173
+ def body_for_get_words_from_deivce count, device, word = true
174
+ body = [0x01, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x90, 0x01, 0x00]
175
+ body[2] = 1 unless word
176
+ body[4..7] = data_for_device(device)
177
+ body[8..9] = data_for_short count
178
+ body
179
+ end
180
+
181
+
182
+ def body_for_set_bits_to_device bits, device
183
+ body = [0x01, 0x14, 0x01, 0x00, 0x00, 0x00, 0x00, 0x90, 0x01, 0x00]
184
+ d = device
185
+ bits = [bits] unless bits.is_a? Array
186
+ bits.each_slice(2) do |pair|
187
+ body << (pair.first ? 0x10 : 0x00)
188
+ body[-1] |= (pair.last ? 0x1 : 0x00) if pair.size == 2
189
+ d = d.next_device
190
+ end
191
+ body[4..7] = data_for_device(device)
192
+ body[8..9] = data_for_short bits.size
193
+ body
194
+ end
195
+ alias :body_for_set_bit_to_device :body_for_set_bits_to_device
196
+
197
+ def body_for_set_words_to_device words, device
198
+ body = [0x01, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x90, 0x01, 0x00]
199
+ d = device
200
+ words = [words] unless words.is_a? Array
201
+ words.each do |v|
202
+ body += data_for_short v
203
+ d = d.next_device
204
+ end
205
+ body[4..7] = data_for_device(device)
206
+ body[8..9] = data_for_short words.size
207
+ body
208
+ end
209
+
210
+ def data_for_device device
211
+ a = data_for_int device.number
212
+ a[3] = device.suffix_code
213
+ a
214
+ end
215
+
216
+ def data_for_short value
217
+ [value].pack("v").unpack("c*")
218
+ end
219
+
220
+ def data_for_int value
221
+ [value].pack("V").unpack("c*")
222
+ end
223
+
224
+ def dump_packet packet
225
+ a = []
226
+ len = packet.length
227
+ bytes = packet.dup
228
+ len.times do |i|
229
+ a << ("0" + bytes[i].to_s(16))[-2, 2]
230
+ end
231
+ "[" + a.join(", ") + "]"
232
+ end
233
+
234
+ def prepare_device_map
235
+ @conv_dev_dict ||= begin
236
+ h = {}
237
+ [
238
+ ["X", "X0", 1024],
239
+ ["Y", "Y0", 1024],
240
+ ["M", "M0", 1024],
241
+ ["C", "C0", 256],
242
+ ["T", "T0", 256],
243
+ ["L", "L0", 1024],
244
+ ["SC", "M1024", 1024],
245
+ ["D", "D0", 1024],
246
+ ["H", "D1024", 1024],
247
+ ["SD", "D2048", 1024],
248
+ ["PRG", "D3072", 1024] # ..D4095
249
+ ].each do |s,d,c|
250
+ h[s] = [QDevice.new(d), c]
251
+ end
252
+ h
253
+ end
254
+ end
255
+
256
+ def local_device_of device
257
+ return device if device.is_a? QDevice
258
+ d, c = @conv_dev_dict[device.suffix]
259
+ return nil unless device.number < c
260
+ ld = QDevice.new(d.suffix, d.number + device.number)
261
+ device_by_name ld.name
262
+ end
263
+
264
+ end
265
+
266
+ end
267
+ end
268
+ end
@@ -0,0 +1,30 @@
1
+ # The MIT License (MIT)
2
+ #
3
+ # Copyright (c) 2016 ITO SOFT DESIGN Inc.
4
+ #
5
+ # Permission is hereby granted, free of charge, to any person obtaining
6
+ # a copy of this software and associated documentation files (the
7
+ # "Software"), to deal in the Software without restriction, including
8
+ # without limitation the rights to use, copy, modify, merge, publish,
9
+ # distribute, sublicense, and/or sell copies of the Software, and to
10
+ # permit persons to whom the Software is furnished to do so, subject to
11
+ # the following conditions:
12
+ #
13
+ # The above copyright notice and this permission notice shall be
14
+ # included in all copies or substantial portions of the Software.
15
+ #
16
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23
+
24
+ $:.unshift File.dirname(__FILE__)
25
+
26
+ require 'socket'
27
+ require 'logger'
28
+ require 'timeout'
29
+ require 'qdevice'
30
+ require 'mc_protocol'
@@ -0,0 +1,114 @@
1
+ # The MIT License (MIT)
2
+ #
3
+ # Copyright (c) 2016 ITO SOFT DESIGN Inc.
4
+ #
5
+ # Permission is hereby granted, free of charge, to any person obtaining
6
+ # a copy of this software and associated documentation files (the
7
+ # "Software"), to deal in the Software without restriction, including
8
+ # without limitation the rights to use, copy, modify, merge, publish,
9
+ # distribute, sublicense, and/or sell copies of the Software, and to
10
+ # permit persons to whom the Software is furnished to do so, subject to
11
+ # the following conditions:
12
+ #
13
+ # The above copyright notice and this permission notice shall be
14
+ # included in all copies or substantial portions of the Software.
15
+ #
16
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23
+
24
+ module LadderDrive
25
+ module Protocol
26
+ module Mitsubishi
27
+
28
+ class QDevice
29
+
30
+ attr_reader :suffix, :number
31
+
32
+ SUFFIXES = %w(SM SD X Y M L F V B D W TS TC TN SS SC SN CS CC CN SB SW S DX DY Z R ZR)
33
+ SUFFIX_CODES = [0x91, 0xa9, 0x9c, 0x9d, 0x90, 0x92, 0x93, 0x94, 0xa0, 0xa8, 0xb4, 0xc1, 0xc0, 0xc2, 0xc7, 0xc6, 0xc8, 0xc4, 0xc3, 0xc5, 0xa1, 0xb5, 0x98, 0xa2, 0xa3, 0xcc ,0xaf, 0xb0]
34
+
35
+ def initialize a, b = nil
36
+ case a
37
+ when Array
38
+ case a.size
39
+ when 4
40
+ @suffix = suffix_for_code(a[3])
41
+ @number = ((a[2] << 8 | a[1]) << 8) | a[0]
42
+ end
43
+ when String
44
+ if b
45
+ @suffix = a.upcase
46
+ @number = b
47
+ else
48
+ if a.length == 12
49
+ @suffix = [a[0,2].to_i(16), a[2,2].to_i(16)].pack "c*"
50
+ @suffix.strip!
51
+ @number = a[4,8].to_i(16)
52
+ elsif /(X|Y)(.+)/i =~ a
53
+ @suffix = $1.upcase
54
+ @number = $2.to_i(p_adic_number)
55
+ else
56
+ /(M|L|S|B|F|T|C|D|W|R)(.+)/i =~ a
57
+ @suffix = $1.upcase
58
+ @number = $2.to_i(p_adic_number)
59
+ end
60
+ end
61
+ end
62
+ end
63
+
64
+ def p_adic_number
65
+ case @suffix
66
+ when "X", "Y", "B", "W", "SB", "SW", "DX", "DY", "ZR"
67
+ 16
68
+ else
69
+ 10
70
+ end
71
+ end
72
+
73
+ def name
74
+ @suffix + @number.to_s(p_adic_number).upcase
75
+ end
76
+
77
+ def next_device
78
+ d = self.class.new @suffix, @number + 1
79
+ d
80
+ end
81
+
82
+ def bit_device?
83
+ case @suffix
84
+ when "SM", "X", "Y", "M", "L", "F", "V", "B",
85
+ "TS", "TC", "SS", "SC","CS", "CC", "SB", "S", "DX", "DY"
86
+ true
87
+ else
88
+ false
89
+ end
90
+ end
91
+
92
+ def suffix_for_code code
93
+ index = SUFFIX_CODES.index code
94
+ index ? SUFFIXES[index] : nil
95
+ end
96
+
97
+ def suffix_code
98
+ index = SUFFIXES.index suffix
99
+ index ? SUFFIX_CODES[index] : 0
100
+ end
101
+
102
+ def + value
103
+ self.class.new self.suffix, self.number + value
104
+ end
105
+
106
+ def - value
107
+ self.class.new self.suffix, [self.number - value, 0].max
108
+ end
109
+
110
+ end
111
+
112
+ end
113
+ end
114
+ end
@@ -0,0 +1,107 @@
1
+ # The MIT License (MIT)
2
+ #
3
+ # Copyright (c) 2016 ITO SOFT DESIGN Inc.
4
+ #
5
+ # Permission is hereby granted, free of charge, to any person obtaining
6
+ # a copy of this software and associated documentation files (the
7
+ # "Software"), to deal in the Software without restriction, including
8
+ # without limitation the rights to use, copy, modify, merge, publish,
9
+ # distribute, sublicense, and/or sell copies of the Software, and to
10
+ # permit persons to whom the Software is furnished to do so, subject to
11
+ # the following conditions:
12
+ #
13
+ # The above copyright notice and this permission notice shall be
14
+ # included in all copies or substantial portions of the Software.
15
+ #
16
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23
+
24
+ dir = File.expand_path(File.dirname(__FILE__))
25
+ $:.unshift dir unless $:.include? dir
26
+
27
+ module LadderDrive
28
+ module Protocol
29
+ end
30
+ end
31
+
32
+ module LadderDrive
33
+ module Protocol
34
+
35
+ class Protocol
36
+
37
+ attr_accessor :host, :port, :log_level
38
+
39
+ def initialize options={}
40
+ @logger = Logger.new(STDOUT)
41
+ self.log_level = options[:log_level] || :info
42
+ end
43
+
44
+ def log_level= level
45
+ @log_level = level.is_a?(String) ? level.to_sym : level
46
+ case @log_level
47
+ when :debug
48
+ @logger.level = Logger::DEBUG
49
+ when :error
50
+ @logger.level = Logger::ERROR
51
+ when :fatal
52
+ @logger.level = Logger::FATAL
53
+ when :info
54
+ @logger.level = Logger::INFO
55
+ when :unknown
56
+ @logger.level = Logger::UNKNOWN
57
+ when :warn
58
+ @logger.level = Logger::WARN
59
+ end
60
+ end
61
+
62
+ # abstract methods
63
+
64
+ def open; end
65
+ def close; end
66
+
67
+ def get_bit_from_device device; end
68
+ def get_bits_from_device count, device; end
69
+ def set_bits_to_device bits, device; end
70
+ def set_bit_to_device bit, device; set_bits_to_device bit, device; end
71
+
72
+ def get_word_from_device device; end
73
+ def get_words_from_device(count, device); end
74
+ def set_words_to_device words, device; end
75
+ def set_word_to_device word, device; set_words_to_device word, device; end
76
+
77
+ def device_by_name name; nil; end
78
+
79
+ def get_from_devices device, count = 1
80
+ d = device_by_name device
81
+ if d.bit_device?
82
+ get_bits_from_device count, d
83
+ else
84
+ get_words_from_device count, d
85
+ end
86
+ end
87
+
88
+ def set_to_devices device, values
89
+ values = [values] unless values.is_a? Array
90
+ d = device_by_name device
91
+ if d.bit_device?
92
+ values = values.map{|v| case v; when 1; true; when 0; false; else; v; end}
93
+ set_bits_to_device values, d
94
+ else
95
+ set_words_to_device values, d
96
+ end
97
+ end
98
+
99
+ end
100
+
101
+ end
102
+ end
103
+
104
+ require 'keyence/keyence'
105
+ # Use load instead require, because there are two emulator files.
106
+ load File.join(dir, 'emulator/emulator.rb')
107
+ require 'mitsubishi/mitsubishi'
@@ -0,0 +1,101 @@
1
+ # The MIT License (MIT)
2
+ #
3
+ # Copyright (c) 2016 ITO SOFT DESIGN Inc.
4
+ #
5
+ # Permission is hereby granted, free of charge, to any person obtaining
6
+ # a copy of this software and associated documentation files (the
7
+ # "Software"), to deal in the Software without restriction, including
8
+ # without limitation the rights to use, copy, modify, merge, publish,
9
+ # distribute, sublicense, and/or sell copies of the Software, and to
10
+ # permit persons to whom the Software is furnished to do so, subject to
11
+ # the following conditions:
12
+ #
13
+ # The above copyright notice and this permission notice shall be
14
+ # included in all copies or substantial portions of the Software.
15
+ #
16
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23
+
24
+ dir = File.expand_path(File.join(File.dirname(__FILE__), "../../../lib"))
25
+ $:.unshift dir unless $:.include? dir
26
+
27
+ require 'rake/loaders/makefile'
28
+ require 'fileutils'
29
+ require "ladder_drive"
30
+
31
+ directory "build"
32
+
33
+ desc "Assemble codes"
34
+ rule %r{^build/.+\.lst} => ['%{^build,asm}X.esc'] do |t|
35
+ Rake::Task["build"].invoke
36
+ begin
37
+ $stderr = File.open('hb.log', 'w')
38
+ $stdout = $stderr
39
+ ensure
40
+ $stdout = STDOUT
41
+ $stderr = STDERR
42
+ end
43
+ #dir = "./asm"
44
+ stream = StringIO.new
45
+ #filename = "asm/#{t.source}"
46
+ puts "asm #{t.source}"
47
+ asm = LadderDrive::Asm.new File.read(t.source)
48
+ #dst = File.join("build", t.name)
49
+ File.write(t.name, asm.dump_line)
50
+ end
51
+
52
+ desc "Make hex codes"
53
+ rule %r{^build/.+\.hex} => ['%{^build,asm}X.esc'] do |t|
54
+ Rake::Task["build"].invoke
55
+ begin
56
+ $stderr = File.open('hb.log', 'w')
57
+ $stdout = $stderr
58
+ ensure
59
+ $stdout = STDOUT
60
+ $stderr = STDERR
61
+ end
62
+ stream = StringIO.new
63
+ puts "hex #{t.source}"
64
+ asm = LadderDrive::Asm.new File.read(t.source)
65
+ hex = LadderDrive::IntelHex.new asm.codes
66
+ File.write(t.name, hex.dump)
67
+ end
68
+
69
+ desc "Clean all generated files."
70
+ task :clean do
71
+ FileUtils.rm_r "build"
72
+ end
73
+
74
+ @config = LadderDrive::LadderDriveConfig.default
75
+
76
+ desc "Install program to PLCs."
77
+ task :upload => @config.output do
78
+ t = @config.target ENV['target']
79
+ t.run
80
+ u = t.uploader
81
+ u.source = @config.output
82
+ puts "uploading #{u.source} ..."
83
+ u.upload
84
+ puts "done uploading"
85
+ end
86
+
87
+ desc "Launch emulator."
88
+ task :emulator do
89
+ t = @config.target :emulator
90
+ t.run
91
+ puts "launch emulator"
92
+ LadderDrive::Console.instance.run
93
+ end
94
+
95
+ task :console => :upload do
96
+ c = LadderDrive::Console.instance
97
+ c.target = @config.target ENV['target']
98
+ c.run
99
+ end
100
+
101
+ task :default => :console