API
 
Loading...
Searching...
No Matches
modbus.cpp
Go to the documentation of this file.
1
2
3#include "modbus.hpp"
4
5
6modbus::modbus( const std::string & host,
7 uint16_t port
8 ) : PORT {port}, HOST{host} {}
9
10modbus::modbus(const std::string & host) : HOST{host} {}
11
13}
14
16 _slaveid = id;
17}
18
20 if(HOST == "" || PORT == 0) {
21 //std::cout << "Missing Host and Port" << std::endl;
22 return false;
23 } else {
24 //std::cout << "Found Proper Host "<< HOST << " and Port " <<PORT <<std::endl;
25 }
26
27 _socket = socket(AF_INET, SOCK_STREAM, 0);
28 if(_socket == -1) {
29 //std::cout <<"Error Opening Socket" <<std::endl;
30 return false;
31 } else {
32 //std::cout <<"Socket Opened Successfully" << std::endl;
33 }
34
35 _server.sin_family = AF_INET;
36 _server.sin_addr.s_addr = inet_addr(HOST.c_str());
37 _server.sin_port = htons(PORT);
38
39 if (connect(_socket, (struct sockaddr*)&_server, sizeof(_server)) < 0) {
40 //std::cout<< "Connection Error" << std::endl;
41 return false;
42 }
43
44 //std::cout<< "Connected" <<std::endl;
45 _connected = true;
46 return true;
47}
48
50 close(_socket);
51 //std::cout <<"Socket Closed" <<std::endl;
52}
53
54void modbus::modbus_build_request(uint8_t *to_send, int address, int func) {
55 to_send[0] = (uint8_t) _msg_id >> 8;
56 to_send[1] = (uint8_t) (_msg_id & 0x00FF);
57 to_send[2] = 0;
58 to_send[3] = 0;
59 to_send[4] = 0;
60 to_send[6] = (uint8_t) _slaveid;
61 to_send[7] = (uint8_t) func;
62 to_send[8] = (uint8_t) (address >> 8);
63 to_send[9] = (uint8_t) (address & 0x00FF);
64}
65
66void modbus::modbus_write(int address, int amount, int func, uint16_t *value) {
67 if(func == WRITE_COIL || func == WRITE_REG) {
68 uint8_t to_send[12];
69 modbus_build_request(to_send, address, func);
70 to_send[5] = 6;
71 to_send[10] = (uint8_t) (value[0] >> 8);
72 to_send[11] = (uint8_t) (value[0] & 0x00FF);
73 modbus_send(to_send, 12);
74 } else if(func == WRITE_REGS){
75 uint8_t to_send[13 + 2 * amount];
76 modbus_build_request(to_send, address, func);
77 to_send[5] = (uint8_t) (5 + 2 * amount);
78 to_send[10] = (uint8_t) (amount >> 8);
79 to_send[11] = (uint8_t) (amount & 0x00FF);
80 to_send[12] = (uint8_t) (2 * amount);
81 for(int i = 0; i < amount; i++) {
82 to_send[13 + 2 * i] = (uint8_t) (value[i] >> 8);
83 to_send[14 + 2 * i] = (uint8_t) (value[i] & 0x00FF);
84 }
85 modbus_send(to_send, 13 + 2 * amount);
86 } else if(func == WRITE_COILS) {
87 uint8_t to_send[14 + (amount -1) / 8 ];
88 modbus_build_request(to_send, address, func);
89 to_send[5] = (uint8_t) (7 + (amount -1) / 8);
90 to_send[10] = (uint8_t) (amount >> 8);
91 to_send[11] = (uint8_t) (amount >> 8);
92 to_send[12] = (uint8_t) ((amount + 7) / 8);
93 for(int i = 0; i < amount; i++) {
94 to_send[13 + (i - 1) / 8] += (uint8_t) (value[i] << (i % 8));
95 }
96 modbus_send(to_send, 14 + (amount - 1) / 8);
97 }
98}
99
100void modbus::modbus_read(int address, int amount, int func){
101 uint8_t to_send[12];
102 modbus_build_request(to_send, address, func);
103 to_send[5] = 6;
104 to_send[10] = (uint8_t) (amount >> 8);
105 to_send[11] = (uint8_t) (amount & 0x00FF);
106 modbus_send(to_send, 12);
107}
108
109void modbus::modbus_read_holding_registers(int address, int amount, uint16_t *buffer) {
110 if(_connected) {
111 if(amount > 65535 || address > 65535) {
113 }
114 modbus_read(address, amount, READ_REGS);
115 uint8_t to_rec[MAX_MSG_LENGTH];
116 modbus_receive(to_rec);
117 try {
119 for(int i = 0; i < amount; i++) {
120 buffer[i] = ((uint16_t)to_rec[9 + 2 * i]) << 8;
121 buffer[i] += (uint16_t) to_rec[10 + 2 * i];
122 }
123 } catch (std::exception &e) {
124 throw; //e;
125 }
126 } else {
128 }
129}
130
131void modbus::modbus_read_input_registers(int address, int amount, uint16_t *buffer) {
132 if(_connected){
133 if(amount > 65535 || address > 65535) {
135 }
136 modbus_read(address, amount, READ_INPUT_REGS);
137 uint8_t to_rec[MAX_MSG_LENGTH];
138 modbus_receive(to_rec);
139 try {
141 for(int i = 0; i < amount; i++) {
142 buffer[i] = ((uint16_t)to_rec[9 + 2 * i]) << 8;
143 buffer[i] += (uint16_t) to_rec[10 + 2 * i];
144 }
145 } catch (std::exception &e) {
146 throw; //e;
147 }
148 } else {
150 }
151}
152
153void modbus::modbus_read_coils(int address, int amount, bool *buffer) {
154 if(_connected) {
155 if(amount > 2040 || address > 65535) {
157 }
158 modbus_read(address, amount, READ_COILS);
159 uint8_t to_rec[MAX_MSG_LENGTH];
160 modbus_receive(to_rec);
161 try {
163 for(int i = 0; i < amount; i++) {
164 buffer[i] = (bool) ((to_rec[9 + i / 8] >> (i % 8)) & 1);
165 }
166 } catch (std::exception &e) {
167 throw; //e;
168 }
169 } else {
171 }
172}
173
174void modbus::modbus_read_input_bits(int address, int amount, bool* buffer) {
175 if(_connected) {
176 if(amount > 2040 || address > 65535) {
178 }
179 modbus_read(address, amount, READ_INPUT_BITS);
180 uint8_t to_rec[MAX_MSG_LENGTH];
181 modbus_receive(to_rec);
182 try {
184 for(int i = 0; i < amount; i++) {
185 buffer[i] = (bool) ((to_rec[9 + i / 8] >> (i % 8)) & 1);
186 }
187 } catch (std::exception &e) {
188 throw; //e;
189 }
190 } else {
192 }
193}
194
195void modbus::modbus_write_coil(int address, bool to_write) {
196 if(_connected) {
197 if(address > 65535) {
199 }
200 int value = to_write * 0xFF00;
201 modbus_write(address, 1, WRITE_COIL, (uint16_t *)&value);
202 uint8_t to_rec[MAX_MSG_LENGTH];
203 modbus_receive(to_rec);
204 try{
206 } catch (std::exception &e) {
207 throw; //e;
208 }
209 } else {
211 }
212}
213
214void modbus::modbus_write_register(int address, uint16_t value) {
215 if(_connected) {
216 if(address > 65535) {
218 }
219 modbus_write(address, 1, WRITE_REG, &value);
220 uint8_t to_rec[MAX_MSG_LENGTH];
221 modbus_receive(to_rec);
222 try{
224 } catch (std::exception &e) {
225 throw; //e;
226 }
227 } else {
229 }
230}
231
232void modbus::modbus_write_coils(int address, int amount, bool *value) {
233 if(_connected) {
234 if(address > 65535 || amount > 65535) {
236 }
237 uint16_t temp[amount];
238 for(int i = 0; i < 4; i++) {
239 temp[i] = (uint16_t)value[i];
240 }
241 modbus_write(address, amount, WRITE_COILS, temp);
242 uint8_t to_rec[MAX_MSG_LENGTH];
243 modbus_receive(to_rec);
244 try{
246 } catch (std::exception &e) {
247 throw; //e;
248 }
249 } else {
251 }
252}
253
254void modbus::modbus_write_registers(int address, int amount, uint16_t *value) {
255 if(_connected) {
256 if(address > 65535 || amount > 65535) {
258 }
259 modbus_write(address, amount, WRITE_REGS, value);
260 uint8_t to_rec[MAX_MSG_LENGTH];
261 modbus_receive(to_rec);
262 try{
264 } catch (std::exception &e) {
265 throw; //e;
266 }
267 } else {
269 }
270}
271
272ssize_t modbus::modbus_send(uint8_t *to_send, int length) {
273 _msg_id++;
274 return send(_socket, to_send, (size_t)length, 0);
275}
276
277ssize_t modbus::modbus_receive(uint8_t *buffer) {
278 return recv(_socket, (char *) buffer, MAX_MSG_LENGTH, 0);
279}
280
281void modbus::modbus_error_handle(uint8_t *msg, int func) {
282 if(msg[7] == func + 0x80) {
283 switch(msg[8]){
288 case EX_ILLEGAL_VALUE:
292 case EX_ACKNOWLEDGE:
294 case EX_SERVER_BUSY:
299 default:
300 break;
301 }
302 }
303}
Modbus Acknowledge Exception.
Modbus Amount Exception.
Modbus Connect Exception.
Modbus Gate Way Problem Exception.
Modbus Illegal Address Exception.
Modbus Illegal Data Value Exception.
Modbus Illgal Function Exception.
Modbus Server Busy Exception.
Modbus Server Failure Exception.
int _msg_id
Definition modbus.hpp:68
void modbus_read(int address, int amount, int func)
Definition modbus.cpp:100
bool modbus_connect()
Definition modbus.cpp:19
void modbus_read_input_registers(int address, int amount, uint16_t *buffer)
Definition modbus.cpp:131
void modbus_read_input_bits(int address, int amount, bool *buffer)
Definition modbus.cpp:174
void modbus_write_coils(int address, int amount, bool *value)
Definition modbus.cpp:232
~modbus()
Definition modbus.cpp:12
void modbus_read_holding_registers(int address, int amount, uint16_t *buffer)
Definition modbus.cpp:109
bool _connected
Definition modbus.hpp:65
ssize_t modbus_send(uint8_t *to_send, int length)
Definition modbus.cpp:272
void modbus_build_request(uint8_t *to_send, int address, int func)
Definition modbus.cpp:54
modbus(const std::string &host, uint16_t port)
Definition modbus.cpp:6
void modbus_set_slave_id(int id)
Definition modbus.cpp:15
ssize_t modbus_receive(uint8_t *buffer)
Definition modbus.cpp:277
void modbus_write_coil(int address, bool to_write)
Definition modbus.cpp:195
uint16_t PORT
Definition modbus.hpp:66
void modbus_close()
Definition modbus.cpp:49
struct sockaddr_in _server
Definition modbus.hpp:71
int _socket
Definition modbus.hpp:67
void modbus_write_register(int address, uint16_t value)
Definition modbus.cpp:214
void modbus_error_handle(uint8_t *msg, int func)
Definition modbus.cpp:281
std::string HOST
Definition modbus.hpp:70
void modbus_write(int address, int amount, int func, uint16_t *value)
Definition modbus.cpp:66
void modbus_write_registers(int address, int amount, uint16_t *value)
Definition modbus.cpp:254
void modbus_read_coils(int address, int amount, bool *buffer)
Definition modbus.cpp:153
int _slaveid
Definition modbus.hpp:69
@ EX_SERVER_FAILURE
Definition modbus.hpp:50
@ EX_GATEWAY_PROBLEMP
Definition modbus.hpp:53
@ EX_ACKNOWLEDGE
Definition modbus.hpp:51
@ EX_ILLEGAL_FUNCTION
Definition modbus.hpp:47
@ EX_GATEWYA_PROBLEMF
Definition modbus.hpp:54
@ EX_SERVER_BUSY
Definition modbus.hpp:52
@ EX_ILLEGAL_VALUE
Definition modbus.hpp:49
@ EX_ILLEGAL_ADDRESS
Definition modbus.hpp:48
#define MAX_MSG_LENGTH
Definition modbus.hpp:31
@ READ_COILS
Definition modbus.hpp:35
@ WRITE_REG
Definition modbus.hpp:40
@ WRITE_COIL
Definition modbus.hpp:39
@ READ_INPUT_BITS
Definition modbus.hpp:36
@ READ_REGS
Definition modbus.hpp:37
@ WRITE_COILS
Definition modbus.hpp:41
@ WRITE_REGS
Definition modbus.hpp:42
@ READ_INPUT_REGS
Definition modbus.hpp:38