Commit cadcf24a5c8ba23c58d10e26ffdf4689eba96331
1 parent
32017af3
Setting up working version
Showing
6 changed files
with
525 additions
and
19 deletions
CMakeLists.txt
src/ConnectionConfig.h
| 1 | 1 | #pragma once |
| 2 | 2 | |
| 3 | 3 | #include <string> |
| 4 | +#include <unordered_map> | |
| 4 | 5 | |
| 5 | -enum class ConnectionPort | |
| 6 | +enum class ConnectionPort : unsigned int | |
| 6 | 7 | { |
| 7 | - CP_EXTERNAL, | |
| 8 | + CP_EXTERNAL = 0, | |
| 8 | 9 | CP_IOBUS, |
| 9 | 10 | CP_TCP |
| 10 | 11 | }; |
| 11 | 12 | |
| 12 | -enum class Parity | |
| 13 | +enum class Parity : unsigned int | |
| 13 | 14 | { |
| 14 | - P_ODD, | |
| 15 | - P_EVEN, | |
| 16 | - P_NONE | |
| 15 | + PAR_ODD, | |
| 16 | + PAR_EVEN, | |
| 17 | + PAR_NONE | |
| 18 | +}; | |
| 19 | + | |
| 20 | +enum class ConnectionType : unsigned int | |
| 21 | +{ | |
| 22 | + CT_SERIAL, | |
| 23 | + CT_TCP, | |
| 24 | + CT_UNKNOWN | |
| 17 | 25 | }; |
| 18 | 26 | |
| 19 | 27 | class ConnectionConfig |
| 20 | 28 | { |
| 21 | 29 | public: |
| 22 | - ConnectionConfig( ConnectionPort port, int baud = 115200, Parity parity = Parity::P_NONE, int dataBits = 8, int stopBits = 1 ) | |
| 23 | - { | |
| 24 | - | |
| 25 | - } | |
| 30 | + ConnectionConfig( ConnectionPort port, int baud = 115200, Parity parity = Parity::PAR_NONE, int dataBits = 8, int stopBits = 1, int timeOut = -1 ) | |
| 31 | + : m_port( port ) | |
| 32 | + , m_baudRate( baud ) | |
| 33 | + , m_parity( parity ) | |
| 34 | + , m_dataBits( dataBits ) | |
| 35 | + , m_stopBits( stopBits ) | |
| 36 | + , m_ipaddress() | |
| 37 | + , m_portnumber( -1 ) | |
| 38 | + , m_timeOut( timeOut ) | |
| 39 | + {} | |
| 26 | 40 | |
| 27 | 41 | ConnectionConfig( ConnectionPort port, const std::string &ip, int portnum, int timeOut = -1 ) |
| 28 | - { | |
| 42 | + : m_port( port ) | |
| 43 | + , m_baudRate( -1 ) | |
| 44 | + , m_parity( Parity::PAR_NONE ) | |
| 45 | + , m_dataBits( -1 ) | |
| 46 | + , m_stopBits( -1 ) | |
| 47 | + , m_ipaddress( ip ) | |
| 48 | + , m_portnumber( portnum ) | |
| 49 | + , m_timeOut( timeOut ) | |
| 50 | + {} | |
| 29 | 51 | |
| 30 | - } | |
| 52 | + // 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; } | |
| 59 | + | |
| 60 | + std::string getIpAddress() const { return m_ipaddress; } | |
| 61 | + int getTcpPort() const { return m_portnumber; } | |
| 62 | + int getTimeOut() const { return m_timeOut; } | |
| 31 | 63 | |
| 32 | 64 | private: |
| 33 | 65 | |
| 66 | + ConnectionType m_conType; | |
| 67 | + | |
| 34 | 68 | /// Serial connections |
| 35 | - ConnectionPort m_serPort; | |
| 69 | + ConnectionPort m_port; | |
| 36 | 70 | int m_baudRate; |
| 37 | 71 | Parity m_parity; |
| 38 | 72 | int m_dataBits; |
| 39 | 73 | int m_stopBits; |
| 40 | 74 | |
| 41 | 75 | /// TCP connections |
| 76 | + std::string m_ipaddress; | |
| 77 | + int m_portnumber; | |
| 42 | 78 | |
| 79 | + /// Generic | |
| 80 | + int m_timeOut; | |
| 81 | + std::unordered_map<ConnectionPort, std::string> m_portMap = | |
| 82 | + { | |
| 83 | + { ConnectionPort::CP_EXTERNAL, "/dev/ttyUSB0" }, | |
| 84 | + { ConnectionPort::CP_IOBUS, "/dev/ttyUSB1" } | |
| 85 | + }; | |
| 86 | + | |
| 87 | + std::unordered_map<Parity, char> m_parityMap = | |
| 88 | + { | |
| 89 | + { Parity::PAR_EVEN, 'E' }, | |
| 90 | + { Parity::PAR_ODD, 'O' }, | |
| 91 | + { Parity::PAR_NONE, 'N' } | |
| 92 | + }; | |
| 43 | 93 | }; | ... | ... |
src/IModbusAdapter.h
| ... | ... | @@ -4,7 +4,69 @@ |
| 4 | 4 | |
| 5 | 5 | #pragma once |
| 6 | 6 | |
| 7 | +// std | |
| 8 | +#include <string> | |
| 9 | +#include <variant> | |
| 10 | +#include <vector> | |
| 11 | + | |
| 12 | +using modbusData = std::vector<std::variant<uint8_t, uint16_t>>; | |
| 13 | + | |
| 14 | +// Forward Declaration | |
| 15 | +class ConnectionConfig; | |
| 16 | + | |
| 17 | +/*! | |
| 18 | + * \brief The IModbusAdapter class | |
| 19 | + */ | |
| 7 | 20 | class IModbusAdapter |
| 8 | 21 | { |
| 22 | + | |
| 23 | +public: | |
| 9 | 24 | virtual ~IModbusAdapter() {} |
| 25 | + | |
| 26 | + virtual void ModbusConnect( const ConnectionConfig &conncfg ) = 0; | |
| 27 | + | |
| 28 | + /*! | |
| 29 | + * \brief ModbusDisconnect | |
| 30 | + */ | |
| 31 | + virtual void ModbusDisconnect() = 0; | |
| 32 | + | |
| 33 | + /*! | |
| 34 | + * \brief ModbusReadData | |
| 35 | + * \param slaveId | |
| 36 | + * \param startAddress | |
| 37 | + * \param noOfItems | |
| 38 | + */ | |
| 39 | + virtual modbusData ModbusReadData( int slaveId, int startAddress, int noOfItems ) = 0; | |
| 40 | + | |
| 41 | + /*! | |
| 42 | + * \brief ModbusReadHoldReg | |
| 43 | + * \param slaveId | |
| 44 | + * \param startAddress | |
| 45 | + * \param noOfItems | |
| 46 | + * \return | |
| 47 | + */ | |
| 48 | + virtual modbusData ModbusReadHoldReg( int slaveId, int startAddress, int noOfItems ) = 0; | |
| 49 | + | |
| 50 | + /*! | |
| 51 | + * \brief ModBusWriteData | |
| 52 | + * \param slaveId | |
| 53 | + * \param funtionCode | |
| 54 | + * \param startAddress | |
| 55 | + * \param noOfItems | |
| 56 | + * \param values | |
| 57 | + */ | |
| 58 | + virtual void ModBusWriteData( int slaveId, int funtionCode, int startAddress, int noOfItems, std::vector<int>values ) = 0; | |
| 59 | + | |
| 60 | + /*! | |
| 61 | + * \brief isConnected | |
| 62 | + * \return | |
| 63 | + */ | |
| 64 | + virtual bool isConnected() const = 0; | |
| 65 | + | |
| 66 | + /*! | |
| 67 | + * \brief ErrorString | |
| 68 | + * \param errnum | |
| 69 | + * \return | |
| 70 | + */ | |
| 71 | + virtual std::string ErrorString( int errnum ) const = 0; | |
| 10 | 72 | }; | ... | ... |
src/ModbusAdapter.cpp
| 1 | + | |
| 2 | +#include "ConnectionConfig.h" | |
| 3 | +#include "ModbusAdapter.h" | |
| 4 | + | |
| 5 | +#include <cstring> /// Added for memset functionality | |
| 6 | + | |
| 7 | +ModbusAdapter::ModbusAdapter() | |
| 8 | + : m_modbus( nullptr ) | |
| 9 | +{ | |
| 10 | + this->InitBuffers(); | |
| 11 | +} | |
| 12 | + | |
| 13 | +ModbusAdapter::~ModbusAdapter() | |
| 14 | +{ | |
| 15 | + | |
| 16 | +} | |
| 17 | + | |
| 18 | +void ModbusAdapter::ModbusConnect( const ConnectionConfig &conncfg ) | |
| 19 | +{ | |
| 20 | + if( m_connected ) | |
| 21 | + { | |
| 22 | + this->ModbusDisconnect(); | |
| 23 | + } | |
| 24 | + | |
| 25 | + this->m_connType = conncfg.getType(); | |
| 26 | + | |
| 27 | + switch( m_connType ) | |
| 28 | + { | |
| 29 | + case ConnectionType::CT_SERIAL: | |
| 30 | + this->ModbusConnectRTU( conncfg.getPort(), conncfg.getBaudRate(), conncfg.getParity(), conncfg.getDataBits(), conncfg.getStopBits(), conncfg.getTimeOut(), MODBUS_RTU_RTS_NONE ); | |
| 31 | + break; | |
| 32 | + | |
| 33 | + case ConnectionType::CT_TCP: | |
| 34 | + break; | |
| 35 | + | |
| 36 | + default: | |
| 37 | + // throw a sensible message or return an errorcode. | |
| 38 | + break; | |
| 39 | + } | |
| 40 | +} | |
| 41 | + | |
| 42 | +void ModbusAdapter::ModbusDisconnect() | |
| 43 | +{ | |
| 44 | + if( m_modbus != nullptr ) | |
| 45 | + { | |
| 46 | + if( m_connected ) | |
| 47 | + { | |
| 48 | + modbus_close( m_modbus ); | |
| 49 | + modbus_free( m_modbus ); | |
| 50 | + } | |
| 51 | + // Clean up after ourselves. | |
| 52 | + m_modbus = nullptr; | |
| 53 | + } | |
| 54 | + m_connected = false; | |
| 55 | +} | |
| 56 | + | |
| 57 | +modbusData ModbusAdapter::ModbusReadData( int slaveId, int functionCode, int startAddress, int noOfItems ) | |
| 58 | +{ | |
| 59 | + if( m_modbus == nullptr ) | |
| 60 | + { | |
| 61 | + // No context | |
| 62 | + return modbusData(); | |
| 63 | + } | |
| 64 | + | |
| 65 | + | |
| 66 | + | |
| 67 | + int resultValue = -1; | |
| 68 | + bool is16Bit = false; | |
| 69 | + | |
| 70 | + modbus_set_slave( m_modbus, slaveId ); | |
| 71 | + | |
| 72 | + // Request data from modbus. | |
| 73 | + switch( functionCode ) | |
| 74 | + { | |
| 75 | + case MODBUS_FC_READ_COILS: | |
| 76 | + resultValue = modbus_read_bits( m_modbus, startAddress, noOfItems, m_dest ); | |
| 77 | + break; | |
| 78 | + case MODBUS_FC_READ_DISCRETE_INPUTS: | |
| 79 | + resultValue = modbus_read_input_bits( m_modbus, startAddress, noOfItems, m_dest ); | |
| 80 | + break; | |
| 81 | + case MODBUS_FC_READ_HOLDING_REGISTERS: | |
| 82 | + resultValue = modbus_read_registers( m_modbus, startAddress, noOfItems, m_dest16 ); | |
| 83 | + break; | |
| 84 | + case MODBUS_FC_READ_INPUT_REGISTERS: | |
| 85 | + resultValue = modbus_read_input_registers( m_modbus, startAddress, noOfItems, m_dest16 ); | |
| 86 | + break; | |
| 87 | + | |
| 88 | + default: | |
| 89 | + break; | |
| 90 | + | |
| 91 | + } | |
| 92 | + | |
| 93 | + // Read the databuffers | |
| 94 | + if( resultValue != noOfItems ) | |
| 95 | + { | |
| 96 | + return modbusData(); | |
| 97 | + } | |
| 98 | + | |
| 99 | + modbusData resultData; | |
| 100 | + for( int index = 0; index < noOfItems; ++index ) | |
| 101 | + { | |
| 102 | + resultData.push_back( (is16Bit ? static_cast<uint16_t>(m_dest16[index]) : static_cast<uint16_t>(m_dest[index])) ); | |
| 103 | + } | |
| 104 | + | |
| 105 | + modbus_flush( m_modbus ); // flush data | |
| 106 | + this->ClearBuffers(); | |
| 107 | + | |
| 108 | + return resultData; | |
| 109 | +} | |
| 110 | + | |
| 111 | +modbusData ModbusAdapter::ModbusReadHoldReg( int slaveId, int startAddress, int noOfItems ) | |
| 112 | +{ | |
| 113 | + if( m_modbus == nullptr ) | |
| 114 | + { | |
| 115 | + return modbusData(); | |
| 116 | + } | |
| 117 | + | |
| 118 | + int resultValue = -1; /// Return value from read functions | |
| 119 | + | |
| 120 | + // -- Start Critical Section --- ?? // | |
| 121 | + | |
| 122 | + modbus_set_slave( m_modbus, slaveId ); | |
| 123 | + /// Request data from modbus | |
| 124 | + resultValue = modbus_read_registers( m_modbus, startAddress, noOfItems, m_dest16 ); | |
| 125 | + | |
| 126 | + /// Read the databuffers | |
| 127 | + if( resultValue != noOfItems ) | |
| 128 | + { | |
| 129 | + return modbusData(); | |
| 130 | + } | |
| 131 | + | |
| 132 | + modbusData resultData; | |
| 133 | + for( int index = 0; index < noOfItems; ++index ) | |
| 134 | + { | |
| 135 | + resultData.push_back( static_cast<uint16_t>(m_dest16[index]) ); | |
| 136 | + } | |
| 137 | + | |
| 138 | + modbus_flush( m_modbus ); | |
| 139 | + this->ClearBuffers(); | |
| 140 | + | |
| 141 | + // -- End Critical Section --- ?? // | |
| 142 | + | |
| 143 | + return resultData; | |
| 144 | +} | |
| 145 | + | |
| 146 | +void ModbusAdapter::ModBusWriteData( int slaveId, int functionCode, int startAddress, int noOfItems, std::vector<int>values ) | |
| 147 | +{ | |
| 148 | + if( m_modbus == nullptr ) | |
| 149 | + { | |
| 150 | + return; | |
| 151 | + } | |
| 152 | + | |
| 153 | + // ------------------------------------------------ | |
| 154 | + // Create 8 bits databuffer | |
| 155 | + auto * data8 = new uint8_t[noOfItems]; | |
| 156 | + for( int index = 0; index < noOfItems; ++index ) | |
| 157 | + { | |
| 158 | + data8[index] = values[index]; | |
| 159 | + } | |
| 160 | + | |
| 161 | + // Create same buffer for 16 bits data | |
| 162 | + auto * data16 = new uint8_t[noOfItems]; | |
| 163 | + for( int index = 0; index < noOfItems; ++index ) | |
| 164 | + { | |
| 165 | + data16[index] = values[index]; | |
| 166 | + } | |
| 167 | + // ------------------------------------------------ | |
| 168 | + | |
| 169 | + int resultValue = -1; | |
| 170 | + | |
| 171 | + modbus_set_slave( m_modbus, slaveId ); | |
| 172 | + | |
| 173 | + // Request data from modbus | |
| 174 | + switch( functionCode ) | |
| 175 | + { | |
| 176 | + case MODBUS_FC_WRITE_SINGLE_COIL: | |
| 177 | + resultValue = modbus_write_bit( m_modbus, startAddress, values[0] ); | |
| 178 | + noOfItems = 1; | |
| 179 | + break; | |
| 180 | + case MODBUS_FC_WRITE_SINGLE_REGISTER: | |
| 181 | + resultValue = modbus_write_register( m_modbus, startAddress, values[0] ); | |
| 182 | + noOfItems = 1; | |
| 183 | + break; | |
| 184 | + case MODBUS_FC_WRITE_MULTIPLE_COILS: | |
| 185 | + | |
| 186 | + resultValue = modbus_write_bits( m_modbus, startAddress, noOfItems, data8 ); | |
| 187 | + break; | |
| 188 | + case MODBUS_FC_WRITE_MULTIPLE_REGISTERS: | |
| 189 | + resultValue = modbus_write_bits( m_modbus, startAddress, noOfItems, data16 ); | |
| 190 | + break; | |
| 191 | + } | |
| 192 | + | |
| 193 | + delete[] data8; | |
| 194 | + delete[] data16; | |
| 195 | + modbus_flush(m_modbus); // Flush data. | |
| 196 | + | |
| 197 | + if( resultValue != noOfItems ) | |
| 198 | + { | |
| 199 | + // Create a log line that writing the register failed. Maybe increment ErrorCounter(s) | |
| 200 | + } | |
| 201 | +} | |
| 202 | + | |
| 203 | +bool ModbusAdapter::isConnected() const | |
| 204 | +{ | |
| 205 | + return m_connected; | |
| 206 | +} | |
| 207 | + | |
| 208 | +std::string ModbusAdapter::ErrorString( int errnum ) | |
| 209 | +{ | |
| 210 | + switch(errnum) | |
| 211 | + { | |
| 212 | + case EINVAL: | |
| 213 | + return "Protocol context is NULL"; | |
| 214 | + break; | |
| 215 | + case ETIMEDOUT: | |
| 216 | + return "Timeout"; | |
| 217 | + break; | |
| 218 | + case ECONNRESET: | |
| 219 | + return "Connection reset"; | |
| 220 | + break; | |
| 221 | + case ECONNREFUSED: | |
| 222 | + return "Connection refused"; | |
| 223 | + break; | |
| 224 | + case EPIPE: | |
| 225 | + return "Socket error"; | |
| 226 | + break; | |
| 227 | + default: | |
| 228 | + return modbus_strerror(errno); | |
| 229 | + } | |
| 230 | +} | |
| 231 | + | |
| 232 | +/* ============= PRIVATE METHODS ============= */ | |
| 233 | +void ModbusAdapter::ModbusConnectRTU( const std::string &serialport, int baud, char parity, int dataBits, int stopBits, int RTS, int timeOut ) | |
| 234 | +{ | |
| 235 | + m_modbus = modbus_new_rtu( serialport.c_str(), baud, parity, dataBits, stopBits, RTS ); | |
| 236 | + | |
| 237 | +#ifdef LIB_MODBUS_DEBUG_OUTPUT | |
| 238 | + // Do sensible logging through PRIVA_LOG | |
| 239 | + m_modbus_set_debug( m_modbus, 1 ); | |
| 240 | +#endif | |
| 241 | + if( m_modbus == nullptr ) | |
| 242 | + { | |
| 243 | + // We can stop here. Nothing to be done as we don't have a valid context | |
| 244 | + // Log to PRIVA_LOG | |
| 245 | + return; | |
| 246 | + } | |
| 247 | + else if( m_modbus && modbus_connect( m_modbus ) == -1 ) | |
| 248 | + { | |
| 249 | + // We could not connect to the selected serial port. | |
| 250 | + // We can stop here. Nothing to be done as we don't have a valid connection | |
| 251 | + modbus_free( m_modbus ); | |
| 252 | + m_connected = false; | |
| 253 | + return; | |
| 254 | + } | |
| 255 | + | |
| 256 | + // Set recovery mode | |
| 257 | + modbus_set_error_recovery( m_modbus, MODBUS_ERROR_RECOVERY_PROTOCOL ); | |
| 258 | + | |
| 259 | + // Set the response timeout | |
| 260 | + modbus_set_response_timeout( m_modbus, timeOut, 0 ); | |
| 261 | + | |
| 262 | + m_connected = true; | |
| 263 | +} | |
| 264 | + | |
| 265 | +void ModbusAdapter::ModbusConnectTCP( const std::string &ip, int port, int timeOut ) | |
| 266 | +{ | |
| 267 | + if( ip.empty() ) | |
| 268 | + { | |
| 269 | + // Nothing to be done. Set an Logline to PRIVA_LOG and exit. | |
| 270 | + return; | |
| 271 | + } | |
| 272 | + | |
| 273 | + m_modbus = modbus_new_tcp( ip.c_str(), port ); | |
| 274 | + | |
| 275 | +#ifdef LIB_MODBUS_DEBUG_OUTPUT | |
| 276 | + // Do sensible logging through PRIVA_LOG | |
| 277 | + m_modbus_set_debug( m_modbus, 1 ); | |
| 278 | +#endif | |
| 279 | + | |
| 280 | + if( m_modbus == nullptr ) | |
| 281 | + { | |
| 282 | + // We can stop here. Nothing to be done as we don't have a valid context | |
| 283 | + // Log to PRIVA_LOG | |
| 284 | + return; | |
| 285 | + } | |
| 286 | + else if( m_modbus && modbus_connect( m_modbus ) == -1 ) | |
| 287 | + { | |
| 288 | + // We could not connect to the selected serial port. | |
| 289 | + // We can stop here. Nothing to be done as we don't have a valid connection | |
| 290 | + modbus_free( m_modbus ); | |
| 291 | + m_connected = false; | |
| 292 | + return; | |
| 293 | + } | |
| 294 | + | |
| 295 | + // Set recovery mode | |
| 296 | + modbus_set_error_recovery( m_modbus, MODBUS_ERROR_RECOVERY_PROTOCOL ); | |
| 297 | + | |
| 298 | + // Set the response timeout | |
| 299 | + modbus_set_response_timeout( m_modbus, timeOut, 0 ); | |
| 300 | + | |
| 301 | + m_connected = true; | |
| 302 | +} | |
| 303 | + | |
| 304 | +void ModbusAdapter::InitBuffers() | |
| 305 | +{ | |
| 306 | + // Setup memory for Data. | |
| 307 | + m_dest = (uint8_t *)malloc(2000 + sizeof(uint8_t)); | |
| 308 | + m_dest16 = (uint16_t *)malloc(125 * sizeof(uint16_t)); | |
| 309 | + | |
| 310 | + this->ClearBuffers(); | |
| 311 | +} | |
| 312 | + | |
| 313 | +void ModbusAdapter::ClearBuffers() | |
| 314 | +{ | |
| 315 | + memset(m_dest, 0, 2000 * sizeof(uint8_t)); | |
| 316 | + memset(m_dest16, 0, 125 * sizeof(uint16_t)); | |
| 317 | +} | ... | ... |
src/ModbusAdapter.h
| ... | ... | @@ -6,17 +6,94 @@ |
| 6 | 6 | |
| 7 | 7 | #include "ConnectionConfig.h" |
| 8 | 8 | #include "IModbusAdapter.h" |
| 9 | +#include "modbus.h" | |
| 9 | 10 | |
| 10 | -/// \brief This class represents a single modbus context. Each context will | |
| 11 | -/// result in an instance of this class. It is not intended to be | |
| 12 | -/// created directly but through a factory. The factory will create | |
| 13 | -/// the object and return the pointer to its interface. | |
| 11 | +// std | |
| 12 | +#include <memory> | |
| 13 | +#include <variant> | |
| 14 | +#include <vector> | |
| 14 | 15 | |
| 16 | +/// @brief The ModbusAdapter class represents a single modbus context. Each context will | |
| 17 | +/// result in an instance of this class. It is not intended to be | |
| 18 | +/// created directly but through a factory. The factory will create | |
| 19 | +/// the object and return the pointer to its interface. | |
| 15 | 20 | class ModbusAdapter : public IModbusAdapter |
| 16 | 21 | { |
| 17 | 22 | public: |
| 23 | + /*! | |
| 24 | + * \brief ModbusAdapter | |
| 25 | + */ | |
| 18 | 26 | ModbusAdapter(); |
| 27 | + | |
| 28 | + /*! | |
| 29 | + * \brief ~ModbusAdapter | |
| 30 | + */ | |
| 19 | 31 | virtual ~ModbusAdapter(); |
| 20 | 32 | |
| 21 | - void ModbusConnectRTU(const ConnectionConfig &conncfg); | |
| 33 | + /*! | |
| 34 | + * \brief ModbusConnect | |
| 35 | + * \param conncfg | |
| 36 | + */ | |
| 37 | + void ModbusConnect( const ConnectionConfig &conncfg ); | |
| 38 | + | |
| 39 | + /*! | |
| 40 | + * \brief ModbusDisconnect | |
| 41 | + */ | |
| 42 | + void ModbusDisconnect(); | |
| 43 | + | |
| 44 | + /*! | |
| 45 | + * \brief ModbusReadData | |
| 46 | + * \param slaveId | |
| 47 | + * \param startAddress | |
| 48 | + * \param noOfItems | |
| 49 | + */ | |
| 50 | + modbusData ModbusReadData( int slaveId, int functionCode, int startAddress, int noOfItems ); | |
| 51 | + | |
| 52 | + /*! | |
| 53 | + * \brief ModbusReadHoldReg | |
| 54 | + * \param slaveId | |
| 55 | + * \param startAddress | |
| 56 | + * \param noOfItems | |
| 57 | + * \return | |
| 58 | + */ | |
| 59 | + modbusData ModbusReadHoldReg( int slaveId, int startAddress, int noOfItems ); | |
| 60 | + | |
| 61 | + /*! | |
| 62 | + * \brief ModBusWriteData | |
| 63 | + * \param slaveId | |
| 64 | + * \param funtionCode | |
| 65 | + * \param startAddress | |
| 66 | + * \param noOfItems | |
| 67 | + * \param values | |
| 68 | + */ | |
| 69 | + void ModBusWriteData( int slaveId, int functionCode, int startAddress, int noOfItems, std::vector<int>values ); | |
| 70 | + | |
| 71 | + /*! | |
| 72 | + * \brief isConnected | |
| 73 | + * \return | |
| 74 | + */ | |
| 75 | + bool isConnected() const; | |
| 76 | + | |
| 77 | + /*! | |
| 78 | + * \brief ErrorString | |
| 79 | + * \param errnum | |
| 80 | + * \return | |
| 81 | + */ | |
| 82 | + std::string ErrorString( int errnum ); | |
| 83 | + | |
| 84 | +private: // Methods | |
| 85 | + void ModbusConnectRTU( const std::string &serialport, int baud, char parity, int dataBits, int stopBits, int RTS, int timeOut ); | |
| 86 | + void ModbusConnectTCP( const std::string &ip, int port, int timeOut = -1 ); | |
| 87 | + | |
| 88 | + void InitBuffers(); | |
| 89 | + void ClearBuffers(); | |
| 90 | + | |
| 91 | +private: // Members | |
| 92 | + ConnectionType m_connType { ConnectionType::CT_UNKNOWN }; ///> The type of connection this instance provides. Needed for administration | |
| 93 | + bool m_connected { false }; ///> Shows if the connection is still active. | |
| 94 | + modbus_t *m_modbus; ///> The actual low-level modbus instance as a raw-pointer. ( unique_pointer gives an error on this struct ) | |
| 95 | + | |
| 96 | + // Return value Buffers ( Room for improvement ) | |
| 97 | + uint8_t *m_dest; | |
| 98 | + uint16_t *m_dest16; | |
| 22 | 99 | }; | ... | ... |
tests/main.cpp renamed to src/main.cpp