libmodbus4r 0.2.2 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
data/NEWS CHANGED
@@ -1,9 +1,18 @@
1
- libmodbus 0.2.2 (2009-08-16)
1
+ libmodbus4r 0.3.0 (2009-09-21)
2
+ ===========================
3
+ - Added support slave for TCP and RTU protocol
4
+ - Migrated on libmodbus 0.2.2
5
+ - Added source of libmodbus in project
6
+ - Compatibility with ruby-1.8.7
7
+
8
+ libmodbus4r 0.2.2 (2009-08-16)
9
+ ===========================
2
10
  - Fixed bug in Master::read_input_registers
3
11
 
4
- libmodbus 0.2.1 (2009-08-10)
12
+ libmodbus4r 0.2.1 (2009-08-10)
13
+ ===========================
5
14
  - Fixed bug in Master::read_input_coils
6
15
 
7
- libmodbus 0.2.0 (2009-07-30)
16
+ libmodbus4r 0.2.0 (2009-07-30)
8
17
  ===========================
9
18
  - First public release
data/README CHANGED
@@ -1,41 +1,46 @@
1
- == About
1
+ == About project
2
2
 
3
- Binding use *libmodbus* (free implementation of modbus for Linux\MacOS) for Ruby.
3
+ libmodbus4r –a wrapper for library libmodbus wrote in Ruby. libmodbus – a free implementation of protocol ModBus TCP\RTU for Linux and OSX operation systems. It's very fast and stable library wrote in C. Goal of project is ability writing application in Ruby that use ModBus protocol for communication with devices.
4
4
 
5
5
  == Features
6
6
 
7
- * Use only Ruby-1.9.x
8
- * Use C library *libmodbus*;
7
+ * Use only Ruby-1.9.x and Ruby-1.8.7
8
+ * Include C library *libmodbus*;
9
9
  * ModBus TCP and RTU master(client);
10
+ * ModBus TCP and RTU slave(server);
10
11
  * Support functions:
11
- * * read coil status (0x01)
12
- * * read input status (0x02)
13
- * * read holding registers (0x03)
14
- * * read input registers (0x04)
15
- * * force single coil (0x05)
16
- * * preset single register (0x06)
17
- * * force multiple coils (0x0F)
18
- * * preset multiple registers (0x10)
19
-
20
- == Install
21
-
22
- 1. Install last release ruby 1.9.1 from http://ruby-lang.org
23
- 2. Install libmodbus-2.0.3 from https://launchpad.net/libmodbus
24
- 3. Install libmodbus4r
25
- *$ sudo rake install*
26
- or
27
- *$ gem install libmodbus4r
28
-
29
- == Authorss
12
+ * read coil status (0x01)
13
+ * read input status (0x02)
14
+ * read holding registers (0x03)
15
+ * read input registers (0x04)
16
+ * force single coil (0x05)
17
+ * preset single register (0x06)
18
+ * force multiple coils (0x0F)
19
+ * preset multiple registers (0x10)
20
+
21
+ == Installation
22
+
23
+ Importan! libmodbus4 work only in Linux и OSX
24
+
25
+ Simplest installation is use rubygems
26
+ $ sudo gem install libmodbus4r
27
+ or installation from source with command:
28
+ $ sudo rake install
29
+
30
+ == Authors
30
31
 
31
32
  Aleksey Timin <atimin@gmail.com>
32
33
 
33
- == Refernces
34
+ == References
34
35
 
35
36
  Home page projects : http://flipback.github.com/libmodbus4r/
37
+
36
38
  Hosting on RubyForge : http://rubyforge.org/projects/libmodbus4r
39
+
37
40
  Hosting on GitHub : http://github.com/flipback/libmodbus4r/tree/master
38
41
 
39
42
  Ruby site : http://ruby-lang.org
43
+
40
44
  libmobus on Launchpad : https://launchpad.net/libmodbus
45
+
41
46
  ModBus community: http://www.modbus-ida.org
@@ -9,42 +9,35 @@ mstr = ModBus::RTUMaster.new('/dev/ttyS0', # device
9
9
  9600, # baud: 9600, 19200, etc
10
10
  "none", # parity: "even", "odd", "none"
11
11
  8, # data bits: 5, 6, 7, 8
12
- 1) # stop bits: 1, 2
12
+ 1, # stop bits: 1, 2
13
+ 1) # slave id
13
14
  mstr.connect
