From 6df1774f17bb595fd04699ed7b2c0cf08651a0f8 Mon Sep 17 00:00:00 2001 From: travis-farmer Date: Thu, 28 Nov 2024 04:17:30 -0500 Subject: [PATCH] cleaning up IO_Modbus --- IO_Modbus.cpp | 43 ++++++++++++++----------------- IO_Modbus.h | 70 +++++++++++++++++++++++++++++++++++---------------- 2 files changed, 68 insertions(+), 45 deletions(-) diff --git a/IO_Modbus.cpp b/IO_Modbus.cpp index 160236c..8127c0e 100644 --- a/IO_Modbus.cpp +++ b/IO_Modbus.cpp @@ -487,32 +487,19 @@ Modbus::Modbus(uint8_t busNo, HardwareSerial &serial, unsigned long baud, uint16 _serialD = &serial; _txPin = txPin; _rtuComm.setTimeout(500); - - _busNo = busNo; _cycleTime = cycleTimeMS * 1000UL; // convert from milliseconds to microseconds. - //if (_transmitEnablePin != VPIN_NONE) { - //pinMode(_transmitEnablePin, OUTPUT); - //ArduinoPins::fastWriteDigital(_transmitEnablePin, 0); // transmitter initially off - //} - //_serial->begin(baud); - //_modbusmaster.begin(baud); - //DIAG(F("ModbusInit: %d %d"), _transmitEnablePin, _baud); // Add device to HAL device chain - IODevice::addDevice(this); - // Add bus to CMRIbus chain. + // Add bus to Modbus chain. _nextBus = _busList; _busList = this; } // Main loop function for Modbus. // Work through list of nodes. For each node, in separate loop entries -// send initialisation message (once only); then send -// output message; then send prompt for input data, and -// process any response data received. // When the slot time has finished, move on to the next device. void Modbus::_loop(unsigned long currentMicros) { _currentMicros = currentMicros; @@ -521,7 +508,7 @@ void Modbus::_loop(unsigned long currentMicros) { _currentNode = _nodeListStart; } - //DIAG(F("Modbus Loop: %d : %d :: %d"), _currentMicros, _cycleStartTime, _currentNode); + if (_currentMicros - _cycleStartTime < _cycleTime) return; _cycleStartTime = _currentMicros; if (_currentNode == NULL) return; @@ -529,21 +516,29 @@ void Modbus::_loop(unsigned long currentMicros) { const char* errorStrings[16] = { "success", "invalid id", "invalid buffer", "invalid quantity", "response timeout", "frame error", "crc error", "unknown comm error", "unexpected id", "exception response", "unexpected function code", "unexpected response length", "unexpected byte count", "unexpected address", "unexpected value", "unexpected quantity" }; uint8_t error; + // send reads and writes, DIAG on errors other than 0 (Success), or 3 (Invalid Quantity) error = writeMultipleHoldingRegisters(_currentNode->getNodeID(), 0, (uint16_t*) _currentNode->holdingRegisters, _currentNode->getNumHoldingRegisters()); - DIAG(F("ModbusHR: T%d F%d N%d %s"), _currentNode->getNodeID(), 0, _currentNode->getNumHoldingRegisters(), errorStrings[error]); - + if (error != 0 || error != 3) DIAG(F("ModbusHR: T%d F%d N%d %s"), _currentNode->getNodeID(), 0, _currentNode->getNumHoldingRegisters(), errorStrings[error]); +#ifdef DIAG_IO + if (error == 0) DIAG(F("ModbusHR: T%d Success!"), _currentNode->getNodeID()); +#endif error = writeMultipleCoils(_currentNode->getNodeID(), 0, (char*) _currentNode->coils, _currentNode->getNumCoils()); - DIAG(F("ModbusMC: T%d F%d N%d %s"), _currentNode->getNodeID(), 0, _currentNode->getNumCoils(), errorStrings[error]); - + if (error != 0 || error != 3) DIAG(F("ModbusMC: T%d F%d N%d %s"), _currentNode->getNodeID(), 0, _currentNode->getNumCoils(), errorStrings[error]); +#ifdef DIAG_IO + if (error == 0) DIAG(F("ModbusMC: T%d Success!"), _currentNode->getNodeID()); +#endif error = readDiscreteInputs(_currentNode->getNodeID(), 0, (char*) _currentNode->discreteInputs, _currentNode->getNumDiscreteInputs()); - DIAG(F("ModbusDI: T%d F%d N%d %s"), _currentNode->getNodeID(), 0, _currentNode->getNumDiscreteInputs(), errorStrings[error]); - + if (error != 0 || error != 3) DIAG(F("ModbusDI: T%d F%d N%d %s"), _currentNode->getNodeID(), 0, _currentNode->getNumDiscreteInputs(), errorStrings[error]); +#ifdef DIAG_IO + if (error == 0) DIAG(F("ModbusDI: T%d Success!"), _currentNode->getNodeID()); +#endif error = readInputRegisters(_currentNode->getNodeID(), 0, (uint16_t*) _currentNode->inputRegisters, _currentNode->getNumInputRegisters()); - DIAG(F("ModbusIR: T%d F%d N%d %s"), _currentNode->getNodeID(), 0, _currentNode->getNumInputRegisters(), errorStrings[error]); - + if (error != 0 || error != 3) DIAG(F("ModbusIR: T%d F%d N%d %s"), _currentNode->getNodeID(), 0, _currentNode->getNumInputRegisters(), errorStrings[error]); +#ifdef DIAG_IO + if (error == 0) DIAG(F("ModbusIR: T%d Success!"), _currentNode->getNodeID()); +#endif _currentNode = _currentNode->getNext(); - //delayUntil(_currentMicros + _cycleTime * 1000UL); } // Link to chain of Modbus instances diff --git a/IO_Modbus.h b/IO_Modbus.h index a8313ea..4b0b564 100644 --- a/IO_Modbus.h +++ b/IO_Modbus.h @@ -229,15 +229,10 @@ public: return 0; } - int _readAnalogue(VPIN vpin) override { - // Return acquired data value, e.g. - int pin = vpin - _firstVpin - _numDiscreteInputs; - return (int) inputRegisters[pin]; - } - + void _write(VPIN vpin, int value) override { // Update current state for this device, in preparation the bus transmission - uint16_t pin = vpin - _firstVpin - _numDiscreteInputs - _numInputRegisters; + uint16_t pin = vpin - _firstVpin - _numDiscreteInputs; if (pin < _numCoils) { if (value) if (value == 1) coils[pin] = (char*) 0x1; @@ -248,8 +243,14 @@ public: } } + int _readAnalogue(VPIN vpin) override { + // Return acquired data value, e.g. + int pin = vpin - _firstVpin - _numDiscreteInputs - _numCoils; + return (int) inputRegisters[pin]; + } + void _writeAnalogue(VPIN vpin, int value, uint8_t param1=0, uint16_t param2=0) override { - uint16_t pin = vpin - _firstVpin - _numDiscreteInputs - _numInputRegisters - _numCoils; + uint16_t pin = vpin - _firstVpin - _numDiscreteInputs - _numCoils - _numInputRegisters; if (pin < _numHoldingRegisters) { if (value) holdingRegisters[pin] = (uint16_t*) value; @@ -258,18 +259,50 @@ public: } } - char getType() { - return _type; - } - uint8_t getBusNumber() { return _busNo; } + uint8_t getNumBinaryInputsVPINsMin() { + if (_numDiscreteInputs > 0) return _firstVpin; + else return 0; + } + uint8_t getNumBinaryInputsVPINsMax() { + if (_numDiscreteInputs > 0) return _firstVpin+_numDiscreteInputs-1; + else return 0; + } + uint8_t getNumBinaryOutputsVPINsMin() { + if (_numCoils > 0) return _firstVpin+_numDiscreteInputs; + else return 0; + } + uint8_t getNumBinaryOutputsVPINsMax() { + if (_numCoils > 0) return _firstVpin+_numDiscreteInputs+_numCoils-1; + else return 0; + } + + uint8_t getNumAnalogInputsVPINsMin() { + if (_numInputRegisters > 0) return _firstVpin+_numDiscreteInputs+_numCoils; + else return 0; + } + uint8_t getNumAnalogInputsVPINsMax() { + if (_numInputRegisters > 0) return _firstVpin+_numDiscreteInputs+_numCoils+_numInputRegisters-1; + else return 0; + } + + uint8_t getNumAnalogOutputsVPINsMin() { + if (_numHoldingRegisters > 0) return _firstVpin+_numDiscreteInputs+_numCoils+_numInputRegisters; + else return 0; + } + uint8_t getNumAnalogOutputsVPINsMax() { + if (_numHoldingRegisters > 0) return _firstVpin+_numDiscreteInputs+_numCoils+_numInputRegisters+_numHoldingRegisters-1; + else return 0; + } void _display() override { - DIAG(F("Modbusnode configured on bus:%d nodeID:%d VPINs:%u-%u (in) %u-%u (out)"), - _busNo, _nodeID, _firstVpin, _firstVpin+_numDiscreteInputs-1, - _firstVpin+_numDiscreteInputs, _firstVpin+_numDiscreteInputs+_numCoils-1); + DIAG(F("Modbusnode configured on bus:%d nodeID:%d VPINs:%u-%u (B In) %u-%u (B Out) %u-%u (A In) %u-%u (A Out)"), + _busNo, _nodeID, getNumBinaryInputsVPINsMin(), getNumBinaryInputsVPINsMax(), + getNumBinaryOutputsVPINsMin(), getNumBinaryOutputsVPINsMax(), + getNumAnalogInputsVPINsMin(), getNumAnalogInputsVPINsMax(), + getNumAnalogOutputsVPINsMin(), getNumAnalogOutputsVPINsMax()); } }; @@ -313,17 +346,12 @@ public: new Modbus(busNo, serial, baud, cycleTimeMS, txPin); } HardwareSerial *_serialD; - //ModbusRTUMaster *_modbusmaster; ModbusRTUComm _rtuComm; // Device-specific initialisation void _begin() override { - //ModbusRTUMaster _modbusmaster(*_serialD, _transmitEnablePin, -1); _serialD->begin(_baud, SERIAL_8N1); - //ModbusRTUMaster _modbusmaster(*_serialD, _txPin, -1); _rtuComm.begin(_baud, SERIAL_8N1); - - //_serialD->println("test"); - + #if defined(DIAG_IO) _display(); #endif