Skip to content

Commit

Permalink
Custom code to make BSB-LAN accessible via Modbus
Browse files Browse the repository at this point in the history
  • Loading branch information
fredlcore committed Dec 10, 2023
1 parent 4c7c0c4 commit bc063b5
Show file tree
Hide file tree
Showing 3 changed files with 58 additions and 0 deletions.
2 changes: 2 additions & 0 deletions BSB_LAN/custom_functions/Modbus_Interface/BSB_LAN_custom.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
// Only doing Modbus maintenance work during loop
mb.task();
43 changes: 43 additions & 0 deletions BSB_LAN/custom_functions/Modbus_Interface/BSB_LAN_custom_global.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
/*
* These three scripts need to be copied to the main directory and the CUSTOM_COMMANDS definement needs to be activated in order
* to start a Modbus server that will relay queries from Modbus to the heating system and return the requested parameter values.
* Writing parameters is also possible.
* You need to define the parameters that should be allowed to be queried via the mb.addHreg function in BSB_LAN_custom_setup.h
* Since querying/setting parameters from/to the heating system may take up to two seconds, make sure that the Modbus client does not
* exit prematurely due to a timeout.
*/

#include "src/modbus-esp8266/src/ModbusTCP.h"
ModbusTCP mb;

// Remove this function when using Modbus RTU (over serial/RS485)
bool cbConn(IPAddress ip) {
Serial.print(PSTR("Modbus connection from IP: "));
Serial.println(ip);
return true; // return false for example to prevent forbidden IP ranges
}

// Callback for querying a parameter - value will be queried from heating system and returned to Modbus client
// This function only supports integers up to 16 bit unsigned.
// Any other values will require further encoding into Modbus' 16 bit unsigned integers to whatever necessary value here!
uint16_t cbGet(TRegister* reg, uint16_t val) {
uint16_t param = reg->address.address;
query(param);
if (decodedTelegram.prognr < 0) return 65535;
val = strtod(decodedTelegram.value, NULL);
return val;
}

// Callback for setting a parameter - value received will be sent to the heating system
// This function only supports integers up to 16 bit unsigned.
// Any other values will require further decoding from Modbus' 16 bit unsigned integers to whatever necessary value here!
uint16_t cbSet(TRegister* reg, uint16_t val) {
uint16_t param = reg->address.address;
char val_as_char[20];
sprintf(val_as_char, "%d", val);
set(param, (char*)val_as_char, (param!=10000?1:0)); // dirty hack to send INF for paramater 10000
// Serial.println(val); // new value
// Serial.println(reg->value); // previous value in register
// Serial.println(reg->address.type); // register type (03 = holding register)
return val;
}
13 changes: 13 additions & 0 deletions BSB_LAN/custom_functions/Modbus_Interface/BSB_LAN_custom_setup.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
// Start Modbus server
mb.server(502); // Start Modbus server on port 502

// Callback functions
mb.onConnect(cbConn); // Add callback on connection event - remove this when using Modbus RTU (over serial / RS485)
mb.onGetHreg(0, cbGet, 20720); // add callback for get holding register request
mb.onSetHreg(0, cbSet, 20720); // add callback for set holding register request

// Add registers that should be accessible over Modbus here.
// ATTENTION: These registers comsume RAM and definig too many can lead to crashes of the ESP32!
mb.addHreg(700, 0, 100); // add one holding register for each parameter from 700 to 799
mb.addHreg(10000, 0, 1); // holding register for parameter 10000
mb.addHreg(20700, 0, 20); // holding register for custom floats (20700-20719)

0 comments on commit bc063b5

Please sign in to comment.