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 | } |