14
15
  # Reads the coils status in the slave
15
- puts mstr.read_coil_status(1, #slave id
16
- 0, #start address
16
+ puts mstr.read_coil_status(0, #start address
17
17
  10) #number
18
18
  # Reads the input status in the slave
19
- puts mstr.read_input_status(1, #slave id
20
- 0, #start address
19
+ puts mstr.read_input_status(0, #start address
21
20
  10) #number
22
21
  # Reads the holding registers in the slave
23
- puts mstr.read_holding_registers(1, #slave id
24
- 0, #start address
22
+ puts mstr.read_holding_registers(0, #start address
25
23
  5) #number
26
24
  # Reads the input registers in the slave
27
- puts mstr.read_input_registers(1, #slave id
28
- 0, #start address
25
+ puts mstr.read_input_registers(0, #start address
29
26
  5) #number
30
27
  # Turns a single coil in the slave
31
- mstr.force_single_coil(1, #slave id
32
- 0, #coil address
28
+ mstr.force_single_coil(0, #coil address
33
29
  true) #state
34
30
 
35
31
  # Sets a value in one holding register in the slave
36
- mstr.preset_single_register(1, #slave id
37
- 0, #reg address
32
+ mstr.preset_single_register(0, #reg address
38
33
  0xa0a0) #value
39
34
 
40
35
  # Sets\reset the coils in the slave
41
- mstr.force_multiple_coils(1, #slave id
42
- 0, #start address
36
+ mstr.force_multiple_coils(0, #start address
43
37
  [true, false, true]) #data
44
38
 
45
39
  #Copies the values in th slave
46
- mstr.preset_multiple_registers(1, #slave id
47
- 0, #start address
40
+ mstr.preset_multiple_registers(0, #start address
48
41
  [1, 0xdf, 2]) #data
49
42
 
50
43
  mstr.close
@@ -0,0 +1,24 @@
1
+ begin
2
+ require 'rubygems'
3
+ rescue
4
+ end
5
+
6
+ require 'modbus4r'
7
+
8
+ sl = ModBus::RTUSlave.new('/dev/ttyS0', # device
9
+ 9600, # baud: 9600, 19200, etc
10
+ "none", # parity: "even", "odd", "none"
11
+ 8, # data bits: 5, 6, 7, 8
12
+ 1, # stop bits: 1, 2
13
+ 1) # slave id
14
+
15
+ sl.coil_status = [false, false, false, false, false]
16
+ sl.input_status = [false, false, false, false, false]
17
+ sl.holding_registers = [0, 0, 0, 0, 0, 0, 0, 0]
18
+ sl.input_registers = [0, 0, 0, 0, 0, 0, 0, 0]
19
+
20
+ sl.start
21
+
22
+ sl.join
23
+
24
+ sl.stop
@@ -5,42 +5,36 @@ end
5
5
 
6
6
  require 'modbus4r'
7
7
 
8
- mstr = ModBus::TCPMaster.new('127.0.0.1', 1502)
8
+ mstr = ModBus::TCPMaster.new('127.0.0.1', #ip -address
9
+ 1502, #port
10
+ 1) #slave id
9
11
  mstr.connect
10
12
  # Reads the coils status in the slave
11
- puts mstr.read_coil_status(1, #slave id
12
- 0, #start address
13
+ puts mstr.read_coil_status(0, #start address
13
14
  10) #number
14
15
  # Reads the input status in the slave
15
- puts mstr.read_input_status(1, #slave id
16
- 0, #start address
16
+ puts mstr.read_input_status(0, #start address
17
17
  10) #number
18
18
  # Reads the holding registers in the slave
19
- puts mstr.read_holding_registers(1, #slave id
20
- 0, #start address
19
+ puts mstr.read_holding_registers(0, #start address
21
20
  5) #number
22
21
  # Reads the input registers in the slave
23
- puts mstr.read_input_registers(1, #slave id
24
- 0, #start address
22
+ puts mstr.read_input_registers(0, #start address
25
23
  5) #number
26
24
  # Turns a single coil in the slave
27
- mstr.force_single_coil(1, #slave id
28
- 0, #coil address
25
+ mstr.force_single_coil(0, #coil address
29
26
  true) #state
30
27
 
31
28
  # Sets a value in one holding register in the slave
32
- mstr.preset_single_register(1, #slave id
33
- 0, #reg address
29
+ mstr.preset_single_register(0, #reg address
34
30
  0xa0a0) #value
35
31
 
36
32
  # Sets\reset the coils in the slave
37
- mstr.force_multiple_coils(1, #slave id
38
- 0, #start address
33
+ mstr.force_multiple_coils(0, #start address
39
34
  [true, false, true]) #data
40
35
 
41
36
  #Copies the values in th slave
42
- mstr.preset_multiple_registers(1, #slave id
43
- 0, #start address
37
+ mstr.preset_multiple_registers(0, #start address
44
38
  [1, 0xdf, 2]) #data
45
39
 
46
40
  mstr.close
@@ -0,0 +1,21 @@
1
+ begin
2
+ require 'rubygems'
3
+ rescue
4
+ end
5
+
6
+ require 'modbus4r'
7
+
8
+ sl = ModBus::TCPSlave.new('127.0.0.1', #ip-address
9
+ 1502, #port
10
+ 1) #slave id
11
+
12
+ sl.coil_status = [false, false, false, false, false]
13
+ sl.input_status = [false, false, false, false, false]
14
+ sl.holding_registers = [0, 0, 0, 0, 0, 0, 0, 0]
15
+ sl.input_registers = [0, 0, 0, 0, 0, 0, 0, 0]
16
+
17
+ sl.start
18
+
19
+ sl.join
20
+
21
+ sl.stop
data/ext/errors.c CHANGED
@@ -52,17 +52,8 @@ void mb_raise_error(int exception)
52
52
  case GATEWAY_PROBLEM_TARGET:
53
53
  rb_raise(eGatewayProblemTarget, "Gateway problem target (%i)", GATEWAY_PROBLEM_TARGET);
54
54
  break;
55
- case COMM_TIME_OUT:
56
- rb_raise(eModBusError, "Communication timeout (%i)", COMM_TIME_OUT);
57
- break;
58
- case PORT_SOCKET_FAILURE:
59
- rb_raise(eModBusError, "Port socket failure (%i)", PORT_SOCKET_FAILURE);
60
- break;
61
- case SELECT_FAILURE:
62
- rb_raise(eModBusError, "Select failure (%i)", SELECT_FAILURE);
63
- break;
64
- case TOO_MANY_DATA:
65
- rb_raise(eModBusError, "Too many data (%i)", TOO_MANY_DATA);
55
+ case INVALID_DATA:
56
+ rb_raise(eModBusError, "Invalid data (%i)", INVALID_DATA);
66
57
  break;
67
58
  case INVALID_CRC:
68
59
  rb_raise(eModBusError, "Invalid CRC (%i)", INVALID_CRC);
@@ -70,6 +61,15 @@ void mb_raise_error(int exception)
70
61
  case INVALID_EXCEPTION_CODE:
71
62
  rb_raise(eModBusError, "Invalid exception code (%i)", INVALID_EXCEPTION_CODE);
72
63
  break;
64
+ case SELECT_TIMEOUT:
65
+ rb_raise(eModBusError, "Select timeout (%i)", SELECT_TIMEOUT);
66
+ break;
67
+ case SELECT_FAILURE:
68
+ rb_raise(eModBusError, "Select failure (%i)", SELECT_FAILURE);
69
+ break;
70
+ case SOCKET_FAILURE:
71
+ rb_raise(eModBusError, "Socket failure (%i)", SOCKET_FAILURE);
72
+ break;
73
73
  case CONNECTION_CLOSED:
74
74
  rb_raise(eModBusError, "Connection closed (%i)", CONNECTION_CLOSED);
75
75
  break;
data/ext/extconf.rb CHANGED
@@ -1,4 +1,9 @@
1
1
  require 'mkmf'
2
2
 
3
- have_library 'modbus'
3
+ printf "checking for ruby version... "
4
+ STDOUT.flush
5
+ ruby_ver = RUBY_VERSION
6
+ puts ruby_ver
7
+ $CFLAGS += " -DRUBY_1_8" if ruby_ver.to_f == 1.8
8
+
4
9
  create_makefile '_modbus4r'
data/ext/master.c CHANGED
@@ -11,9 +11,17 @@ but WITHOUT ANY WARRANTY; without even the implied warranty of
11
11
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12
12
  GNU General Public License for more details. */
13
13
 
14
+ #include <unistd.h>
14
15
  #include "modbus4r.h"
15
16
  #include "errors.h"
16
17
 
18
+ void mb_mstr_free(modbus_param_t *mb_param )
19
+ {
20
+ modbus_close(mb_param);
21
+ free(mb_param);
22
+ }
23
+
24
+
17
25
  VALUE mb_mstr_is_closed(VALUE self)
18
26
  {
19
27
  modbus_param_t *mb_param;
@@ -46,19 +54,17 @@ VALUE mb_mstr_close(VALUE self)
46
54
  return self;
47
55
  }
48
56
 
49
- VALUE mb_mstr_read_coil(VALUE self, VALUE slave,
50
- VALUE start_addr, VALUE nb,
51
- int (*func)(modbus_param_t*, int, int, int, uint8_t*))
57
+ VALUE mb_mstr_read_coil(VALUE self, VALUE start_addr, VALUE nb,
58
+ int (*func)(modbus_param_t*, int, int, uint8_t*))
52
59
  {
53
60
  modbus_param_t *mb_param;
54
61
  Data_Get_Struct(self, modbus_param_t, mb_param);
55
62
 
56
- slave = rb_funcall(slave, rb_intern("to_i"), 0);
57
63
  start_addr = rb_funcall(start_addr, rb_intern("to_i"), 0);
58
64
  nb = rb_funcall(nb, rb_intern("to_i"), 0);
59
65
 
60
66
  uint8_t dest[FIX2INT(nb)];
61
- int status = (*func)(mb_param, FIX2INT(slave), FIX2INT(start_addr), FIX2INT(nb), dest);
67
+ int status = (*func)(mb_param, FIX2INT(start_addr), FIX2INT(nb), dest);
62
68
 
63
69
  if (status < 0) {
64
70
  mb_raise_error(status);
@@ -73,33 +79,27 @@ VALUE mb_mstr_read_coil(VALUE self, VALUE slave,
73
79
  return ret;
74
80
  }
75
81
 
76
- VALUE mb_mstr_read_coil_status(VALUE self, VALUE slave,
77
- VALUE start_addr, VALUE nb)
82
+ VALUE mb_mstr_read_coil_status(VALUE self, VALUE start_addr, VALUE nb)
78
83
  {
79
- return mb_mstr_read_coil(self, slave, start_addr, nb,
80
- read_coil_status);
84
+ return mb_mstr_read_coil(self, start_addr, nb, read_coil_status);
81
85
  }
82
86
 
83
- VALUE mb_mstr_read_input_status(VALUE self, VALUE slave,
84
- VALUE start_addr, VALUE nb)
87
+ VALUE mb_mstr_read_input_status(VALUE self, VALUE start_addr, VALUE nb)
85
88
  {
86
- return mb_mstr_read_coil(self, slave, start_addr, nb,
87
- read_input_status);
89
+ return mb_mstr_read_coil(self, start_addr, nb, read_input_status);
88
90
  }
89
91
 
90
- VALUE mb_mstr_read_registers(VALUE self, VALUE slave,
91
- VALUE start_addr, VALUE nb,
92
- int (*func)(modbus_param_t*, int, int, int, uint16_t*))
92
+ VALUE mb_mstr_read_registers(VALUE self, VALUE start_addr, VALUE nb,
93
+ int (*func)(modbus_param_t*, int, int, uint16_t*))
93
94
  {
94
95
  modbus_param_t *mb_param;
95
96
  Data_Get_Struct(self, modbus_param_t, mb_param);
96
97
 
97
- slave = rb_funcall(slave, rb_intern("to_i"), 0);
98
98
  start_addr = rb_funcall(start_addr, rb_intern("to_i"), 0);
99
99
  nb = rb_funcall(nb, rb_intern("to_i"), 0);
100
100
 
101
101
  uint16_t dest[FIX2INT(nb)];
102
- int status = (*func)(mb_param, FIX2INT(slave), FIX2INT(start_addr), FIX2INT(nb), dest);
102
+ int status = (*func)(mb_param, FIX2INT(start_addr), FIX2INT(nb), dest);
103
103
 
104
104
  if (status < 0) {
105
105
  mb_raise_error(status);
@@ -115,30 +115,26 @@ VALUE mb_mstr_read_registers(VALUE self, VALUE slave,
115
115
  return ret;
116
116
  }
117
117
 
118
- VALUE mb_mstr_read_holding_registers(VALUE self, VALUE slave,
119
- VALUE start_addr, VALUE nb)
118
+ VALUE mb_mstr_read_holding_registers(VALUE self, VALUE start_addr, VALUE nb)
120
119
  {
121
- return mb_mstr_read_registers(self, slave, start_addr, nb,
120
+ return mb_mstr_read_registers(self, start_addr, nb,
122
121
  read_holding_registers);
123
122
  }
124
123
 
125
- VALUE mb_mstr_read_input_registers(VALUE self, VALUE slave,
126
- VALUE start_addr, VALUE nb)
124
+ VALUE mb_mstr_read_input_registers(VALUE self, VALUE start_addr, VALUE nb)
127
125
  {
128
- return mb_mstr_read_registers(self, slave, start_addr, nb,
126
+ return mb_mstr_read_registers(self, start_addr, nb,
129
127
  read_input_registers);
130
128
  }
131
129
 
132
- VALUE mb_mstr_force_single_coil(VALUE self, VALUE slave,
133
- VALUE coil_addr, VALUE state)
130
+ VALUE mb_mstr_force_single_coil(VALUE self, VALUE coil_addr, VALUE state)
134
131
  {
135
132
  modbus_param_t *mb_param;
136
133
  Data_Get_Struct(self, modbus_param_t, mb_param);
137
134
 
138
- slave = rb_funcall(slave, rb_intern("to_i"), 0);
139
135
  coil_addr = rb_funcall(coil_addr, rb_intern("to_i"), 0);
140
136
 
141
- int status = force_single_coil(mb_param, FIX2INT(slave), FIX2INT(coil_addr), (state == Qfalse ? 0 : 1));
137
+ int status = force_single_coil(mb_param, FIX2INT(coil_addr), (state == Qfalse ? 0 : 1));
142
138
 
143
139
  if (status < 0) {
144
140
  mb_raise_error(status);
@@ -148,17 +144,15 @@ VALUE mb_mstr_force_single_coil(VALUE self, VALUE slave,
148
144
  }
149
145
 
150
146
 
151
- VALUE mb_mstr_preset_single_register(VALUE self, VALUE slave,
152
- VALUE reg_addr, VALUE value)
147
+ VALUE mb_mstr_preset_single_register(VALUE self, VALUE reg_addr, VALUE value)
153
148
  {
154
149
  modbus_param_t *mb_param;
155
150
  Data_Get_Struct(self, modbus_param_t, mb_param);
156
151
 
157
- slave = rb_funcall(slave, rb_intern("to_i"), 0);
158
152
  reg_addr = rb_funcall(reg_addr, rb_intern("to_i"), 0);
159
153
  value = rb_funcall(value, rb_intern("to_i"), 0);
160
154
 
161
- int status = preset_single_register(mb_param, FIX2INT(slave), FIX2INT(reg_addr), FIX2INT(value));
155
+ int status = preset_single_register(mb_param, FIX2INT(reg_addr), FIX2INT(value));
162
156
 
163
157
  if (status < 0) {
164
158
  mb_raise_error(status);
@@ -167,13 +161,11 @@ VALUE mb_mstr_preset_single_register(VALUE self, VALUE slave,
167
161
  return self;
168
162
  }
169
163
 
170
- VALUE mb_mstr_force_multiple_coils(VALUE self, VALUE slave,
171
- VALUE start_addr, VALUE data)
164
+ VALUE mb_mstr_force_multiple_coils(VALUE self, VALUE start_addr, VALUE data)
172
165
  {
173
166
  modbus_param_t *mb_param;
174
167
  Data_Get_Struct(self, modbus_param_t, mb_param);
175
168
 
176
- slave = rb_funcall(slave, rb_intern("to_i"), 0);
177
169
  start_addr = rb_funcall(start_addr, rb_intern("to_i"), 0);
178
170
  data = rb_funcall(data, rb_intern("to_a"), 0);
179
171
 
@@ -186,7 +178,7 @@ VALUE mb_mstr_force_multiple_coils(VALUE self, VALUE slave,
186
178
  ary++;
187
179
  }
188
180
 
189
- int status = force_multiple_coils(mb_param, FIX2INT(slave), FIX2INT(start_addr), RARRAY_LEN(data), buf);
181
+ int status = force_multiple_coils(mb_param, FIX2INT(start_addr), RARRAY_LEN(data), buf);
190
182
 
191
183
  if (status < 0) {
192
184
  mb_raise_error(status);
@@ -195,13 +187,11 @@ VALUE mb_mstr_force_multiple_coils(VALUE self, VALUE slave,
195
187
  return self;
196
188
  }
197
189
 
198
- VALUE mb_mstr_preset_multiple_registers(VALUE self, VALUE slave,
199
- VALUE start_addr, VALUE data)
190
+ VALUE mb_mstr_preset_multiple_registers(VALUE self, VALUE start_addr, VALUE data)
200
191
  {
201
192
  modbus_param_t *mb_param;
202
193
  Data_Get_Struct(self, modbus_param_t, mb_param);
203
194
 
204
- slave = rb_funcall(slave, rb_intern("to_i"), 0);
205
195
  start_addr = rb_funcall(start_addr, rb_intern("to_i"), 0);
206
196
  data = rb_funcall(data, rb_intern("to_a"), 0);
207
197
 
@@ -215,7 +205,7 @@ VALUE mb_mstr_preset_multiple_registers(VALUE self, VALUE slave,
215
205
  ary++;
216
206
  }
217
207
 
218
- int status = preset_multiple_registers(mb_param, FIX2INT(slave), FIX2INT(start_addr), RARRAY_LEN(data), buf);
208
+ int status = preset_multiple_registers(mb_param, FIX2INT(start_addr), RARRAY_LEN(data), buf);
219
209
 
220
210
  if (status < 0) {
221
211
  mb_raise_error(status);
data/ext/master.h CHANGED
@@ -17,20 +17,21 @@ GNU General Public License for more details. */
17
17
  extern VALUE mb_mstr_is_closed(VALUE self);
18
18
  extern VALUE mb_mstr_connect(VALUE self);
19
19
  extern VALUE mb_mstr_close(VALUE self);
20
- extern VALUE mb_mstr_read_coil_status(VALUE self, VALUE slave,
20
+ extern VALUE mb_mstr_read_coil_status(VALUE self,
21
21
  VALUE start_addr, VALUE nb);
22
- extern VALUE mb_mstr_read_input_status(VALUE self, VALUE slave,
22
+ extern VALUE mb_mstr_read_input_status(VALUE self,
23
23
  VALUE start_addr, VALUE nb);
24
- extern VALUE mb_mstr_read_holding_registers(VALUE self, VALUE slave,
24
+ extern VALUE mb_mstr_read_holding_registers(VALUE self,
25
25
  VALUE start_addr, VALUE nb);
26
- extern VALUE mb_mstr_read_input_registers(VALUE self, VALUE slave,
26
+ extern VALUE mb_mstr_read_input_registers(VALUE self,
27
27
  VALUE start_addr, VALUE nb);
28
- extern VALUE mb_mstr_force_single_coil(VALUE self, VALUE slave,
28
+ extern VALUE mb_mstr_force_single_coil(VALUE self,
29
29
  VALUE coil_addr, VALUE state);
30
- extern VALUE mb_mstr_preset_single_register(VALUE self, VALUE slave,
30
+ extern VALUE mb_mstr_preset_single_register(VALUE self,
31
31
  VALUE reg_addr, VALUE value);
32
- extern VALUE mb_mstr_force_multiple_coils(VALUE self, VALUE slave,
32
+ extern VALUE mb_mstr_force_multiple_coils(VALUE self,
33
33
  VALUE start_addr, VALUE data);
34
- extern VALUE mb_mstr_preset_multiple_registers(VALUE self, VALUE slave,
34
+ extern VALUE mb_mstr_preset_multiple_registers(VALUE self,
35
35
  VALUE start_addr, VALUE data);
36
+ extern void mb_mstr_free(modbus_param_t *mb_param );
36
37
  #endif