Digitalisierte Elektroverteilung zur permanenten Verbraucherüberwachung
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

ModbusInterface.cpp 5.1KB

3 years ago
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213
  1. #include "ModbusInterface.h"
  2. #include "ModbusInterface.h"
  3. #include <iostream>
  4. #include <easylogging++.h>
  5. void ModbusInterface::assignSlave() {
  6. my_modbus->addSlave(slaveAddressID);
  7. my_slave = my_modbus->slavePtr(slaveAddressID);
  8. }
  9. ModbusInterface::~ModbusInterface() {
  10. if(my_modbus != nullptr){
  11. my_modbus->close();
  12. delete my_modbus;
  13. }
  14. }
  15. bool ModbusInterface::openConnection() {
  16. modbus_init();
  17. //if(!(my_modbus->isOpen()))
  18. open = my_modbus->open();
  19. if(!open){
  20. LOG(ERROR) << "Couldn't open Modbus " << getConnectionType() <<
  21. " connection at " << device;
  22. LOG(ERROR) << my_modbus->lastError();
  23. }
  24. return open;
  25. }
  26. void ModbusInterface::disconnect() {
  27. if(my_modbus != nullptr)
  28. my_modbus->close();
  29. }
  30. bool ModbusInterface::readBit(ParameterSpecification &param) {
  31. if(!param.connection->getIsOpen()){
  32. param.error = true;
  33. return false;
  34. }
  35. bool buf;
  36. if (my_slave->readCoil(param.address, buf) != 1) {
  37. param.error = true;
  38. return 0;
  39. }
  40. else{
  41. param.readedBytes.push_back(buf);
  42. param.error = false;
  43. return buf;
  44. }
  45. }
  46. bool ModbusInterface::readBits(ParameterSpecification &param) {
  47. if(!param.connection->getIsOpen()){
  48. param.error = true;
  49. return false;
  50. }
  51. bool bufBool[param.length*8];
  52. int ans = my_slave->readCoils(param.address, bufBool, param.length*8);
  53. if (ans != param.length*8) {
  54. param.error = true;
  55. return 0;
  56. }
  57. else{
  58. //Big Endian decryption
  59. for(unsigned int i = 0; i < param.length; i++){
  60. uint8_t byte = 0;
  61. for(unsigned int j = 0; j < 8; j++){
  62. byte += bufBool[i*8 +j] << j;
  63. }
  64. param.readedBytes.push_back(byte);
  65. }
  66. param.error = false;
  67. return true;
  68. }
  69. }
  70. uint8_t ModbusInterface::readByte(ParameterSpecification &param) {
  71. if(!param.connection->getIsOpen()){
  72. param.error = true;
  73. return false;
  74. }
  75. uint16_t buf;
  76. if (my_slave->readRegister(param.address, buf) != 1) {
  77. param.error = true;
  78. return 0;
  79. }
  80. else{
  81. param.readedBytes.push_back(buf & 0x00FF);
  82. param.error = false;
  83. return static_cast<uint8_t>(buf & 0x00FF);
  84. }
  85. }
  86. uint16_t ModbusInterface::readRegister(ParameterSpecification &param) {
  87. if(!param.connection->getIsOpen()){
  88. param.error = true;
  89. return false;
  90. }
  91. uint16_t buf;
  92. if (my_slave->readRegister(param.address, buf) != 1) {
  93. param.error = true;
  94. return 0;
  95. }
  96. else{
  97. param.readedBytes.push_back(buf);
  98. param.error = false;
  99. return buf;
  100. }
  101. }
  102. uint32_t ModbusInterface::readDRegister(ParameterSpecification &param) {
  103. if(!param.connection->getIsOpen()){
  104. param.error = true;
  105. return false;
  106. }
  107. uint16_t buf[2];
  108. if (my_slave->readRegisters(param.address, buf, 2) != 2) {
  109. param.error = true;
  110. return 0;
  111. }
  112. else{
  113. param.readedBytes.push_back(*buf);
  114. param.readedBytes.push_back(*(buf+1));
  115. param.error = false;
  116. return _MODBUS_GET_INT32_FROM_INT16(buf, 0);
  117. }
  118. }
  119. uint64_t ModbusInterface::readQRegister(ParameterSpecification &param) {
  120. if(!param.connection->getIsOpen()){
  121. param.error = true;
  122. return false;
  123. }
  124. uint16_t buf[4];
  125. int ans = my_slave->readRegisters(param.address, buf, 4);
  126. if (ans != 4) {
  127. param.error = true;
  128. return 0;
  129. }
  130. else{
  131. param.readedBytes.push_back(*buf);
  132. param.readedBytes.push_back(*(buf+1));
  133. param.readedBytes.push_back(*(buf+2));
  134. param.readedBytes.push_back(*(buf+3));
  135. param.error = false;
  136. return _MODBUS_GET_INT64_FROM_INT16(buf, 0);
  137. }
  138. }
  139. bool ModbusInterface::writeBit(const uint16_t address, bool bit)
  140. {
  141. if(my_slave->writeCoil(address, bit) != 1){
  142. return false;
  143. }
  144. else
  145. return true;
  146. }
  147. bool ModbusInterface::writeByte(const uint16_t address, uint8_t byte)
  148. {
  149. bool buf[8];
  150. for(int i = 0; i < 8; i++){
  151. buf[i] = byte & 0x01;
  152. byte = byte > 1;
  153. }
  154. if(my_slave->writeCoils(address, buf, 8) != 1){
  155. return false;
  156. }
  157. else
  158. return true;
  159. }
  160. bool ModbusInterface::writeRegister(const uint16_t address, uint16_t word)
  161. {
  162. if(my_slave->writeRegister(address, word) != 1){
  163. return false;
  164. }
  165. else
  166. return true;
  167. }
  168. bool ModbusInterface::writeDRegister(const uint16_t address, uint32_t dword)
  169. {
  170. uint16_t data[2];
  171. data[0] = (dword & 0x0000FFFF);
  172. data[0] = (dword & 0xFFFF0000)>>16;
  173. if(my_slave->writeRegisters(address, data, 2) != 1){
  174. return false;
  175. }
  176. else
  177. return true;
  178. }
  179. bool ModbusInterface::writeQRegister(const uint16_t address, uint64_t qword)
  180. {
  181. uint16_t data[4];
  182. data[0] = (qword & 0x0000'0000'0000'FFFF);
  183. data[1] = (qword & 0x0000'0000'FFFF'0000) >> 16;
  184. data[2] = (qword & 0x0000'FFFF'0000'0000) >> 32;
  185. data[3] = (qword & 0xFFFF'0000'0000'0000) >> 48;
  186. if(my_slave->writeRegisters(address, data, 4) != 1){
  187. return false;
  188. }
  189. else
  190. return true;
  191. }