Not Modbus specific, so apologies if I’m answering the wrong question, but if you generally want to pass additional context to a squirrel callback you can wrap the context in a class and then bindenv the function to an instance of that class, e.g.:
Phil’s solution is a great generic approach. For the Modbus lib in particular, the callback parameters are defined by the library itself. Look for _callbackHander() in ModbusSerialMaster.device.lib.nut, which triggers the callback you supply in the line you quote and passes in values for error and result.
You can add to a third param to the function you pass into modbus.read(), but you’ll need to provide a default parameter value, or you’ll get an wrong number of parameters error when the callback is executed: _callbackHander() hasn’t passed in a value. Soemthing like:
function dataLog(m) {
server.log(m);
}
local myData = "This is my extra data";
modbus.read(0x01, MODBUSRTU_TARGET_TYPE.COIL, 0x0001, 1, function(err, result, userData = myData) {
if (err) {
server.error(err);
} else {
server.log(result);
}
// Do something with the userData
dataLog(userData);
}.bindenv(this));
Alternatively, you can subclass ModbusSerialMaster ( class ModbusSerialMasterAlt extends ModbusSerialMaster { ... }) which just overrides _callbackHander() to pass an extra param into the callback? Could get messy, though, depending on what else calls that function.