Skip to content
This repository was archived by the owner on Jul 30, 2021. It is now read-only.
This repository was archived by the owner on Jul 30, 2021. It is now read-only.

Suggestion on how to read from two Slaves at the same time #8

@maxdd

Description

@maxdd

Hello,
i have an inverter (fronius) and a smart meter.
The smart meter itself is read through the inverter with no problem.
Sometimes, though, i have a AsyncTCP kernel panic fault (i assume it is from Async lib)
My "read" function is the following

for (uint8_t i = 0; i < _numberfroniusRegisters; i++) {
        uint16_t packetId = _fronius.readHoldingRegisters(_froniusRegisters[i].address, _froniusRegisters[i].length);
        if (packetId > 0) {
            _froniusRegisters[i].packetId = packetId;
        } else {
            Serial.print("reading Primo error\n");
        }
    }
    delay(500); // test
for (uint8_t i = 0; i < _numbersmartMeterRegisters; i++) {
        uint16_t packetId = _smartMeter.readHoldingRegisters(_smartMeterRegisters[i].address, _smartMeterRegisters[i].length);
        if (packetId > 0) {
            _smartMeterRegisters[i].packetId = packetId;
        } else {
            Serial.print("reading Smart Meter error\n");
        }
    }

the onData() and onError() definition are inside the class init and are something like this

_fronius.onData([&](uint16_t packet, uint8_t slave, esp32Modbus::FunctionCode fc, uint8_t* data, uint16_t len) {
        for (uint8_t i = 0; i < _numberfroniusRegisters; ++i) {
            if (_froniusRegisters[i].packetId == packet) {
                _froniusRegisters[i].packetId = 0;
                if (_froniusRegisters[i].address == 40091) {
                    union u_tag {
                        uint32_t b;
                        float fval;
                    } u;
                    u.b = (data[0] << 24) | (data[1] << 16) | (data[2] << 8) | (data[3]);
                    _fronius_power = u.fval;
                    if (!isnan(_fronius_power)) {
                        _fronius_power = u.fval;
                        _produced_power = u.fval;
                        _average_fronius_power = (_average_fronius_power * idx + u.fval) / (idx + 1);
                        Serial.printf("_produced_power: %.2f\n", _produced_power);
                        Serial.printf("_average_fronius_power: %.2f\n", _average_fronius_power);
                    }
                }
            }
        }
    });

Do you believe that calling them sequentially like that can be the reason i have these crashes?
I will soon provide you an example of a crash

Moreover in the initialization list of my main class i have the following

 , _fronius(1, { 192, 168, 188, 62 }, 502)
 , _smartMeter(240, { 192, 168, 188, 62 }, 502)

is there a simpler way in order to avoid declaring two "esp32ModbusTCP" and only using one that can access two slave ids?

Can i extend the API of

uint16_t esp32ModbusTCP::readHoldingRegisters(uint16_t address, uint16_t numberRegisters) {
  esp32ModbusTCPInternals::ModbusRequest* request =
    new esp32ModbusTCPInternals::ModbusRequest03(_serverID, address, numberRegisters);
  return _addToQueue(request);
}

to take in also the different _serverID ? But how do i change the callback in order to understand which ID the information is from?

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions