Commit 467852705fb7f1e99346076fa7820b0a990a6385
1 parent
cadcf24a
Setting up working version
Showing
10 changed files
with
351 additions
and
54 deletions
3rdparty/libmodbus/modbus-tcp.c
1 | -/* | ||
2 | - * Copyright © 2001-2013 Stéphane Raimbault <stephane.raimbault@gmail.com> | ||
3 | - * | ||
4 | - * SPDX-License-Identifier: LGPL-2.1+ | ||
5 | - */ | ||
6 | - | ||
7 | #include <stdio.h> | 1 | #include <stdio.h> |
8 | #include <stdlib.h> | 2 | #include <stdlib.h> |
9 | #include <string.h> | 3 | #include <string.h> |
10 | #include <errno.h> | 4 | #include <errno.h> |
11 | -#ifndef _MSC_VER | ||
12 | #include <unistd.h> | 5 | #include <unistd.h> |
13 | -#endif | ||
14 | #include <signal.h> | 6 | #include <signal.h> |
15 | #include <sys/types.h> | 7 | #include <sys/types.h> |
16 | 8 | ||
17 | -#if defined(_WIN32) | ||
18 | -# define OS_WIN32 | ||
19 | -/* ws2_32.dll has getaddrinfo and freeaddrinfo on Windows XP and later. | ||
20 | - * minwg32 headers check WINVER before allowing the use of these */ | ||
21 | -# ifndef WINVER | ||
22 | -# define WINVER 0x0501 | ||
23 | -# endif | ||
24 | -/* Already set in modbus-tcp.h but it seems order matters in VS2005 */ | ||
25 | -# include <winsock2.h> | ||
26 | -# include <ws2tcpip.h> | ||
27 | -# define SHUT_RDWR 2 | ||
28 | -# define close closesocket | ||
29 | -#else | ||
30 | # include <sys/socket.h> | 9 | # include <sys/socket.h> |
31 | # include <sys/ioctl.h> | 10 | # include <sys/ioctl.h> |
32 | 11 | ||
@@ -40,7 +19,7 @@ | @@ -40,7 +19,7 @@ | ||
40 | # include <netinet/tcp.h> | 19 | # include <netinet/tcp.h> |
41 | # include <arpa/inet.h> | 20 | # include <arpa/inet.h> |
42 | # include <netdb.h> | 21 | # include <netdb.h> |
43 | -#endif | 22 | + |
44 | 23 | ||
45 | #if !defined(MSG_NOSIGNAL) | 24 | #if !defined(MSG_NOSIGNAL) |
46 | #define MSG_NOSIGNAL 0 | 25 | #define MSG_NOSIGNAL 0 |
3rdparty/libmodbus/modbus.c
@@ -1129,19 +1129,19 @@ int modbus_read_input_bits(modbus_t *ctx, int addr, int nb, uint8_t *dest) | @@ -1129,19 +1129,19 @@ int modbus_read_input_bits(modbus_t *ctx, int addr, int nb, uint8_t *dest) | ||
1129 | } | 1129 | } |
1130 | 1130 | ||
1131 | /* Reads the data from a remove device and put that data into an array */ | 1131 | /* Reads the data from a remove device and put that data into an array */ |
1132 | -static int read_registers(modbus_t *ctx, int function, int addr, int nb, | ||
1133 | - uint16_t *dest) | 1132 | +static int read_registers(modbus_t *ctx, int function, int addr, int nb, uint16_t *dest) |
1134 | { | 1133 | { |
1135 | int rc; | 1134 | int rc; |
1136 | int req_length; | 1135 | int req_length; |
1137 | uint8_t req[_MIN_REQ_LENGTH]; | 1136 | uint8_t req[_MIN_REQ_LENGTH]; |
1138 | uint8_t rsp[MAX_MESSAGE_LENGTH]; | 1137 | uint8_t rsp[MAX_MESSAGE_LENGTH]; |
1139 | 1138 | ||
1140 | - if (nb > MODBUS_MAX_READ_REGISTERS) { | ||
1141 | - if (ctx->debug) { | 1139 | + if (nb > MODBUS_MAX_READ_REGISTERS) |
1140 | + { | ||
1141 | + if (ctx->debug) | ||
1142 | + { | ||
1142 | fprintf(stderr, | 1143 | fprintf(stderr, |
1143 | - "ERROR Too many registers requested (%d > %d)\n", | ||
1144 | - nb, MODBUS_MAX_READ_REGISTERS); | 1144 | + "ERROR Too many registers requested (%d > %d)\n", nb, MODBUS_MAX_READ_REGISTERS); |
1145 | } | 1145 | } |
1146 | errno = EMBMDATA; | 1146 | errno = EMBMDATA; |
1147 | return -1; | 1147 | return -1; |
@@ -1150,7 +1150,8 @@ static int read_registers(modbus_t *ctx, int function, int addr, int nb, | @@ -1150,7 +1150,8 @@ static int read_registers(modbus_t *ctx, int function, int addr, int nb, | ||
1150 | req_length = ctx->backend->build_request_basis(ctx, function, addr, nb, req); | 1150 | req_length = ctx->backend->build_request_basis(ctx, function, addr, nb, req); |
1151 | 1151 | ||
1152 | rc = send_msg(ctx, req, req_length); | 1152 | rc = send_msg(ctx, req, req_length); |
1153 | - if (rc > 0) { | 1153 | + if (rc > 0) |
1154 | + { | ||
1154 | int offset; | 1155 | int offset; |
1155 | int i; | 1156 | int i; |
1156 | 1157 | ||
@@ -1164,10 +1165,10 @@ static int read_registers(modbus_t *ctx, int function, int addr, int nb, | @@ -1164,10 +1165,10 @@ static int read_registers(modbus_t *ctx, int function, int addr, int nb, | ||
1164 | 1165 | ||
1165 | offset = ctx->backend->header_length; | 1166 | offset = ctx->backend->header_length; |
1166 | 1167 | ||
1167 | - for (i = 0; i < rc; i++) { | 1168 | + for (i = 0; i < rc; i++) |
1169 | + { | ||
1168 | /* shift reg hi_byte to temp OR with lo_byte */ | 1170 | /* shift reg hi_byte to temp OR with lo_byte */ |
1169 | - dest[i] = (rsp[offset + 2 + (i << 1)] << 8) | | ||
1170 | - rsp[offset + 3 + (i << 1)]; | 1171 | + dest[i] = (rsp[offset + 2 + (i << 1)] << 8) | rsp[offset + 3 + (i << 1)]; |
1171 | } | 1172 | } |
1172 | } | 1173 | } |
1173 | 1174 |
CMakeLists.txt
@@ -12,6 +12,8 @@ set(SOURCE_FILES | @@ -12,6 +12,8 @@ set(SOURCE_FILES | ||
12 | src/IModbusAdapter.h | 12 | src/IModbusAdapter.h |
13 | src/ModbusAdapter.h | 13 | src/ModbusAdapter.h |
14 | src/ModbusAdapter.cpp | 14 | src/ModbusAdapter.cpp |
15 | + src/ModbusConnections.h | ||
16 | + src/ModbusConnections.cpp | ||
15 | ) | 17 | ) |
16 | 18 | ||
17 | add_executable(main | 19 | add_executable(main |
src/ConnectionConfig.h
@@ -3,6 +3,9 @@ | @@ -3,6 +3,9 @@ | ||
3 | #include <string> | 3 | #include <string> |
4 | #include <unordered_map> | 4 | #include <unordered_map> |
5 | 5 | ||
6 | +/*! | ||
7 | + * \brief The ConnectionPort enum | ||
8 | + */ | ||
6 | enum class ConnectionPort : unsigned int | 9 | enum class ConnectionPort : unsigned int |
7 | { | 10 | { |
8 | CP_EXTERNAL = 0, | 11 | CP_EXTERNAL = 0, |
@@ -10,6 +13,9 @@ enum class ConnectionPort : unsigned int | @@ -10,6 +13,9 @@ enum class ConnectionPort : unsigned int | ||
10 | CP_TCP | 13 | CP_TCP |
11 | }; | 14 | }; |
12 | 15 | ||
16 | +/*! | ||
17 | + * \brief The Parity enum | ||
18 | + */ | ||
13 | enum class Parity : unsigned int | 19 | enum class Parity : unsigned int |
14 | { | 20 | { |
15 | PAR_ODD, | 21 | PAR_ODD, |
@@ -17,6 +23,9 @@ enum class Parity : unsigned int | @@ -17,6 +23,9 @@ enum class Parity : unsigned int | ||
17 | PAR_NONE | 23 | PAR_NONE |
18 | }; | 24 | }; |
19 | 25 | ||
26 | +/*! | ||
27 | + * \brief The ConnectionType enum | ||
28 | + */ | ||
20 | enum class ConnectionType : unsigned int | 29 | enum class ConnectionType : unsigned int |
21 | { | 30 | { |
22 | CT_SERIAL, | 31 | CT_SERIAL, |
@@ -27,6 +36,15 @@ enum class ConnectionType : unsigned int | @@ -27,6 +36,15 @@ enum class ConnectionType : unsigned int | ||
27 | class ConnectionConfig | 36 | class ConnectionConfig |
28 | { | 37 | { |
29 | public: | 38 | public: |
39 | + /*! | ||
40 | + * \brief ConnectionConfig | ||
41 | + * \param port | ||
42 | + * \param baud | ||
43 | + * \param parity | ||
44 | + * \param dataBits | ||
45 | + * \param stopBits | ||
46 | + * \param timeOut | ||
47 | + */ | ||
30 | ConnectionConfig( ConnectionPort port, int baud = 115200, Parity parity = Parity::PAR_NONE, int dataBits = 8, int stopBits = 1, int timeOut = -1 ) | 48 | ConnectionConfig( ConnectionPort port, int baud = 115200, Parity parity = Parity::PAR_NONE, int dataBits = 8, int stopBits = 1, int timeOut = -1 ) |
31 | : m_port( port ) | 49 | : m_port( port ) |
32 | , m_baudRate( baud ) | 50 | , m_baudRate( baud ) |
@@ -36,8 +54,16 @@ public: | @@ -36,8 +54,16 @@ public: | ||
36 | , m_ipaddress() | 54 | , m_ipaddress() |
37 | , m_portnumber( -1 ) | 55 | , m_portnumber( -1 ) |
38 | , m_timeOut( timeOut ) | 56 | , m_timeOut( timeOut ) |
57 | + , m_conType( ConnectionType::CT_SERIAL ) | ||
39 | {} | 58 | {} |
40 | 59 | ||
60 | + /*! | ||
61 | + * \brief ConnectionConfig | ||
62 | + * \param port | ||
63 | + * \param ip | ||
64 | + * \param portnum | ||
65 | + * \param timeOut | ||
66 | + */ | ||
41 | ConnectionConfig( ConnectionPort port, const std::string &ip, int portnum, int timeOut = -1 ) | 67 | ConnectionConfig( ConnectionPort port, const std::string &ip, int portnum, int timeOut = -1 ) |
42 | : m_port( port ) | 68 | : m_port( port ) |
43 | , m_baudRate( -1 ) | 69 | , m_baudRate( -1 ) |
@@ -47,23 +73,24 @@ public: | @@ -47,23 +73,24 @@ public: | ||
47 | , m_ipaddress( ip ) | 73 | , m_ipaddress( ip ) |
48 | , m_portnumber( portnum ) | 74 | , m_portnumber( portnum ) |
49 | , m_timeOut( timeOut ) | 75 | , m_timeOut( timeOut ) |
76 | + , m_conType( ConnectionType::CT_TCP ) | ||
50 | {} | 77 | {} |
51 | 78 | ||
52 | // Getters and Setters. Implemented to avoid outside meddling on the member variables. | 79 | // Getters and Setters. Implemented to avoid outside meddling on the member variables. |
53 | - ConnectionType getType() const { return m_conType; } | ||
54 | - std::string getPort() const { return m_portMap.at(m_port); } | ||
55 | - int getBaudRate() const { return m_baudRate; } | ||
56 | - char getParity() const { return m_parityMap.at(m_parity); } | ||
57 | - int getDataBits() const { return m_dataBits; } | ||
58 | - int getStopBits() const { return m_stopBits; } | 80 | + std::string getPort() const { return m_portMap.at(m_port); } ///< |
81 | + ConnectionPort getPortEnum() const { return m_port; } ///< | ||
82 | + int getBaudRate() const { return m_baudRate; } ///< | ||
83 | + char getParity() const { return m_parityMap.at(m_parity); } ///< | ||
84 | + int getDataBits() const { return m_dataBits; } ///< | ||
85 | + int getStopBits() const { return m_stopBits; } ///< | ||
59 | 86 | ||
60 | - std::string getIpAddress() const { return m_ipaddress; } | ||
61 | - int getTcpPort() const { return m_portnumber; } | ||
62 | - int getTimeOut() const { return m_timeOut; } | 87 | + std::string getIpAddress() const { return m_ipaddress; } ///< |
88 | + int getTcpPort() const { return m_portnumber; } ///< | ||
63 | 89 | ||
64 | -private: | 90 | + int getTimeOut() const { return m_timeOut; } ///< |
91 | + ConnectionType getType() const { return m_conType; } ///< | ||
65 | 92 | ||
66 | - ConnectionType m_conType; | 93 | +private: |
67 | 94 | ||
68 | /// Serial connections | 95 | /// Serial connections |
69 | ConnectionPort m_port; | 96 | ConnectionPort m_port; |
@@ -78,6 +105,9 @@ private: | @@ -78,6 +105,9 @@ private: | ||
78 | 105 | ||
79 | /// Generic | 106 | /// Generic |
80 | int m_timeOut; | 107 | int m_timeOut; |
108 | + ConnectionType m_conType; | ||
109 | + | ||
110 | + // Change accordingly to the devicenames on your platform. | ||
81 | std::unordered_map<ConnectionPort, std::string> m_portMap = | 111 | std::unordered_map<ConnectionPort, std::string> m_portMap = |
82 | { | 112 | { |
83 | { ConnectionPort::CP_EXTERNAL, "/dev/ttyUSB0" }, | 113 | { ConnectionPort::CP_EXTERNAL, "/dev/ttyUSB0" }, |
src/IModbusAdapter.h
@@ -36,7 +36,7 @@ public: | @@ -36,7 +36,7 @@ public: | ||
36 | * \param startAddress | 36 | * \param startAddress |
37 | * \param noOfItems | 37 | * \param noOfItems |
38 | */ | 38 | */ |
39 | - virtual modbusData ModbusReadData( int slaveId, int startAddress, int noOfItems ) = 0; | 39 | + virtual modbusData ModbusReadData( int slaveId, int functionCode, int startAddress, int noOfItems ) = 0; |
40 | 40 | ||
41 | /*! | 41 | /*! |
42 | * \brief ModbusReadHoldReg | 42 | * \brief ModbusReadHoldReg |
@@ -55,7 +55,7 @@ public: | @@ -55,7 +55,7 @@ public: | ||
55 | * \param noOfItems | 55 | * \param noOfItems |
56 | * \param values | 56 | * \param values |
57 | */ | 57 | */ |
58 | - virtual void ModBusWriteData( int slaveId, int funtionCode, int startAddress, int noOfItems, std::vector<int>values ) = 0; | 58 | + virtual void ModBusWriteData( int slaveId, int functionCode, int startAddress, int noOfItems, std::vector<int>values ) = 0; |
59 | 59 | ||
60 | /*! | 60 | /*! |
61 | * \brief isConnected | 61 | * \brief isConnected |
src/ModbusAdapter.cpp
@@ -205,7 +205,7 @@ bool ModbusAdapter::isConnected() const | @@ -205,7 +205,7 @@ bool ModbusAdapter::isConnected() const | ||
205 | return m_connected; | 205 | return m_connected; |
206 | } | 206 | } |
207 | 207 | ||
208 | -std::string ModbusAdapter::ErrorString( int errnum ) | 208 | +std::string ModbusAdapter::ErrorString( int errnum ) const |
209 | { | 209 | { |
210 | switch(errnum) | 210 | switch(errnum) |
211 | { | 211 | { |
src/ModbusAdapter.h
@@ -23,7 +23,7 @@ public: | @@ -23,7 +23,7 @@ public: | ||
23 | /*! | 23 | /*! |
24 | * \brief ModbusAdapter | 24 | * \brief ModbusAdapter |
25 | */ | 25 | */ |
26 | - ModbusAdapter(); | 26 | + explicit ModbusAdapter(); |
27 | 27 | ||
28 | /*! | 28 | /*! |
29 | * \brief ~ModbusAdapter | 29 | * \brief ~ModbusAdapter |
@@ -34,12 +34,12 @@ public: | @@ -34,12 +34,12 @@ public: | ||
34 | * \brief ModbusConnect | 34 | * \brief ModbusConnect |
35 | * \param conncfg | 35 | * \param conncfg |
36 | */ | 36 | */ |
37 | - void ModbusConnect( const ConnectionConfig &conncfg ); | 37 | + void ModbusConnect( const ConnectionConfig &conncfg ) override; |
38 | 38 | ||
39 | /*! | 39 | /*! |
40 | * \brief ModbusDisconnect | 40 | * \brief ModbusDisconnect |
41 | */ | 41 | */ |
42 | - void ModbusDisconnect(); | 42 | + void ModbusDisconnect() override; |
43 | 43 | ||
44 | /*! | 44 | /*! |
45 | * \brief ModbusReadData | 45 | * \brief ModbusReadData |
@@ -47,7 +47,7 @@ public: | @@ -47,7 +47,7 @@ public: | ||
47 | * \param startAddress | 47 | * \param startAddress |
48 | * \param noOfItems | 48 | * \param noOfItems |
49 | */ | 49 | */ |
50 | - modbusData ModbusReadData( int slaveId, int functionCode, int startAddress, int noOfItems ); | 50 | + modbusData ModbusReadData( int slaveId, int functionCode, int startAddress, int noOfItems ) override; |
51 | 51 | ||
52 | /*! | 52 | /*! |
53 | * \brief ModbusReadHoldReg | 53 | * \brief ModbusReadHoldReg |
@@ -56,7 +56,7 @@ public: | @@ -56,7 +56,7 @@ public: | ||
56 | * \param noOfItems | 56 | * \param noOfItems |
57 | * \return | 57 | * \return |
58 | */ | 58 | */ |
59 | - modbusData ModbusReadHoldReg( int slaveId, int startAddress, int noOfItems ); | 59 | + modbusData ModbusReadHoldReg( int slaveId, int startAddress, int noOfItems ) override; |
60 | 60 | ||
61 | /*! | 61 | /*! |
62 | * \brief ModBusWriteData | 62 | * \brief ModBusWriteData |
@@ -66,20 +66,20 @@ public: | @@ -66,20 +66,20 @@ public: | ||
66 | * \param noOfItems | 66 | * \param noOfItems |
67 | * \param values | 67 | * \param values |
68 | */ | 68 | */ |
69 | - void ModBusWriteData( int slaveId, int functionCode, int startAddress, int noOfItems, std::vector<int>values ); | 69 | + void ModBusWriteData( int slaveId, int functionCode, int startAddress, int noOfItems, std::vector<int>values ) override; |
70 | 70 | ||
71 | /*! | 71 | /*! |
72 | * \brief isConnected | 72 | * \brief isConnected |
73 | * \return | 73 | * \return |
74 | */ | 74 | */ |
75 | - bool isConnected() const; | 75 | + bool isConnected() const override; |
76 | 76 | ||
77 | /*! | 77 | /*! |
78 | * \brief ErrorString | 78 | * \brief ErrorString |
79 | * \param errnum | 79 | * \param errnum |
80 | * \return | 80 | * \return |
81 | */ | 81 | */ |
82 | - std::string ErrorString( int errnum ); | 82 | + std::string ErrorString( int errnum ) const override; |
83 | 83 | ||
84 | private: // Methods | 84 | private: // Methods |
85 | void ModbusConnectRTU( const std::string &serialport, int baud, char parity, int dataBits, int stopBits, int RTS, int timeOut ); | 85 | void ModbusConnectRTU( const std::string &serialport, int baud, char parity, int dataBits, int stopBits, int RTS, int timeOut ); |
src/ModbusConnections.cpp
0 → 100644
1 | +#include "ModbusConnections.h" | ||
2 | + | ||
3 | +ModbusConnections::ModbusConnections() | ||
4 | +{ | ||
5 | + | ||
6 | +} | ||
7 | + | ||
8 | +ModbusConnections::~ModbusConnections() | ||
9 | +{ | ||
10 | + if( m_mapSerial.size() > 0 ) | ||
11 | + { | ||
12 | + // Iterate, remove and destroy ( Searching, Seek & Destroy ) | ||
13 | + } | ||
14 | + | ||
15 | + if( m_mapTcp.size() > 0 ) | ||
16 | + { | ||
17 | + // Iterate, remove and destroy ( Searching, Seek & Destroy ) | ||
18 | + } | ||
19 | +} | ||
20 | + | ||
21 | +bool ModbusConnections::CreateConnection( const ConnectionConfig &config ) | ||
22 | +{ | ||
23 | + std::shared_ptr<IModbusAdapter> ptrNewAdapter = std::make_shared<ModbusAdapter>(); | ||
24 | + if( ptrNewAdapter == nullptr ) | ||
25 | + { | ||
26 | + // Log a message and bail out | ||
27 | + return false; | ||
28 | + } | ||
29 | + | ||
30 | + // It looks like the pointer is valid. Time to connect. | ||
31 | + ptrNewAdapter->ModbusConnect( config ); | ||
32 | + if( !ptrNewAdapter->isConnected() ) | ||
33 | + { | ||
34 | + // Unsuccessful. Delete the object and return false | ||
35 | + ptrNewAdapter.reset(); | ||
36 | + return false; | ||
37 | + } | ||
38 | + | ||
39 | + std::shared_ptr<IModbusAdapter> ptr = connectionExist( config.getPortEnum(), createEndPoint( config ) ); | ||
40 | + if( ptr != nullptr ) | ||
41 | + { | ||
42 | + if( !DeleteConnection( config.getPortEnum(), createEndPoint( config ) ) ) | ||
43 | + { | ||
44 | + // Something went wrong here.. Our administration is "wonky" so report false and bail. | ||
45 | + // New connection is not created. | ||
46 | + ptrNewAdapter.reset(); | ||
47 | + return false; | ||
48 | + } | ||
49 | + } | ||
50 | + | ||
51 | + if( config.getType() == ConnectionType::CT_TCP ) | ||
52 | + { | ||
53 | + m_mapTcp.insert( { createEndPoint( config ), ptrNewAdapter } ); | ||
54 | + } | ||
55 | + else if( config.getType() == ConnectionType::CT_SERIAL ) | ||
56 | + { | ||
57 | + m_mapSerial.insert( { config.getPortEnum(), ptrNewAdapter } ); | ||
58 | + } | ||
59 | + else | ||
60 | + { | ||
61 | + // No idea what the type is but not something we recognize. | ||
62 | + ptrNewAdapter.reset(); | ||
63 | + return false; | ||
64 | + } | ||
65 | + return true; | ||
66 | +} | ||
67 | + | ||
68 | +bool ModbusConnections::DeleteConnection( const ConnectionPort portName, const std::string &endpoint ) | ||
69 | +{ | ||
70 | + | ||
71 | +} | ||
72 | + | ||
73 | +int ModbusConnections::ConnectionCount() | ||
74 | +{ | ||
75 | + return ( m_mapSerial.size() + m_mapTcp.size() ); | ||
76 | +} | ||
77 | + | ||
78 | +std::shared_ptr<IModbusAdapter> ModbusConnections::getConnection( const ConnectionPort portName, const std::string &endpoint ) | ||
79 | +{ | ||
80 | + return this->connectionExist( portName, endpoint ); | ||
81 | +} | ||
82 | + | ||
83 | +std::shared_ptr<IModbusAdapter> ModbusConnections::connectionExist( const ConnectionPort portName, const std::string &endpoint ) | ||
84 | +{ | ||
85 | + if( portName == ConnectionPort::CP_TCP ) | ||
86 | + { | ||
87 | + auto search = m_mapTcp.find( endpoint ); | ||
88 | + if( search != m_mapTcp.end() ) | ||
89 | + { | ||
90 | + return search->second; | ||
91 | + } | ||
92 | + else | ||
93 | + { | ||
94 | + return nullptr; | ||
95 | + } | ||
96 | + } | ||
97 | + else | ||
98 | + { | ||
99 | + auto search = m_mapSerial.find( portName ); | ||
100 | + if( search != m_mapSerial.end() ) | ||
101 | + { | ||
102 | + return search->second; | ||
103 | + } | ||
104 | + else | ||
105 | + { | ||
106 | + return nullptr; | ||
107 | + } | ||
108 | + } | ||
109 | +} | ||
110 | + | ||
111 | +std::string ModbusConnections::createEndPoint( const std::string &ipAddress, int portNumber ) | ||
112 | +{ | ||
113 | + if( portNumber > 0 && !ipAddress.empty() ) | ||
114 | + { | ||
115 | + return std::string( "tcp://" + ipAddress + ":" + std::to_string( portNumber ) ); | ||
116 | + } | ||
117 | + | ||
118 | + return std::string(); | ||
119 | +} | ||
120 | + | ||
121 | +std::string ModbusConnections::createEndPoint( const ConnectionConfig &config ) | ||
122 | +{ | ||
123 | + if( config.getType() != ConnectionType::CT_TCP ) | ||
124 | + { | ||
125 | + // Early opt-out | ||
126 | + return std::string(); | ||
127 | + } | ||
128 | + | ||
129 | + return createEndPoint( config.getIpAddress(), config.getTcpPort() ); | ||
130 | +} |
src/ModbusConnections.h
0 → 100644
1 | +/**************************************************************************** | ||
2 | + * Copyright (c) 2022 Priva B.V. | ||
3 | + ****************************************************************************/ | ||
4 | +#pragma once | ||
5 | + | ||
6 | +// Flexblox | ||
7 | +#include "IModbusAdapter.h" | ||
8 | +#include "ModbusAdapter.h" | ||
9 | + | ||
10 | +// std | ||
11 | +#include <memory> | ||
12 | +#include <string> | ||
13 | +#include <unordered_map> | ||
14 | + | ||
15 | +class ModbusConnections | ||
16 | +{ | ||
17 | +public: | ||
18 | + /*! | ||
19 | + * \brief ModbusConnections | ||
20 | + */ | ||
21 | + explicit ModbusConnections(); | ||
22 | + | ||
23 | + /*! | ||
24 | + * \brief ~ModbusConnections | ||
25 | + */ | ||
26 | + virtual ~ModbusConnections(); | ||
27 | + | ||
28 | + /*! | ||
29 | + * \brief CreateConnection | ||
30 | + * \param config | ||
31 | + * \return | ||
32 | + */ | ||
33 | + bool CreateConnection( const ConnectionConfig &config ); | ||
34 | + | ||
35 | + /*! | ||
36 | + * \brief DeleteConnection | ||
37 | + * \param portName | ||
38 | + * \param endpoint | ||
39 | + * \return | ||
40 | + */ | ||
41 | + bool DeleteConnection( const ConnectionPort portName, const std::string &endpoint = std::string() ); | ||
42 | + | ||
43 | + /*! | ||
44 | + * \brief ConnectionCount | ||
45 | + * \return | ||
46 | + */ | ||
47 | + int ConnectionCount(); | ||
48 | + | ||
49 | + /*! | ||
50 | + * \brief getConnection | ||
51 | + * \param portName | ||
52 | + * \param endpoint | ||
53 | + * \return | ||
54 | + */ | ||
55 | + std::shared_ptr<IModbusAdapter> getConnection( const ConnectionPort portName, const std::string &endpoint = std::string() ); | ||
56 | + | ||
57 | + // Convenient functions | ||
58 | + /*! | ||
59 | + * \brief getConnection | ||
60 | + * \param portName | ||
61 | + * \param ipAddress | ||
62 | + * \param tcpPortNumber | ||
63 | + * \return | ||
64 | + */ | ||
65 | + std::shared_ptr<IModbusAdapter> getConnection( const ConnectionPort portName, const std::string &ipAddress, int tcpPortNumber ); | ||
66 | + | ||
67 | +private: | ||
68 | + /*! | ||
69 | + * \brief connectionExist | ||
70 | + * \param portName | ||
71 | + * \param endpoint | ||
72 | + * \return | ||
73 | + */ | ||
74 | + std::shared_ptr<IModbusAdapter> connectionExist( const ConnectionPort portName, const std::string &endpoint = std::string() ); | ||
75 | + | ||
76 | + /*! | ||
77 | + * \brief createEndPoint | ||
78 | + * \param ipAddress | ||
79 | + * \param portNumber | ||
80 | + * \return | ||
81 | + */ | ||
82 | + std::string createEndPoint( const std::string &ipAddress, int portNumber ); | ||
83 | + | ||
84 | + /*! | ||
85 | + * \brief createEndPoint | ||
86 | + * \param config | ||
87 | + * \return | ||
88 | + */ | ||
89 | + std::string createEndPoint( const ConnectionConfig &config ); | ||
90 | + | ||
91 | +private: | ||
92 | + std::unordered_map<ConnectionPort, std::shared_ptr<IModbusAdapter>> m_mapSerial; ///< Unordered map holding the Modbus connections By PortName | ||
93 | + std::unordered_map<std::string, std::shared_ptr<IModbusAdapter>> m_mapTcp; ///< Unordered map holding the Modbus connections By tcp://endpoint:port | ||
94 | +}; |
src/main.cpp
1 | #include <iostream> | 1 | #include <iostream> |
2 | 2 | ||
3 | +#include "ModbusAdapter.h" | ||
4 | + | ||
3 | int main( int argc, char* argv[] ) | 5 | int main( int argc, char* argv[] ) |
4 | { | 6 | { |
7 | + ModbusAdapter oModbus; | ||
8 | + ConnectionConfig oConfig( ConnectionPort::CP_EXTERNAL, 9600, Parity::PAR_NONE, 8, 1, 1 ); | ||
9 | + | ||
10 | + std::cout << "========================= [START] Connection test ================================" << std::endl; | ||
11 | + oModbus.ModbusConnect( oConfig ); | ||
12 | + if( oModbus.isConnected() ) | ||
13 | + { | ||
14 | + std::cout << "Successful connected to : " << oConfig.getPort() << std::endl; | ||
15 | + } | ||
16 | + else | ||
17 | + { | ||
18 | + std::cout << "There was a problem connecting to : " << oConfig.getPort() << std::endl; | ||
19 | + } | ||
20 | + | ||
21 | + oModbus.ModbusDisconnect(); | ||
22 | + if( !oModbus.isConnected() ) | ||
23 | + { | ||
24 | + std::cout << "Successful disconnected from : " << oConfig.getPort() << std::endl; | ||
25 | + } | ||
26 | + else | ||
27 | + { | ||
28 | + std::cout << "There was a problem disconnecting from : " << oConfig.getPort() << std::endl; | ||
29 | + } | ||
30 | + std::cout << "========================= [END] Connection test ===============================" << std::endl; | ||
31 | + | ||
32 | + std::cout << "========================= [START] Reading test ================================" << std::endl; | ||
33 | + std::cout << "== Reading the Hold Registers ==" << std::endl; | ||
34 | + oModbus.ModbusConnect( oConfig ); | ||
35 | + if( oModbus.isConnected() ) | ||
36 | + { | ||
37 | + std::cout << "Successful connected to : " << oConfig.getPort() << std::endl; | ||
38 | + modbusData returnValues = oModbus.ModbusReadHoldReg( 1, MODBUS_FC_READ_HOLDING_REGISTERS, 2 ); | ||
39 | + if( returnValues.size() == 2 ) | ||
40 | + { | ||
41 | + std::cout << "2 items returned from MODBUS_FC_READ_HOLDING_REGISTERS " << std::endl; | ||
42 | + } | ||
43 | + else | ||
44 | + { | ||
45 | + std::cout << "There was an error reading the Hold Registers " << std::endl; | ||
46 | + std::cout << "Number of items returned : " << returnValues.size() << std::endl; | ||
47 | + } | ||
5 | 48 | ||
49 | + std::cout << "== Reading the Temperature ==" << std::endl; | ||
50 | + returnValues = oModbus.ModbusReadData( 0x01, MODBUS_FC_READ_INPUT_REGISTERS, 0x00, 0x02 ); | ||
51 | + if( returnValues.size() == 0 ) | ||
52 | + { | ||
53 | + std::cout << "No values returned " << std::endl; | ||
54 | + } | ||
55 | + else | ||
56 | + { | ||
57 | + std::cout << "Number of items returned : " << returnValues.size() << std::endl; | ||
58 | + } | ||
59 | + } | ||
60 | + else | ||
61 | + { | ||
62 | + std::cout << "There was a problem connecting to : " << oConfig.getPort() << std::endl; | ||
63 | + return -1; | ||
64 | + } | ||
65 | + oModbus.ModbusDisconnect(); | ||
66 | + std::cout << "=========================== [END] Reading test ================================" << std::endl; | ||
6 | } | 67 | } |