16[[noreturn]]
void modbusConnectionError(
modbus &mb,
const char *operation )
18 const int savedErrno = errno;
23 exc.
msg = std::string( operation ) +
" failed: " + std::strerror( savedErrno );
30constexpr int modbusNoSignalFlag = MSG_NOSIGNAL;
32constexpr int modbusNoSignalFlag = 0;
37modbus::modbus(
const std::string &host, uint16_t port ) : PORT{ port }, HOST{ host }
66 _socket = socket( AF_INET, SOCK_STREAM, 0 );
78 _server.sin_addr.s_addr = inet_addr(
HOST.c_str() );
112 struct timeval timeout;
113 timeout.tv_sec = seconds;
114 timeout.tv_usec = microseconds;
116 if( setsockopt(
_socket, SOL_SOCKET, SO_RCVTIMEO, &timeout,
sizeof( timeout ) ) != 0 )
121 if( setsockopt(
_socket, SOL_SOCKET, SO_SNDTIMEO, &timeout,
sizeof( timeout ) ) != 0 )
131 to_send[0] = (uint8_t)
_msg_id >> 8;
132 to_send[1] = (uint8_t)(
_msg_id & 0x00FF );
137 to_send[7] = (uint8_t)func;
138 to_send[8] = (uint8_t)( address >> 8 );
139 to_send[9] = (uint8_t)( address & 0x00FF );
149 to_send[10] = (uint8_t)( value[0] >> 8 );
150 to_send[11] = (uint8_t)( value[0] & 0x00FF );
155 uint8_t to_send[13 + 2 * amount];
157 to_send[5] = (uint8_t)( 5 + 2 * amount );
158 to_send[10] = (uint8_t)( amount >> 8 );
159 to_send[11] = (uint8_t)( amount & 0x00FF );
160 to_send[12] = (uint8_t)( 2 * amount );
161 for(
int i = 0; i < amount; i++ )
163 to_send[13 + 2 * i] = (uint8_t)( value[i] >> 8 );
164 to_send[14 + 2 * i] = (uint8_t)( value[i] & 0x00FF );
170 uint8_t to_send[14 + ( amount - 1 ) / 8];
172 to_send[5] = (uint8_t)( 7 + ( amount - 1 ) / 8 );
173 to_send[10] = (uint8_t)( amount >> 8 );
174 to_send[11] = (uint8_t)( amount >> 8 );
175 to_send[12] = (uint8_t)( ( amount + 7 ) / 8 );
176 for(
int i = 0; i < amount; i++ )
178 to_send[13 + ( i - 1 ) / 8] += (uint8_t)( value[i] << ( i % 8 ) );
189 to_send[10] = (uint8_t)( amount >> 8 );
190 to_send[11] = (uint8_t)( amount & 0x00FF );
198 if( amount > 65535 || address > 65535 )
208 for(
int i = 0; i < amount; i++ )
210 buffer[i] = ( (uint16_t)to_rec[9 + 2 * i] ) << 8;
211 buffer[i] += (uint16_t)to_rec[10 + 2 * i];
214 catch( std::exception &e )
229 if( amount > 65535 || address > 65535 )
239 for(
int i = 0; i < amount; i++ )
241 buffer[i] = ( (uint16_t)to_rec[9 + 2 * i] ) << 8;
242 buffer[i] += (uint16_t)to_rec[10 + 2 * i];
245 catch( std::exception &e )
260 if( amount > 2040 || address > 65535 )
270 for(
int i = 0; i < amount; i++ )
272 buffer[i] = (bool)( ( to_rec[9 + i / 8] >> ( i % 8 ) ) & 1 );
275 catch( std::exception &e )
290 if( amount > 2040 || address > 65535 )
300 for(
int i = 0; i < amount; i++ )
302 buffer[i] = (bool)( ( to_rec[9 + i / 8] >> ( i % 8 ) ) & 1 );
305 catch( std::exception &e )
320 if( address > 65535 )
324 int value = to_write * 0xFF00;
332 catch( std::exception &e )
347 if( address > 65535 )
358 catch( std::exception &e )
373 if( address > 65535 || amount > 65535 )
377 uint16_t temp[amount];
378 for(
int i = 0; i < 4; i++ )
380 temp[i] = (uint16_t)value[i];
389 catch( std::exception &e )
404 if( address > 65535 || amount > 65535 )
415 catch( std::exception &e )
430 ssize_t sent = send(
_socket, to_send, (
size_t)length, modbusNoSignalFlag );
434 modbusConnectionError( *
this,
"send" );
440 modbusConnectionError( *
this,
"send" );
458 modbusConnectionError( *
this,
"recv" );
466 if( msg[7] == func + 0x80 )
Modbus Acknowledge 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.
void modbus_read(int address, int amount, int func)
void modbus_read_input_registers(int address, int amount, uint16_t *buffer)
void modbus_read_input_bits(int address, int amount, bool *buffer)
void modbus_write_coils(int address, int amount, bool *value)
void modbus_read_holding_registers(int address, int amount, uint16_t *buffer)
ssize_t modbus_send(uint8_t *to_send, int length)
void modbus_build_request(uint8_t *to_send, int address, int func)
modbus(const std::string &host, uint16_t port)
void modbus_set_slave_id(int id)
bool modbus_set_timeouts(int seconds, int microseconds=0)
ssize_t modbus_receive(uint8_t *buffer)
void modbus_write_coil(int address, bool to_write)
struct sockaddr_in _server
void modbus_write_register(int address, uint16_t value)
void modbus_error_handle(uint8_t *msg, int func)
void modbus_write(int address, int amount, int func, uint16_t *value)
void modbus_write_registers(int address, int amount, uint16_t *value)
void modbus_read_coils(int address, int amount, bool *buffer)
The MagAO-X Modbus TCP client interface.