1
0
mirror of https://github.com/DCC-EX/CommandStation-EX.git synced 2024-12-24 13:21:23 +01:00

making current

This commit is contained in:
travis-farmer 2024-11-26 08:18:22 -05:00
parent 0b5aca43f8
commit 8624b0aa79
No known key found for this signature in database
GPG Key ID: 0BC296791D14CB35
2 changed files with 74 additions and 65 deletions

View File

@ -206,11 +206,11 @@ void ModbusRTUComm::begin(unsigned long baud, uint32_t config) {
#endif
if (_dePin >= 0) {
pinMode(_dePin, OUTPUT);
digitalWrite(_dePin, LOW);
ArduinoPins::fastWriteDigital(_dePin, LOW);
}
if (_rePin >= 0) {
pinMode(_rePin, OUTPUT);
digitalWrite(_rePin, LOW);
ArduinoPins::fastWriteDigital(_rePin, LOW);
}
clearRxBuffer();
}
@ -249,13 +249,13 @@ ModbusRTUCommError ModbusRTUComm::readAdu(ModbusADU& adu) {
void ModbusRTUComm::writeAdu(ModbusADU& adu) {
adu.updateCrc();
if (_dePin >= 0) digitalWrite(_dePin, HIGH);
if (_rePin >= 0) digitalWrite(_rePin, HIGH);
if (_dePin >= 0) ArduinoPins::fastWriteDigital(_dePin, HIGH);
if (_rePin >= 0) ArduinoPins::fastWriteDigital(_rePin, HIGH);
_serial.write(adu.rtu, adu.getRtuLen());
_serial.flush();
///delayMicroseconds(_postDelay);
if (_dePin >= 0) digitalWrite(_dePin, LOW);
if (_rePin >= 0) digitalWrite(_rePin, LOW);
if (_dePin >= 0) ArduinoPins::fastWriteDigital(_dePin, LOW);
if (_rePin >= 0) ArduinoPins::fastWriteDigital(_rePin, LOW);
}
void ModbusRTUComm::clearRxBuffer() {
@ -487,10 +487,10 @@ ModbusRTUMasterError ModbusRTUMaster::_translateCommError(ModbusRTUCommError com
************************************************************/
// Constructor for Modbus
Modbus::Modbus(uint8_t busNo, HardwareSerial serial, unsigned long baud, uint16_t cycleTimeMS, int16_t transmitEnablePin) {
Modbus::Modbus(uint8_t busNo, HardwareSerial serial, unsigned long baud, uint16_t cycleTimeMS, int8_t transmitEnablePin) {
_busNo = busNo;
_baud = baud;
_serial = &serial;
_serialD = &serial;
_cycleTime = cycleTimeMS * 1000UL; // convert from milliseconds to microseconds.
_transmitEnablePin = transmitEnablePin;
//if (_transmitEnablePin != VPIN_NONE) {
@ -503,21 +503,12 @@ Modbus::Modbus(uint8_t busNo, HardwareSerial serial, unsigned long baud, uint16_
//DIAG(F("ModbusInit: %d %d"), _transmitEnablePin, _baud);
// Add device to HAL device chain
IODevice::addDevice(this);
// Add bus to CMRIbus chain.
_nextBus = _busList;
_busList = this;
}
void Modbus::_begin() {
ModbusRTUMaster _modbusmaster(*_serial, _transmitEnablePin, -1);
_serial->begin(_baud);
_modbusmaster.begin(_baud);
#if defined(DIAG_IO)
_display();
#endif
}
// Main loop function for Modbus.
// Work through list of nodes. For each node, in separate loop entries
// send initialisation message (once only); then send
@ -528,30 +519,35 @@ void Modbus::_loop(unsigned long currentMicros) {
_currentMicros = currentMicros;
//if (_currentNode == NULL) {
//_currentNode = _nodeListStart;
if (_currentNode == NULL) {
_currentNode = _nodeListStart;
//}
}
//DIAG(F("Modbus Loop: %d : %d :: %d"), _currentMicros, _cycleStartTime, _currentNode);
if (_currentMicros - _cycleStartTime < _cycleTime) return;
_cycleStartTime = _currentMicros;
DIAG(F("Tick"));
if (_currentNode == NULL) return;
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;
//error = _modbusmaster->writeMultipleHoldingRegisters(_currentNode->getNodeID(), 0, _currentNode->holdingRegisters, _currentNode->getNumHoldingRegisters());
//if (error != 0) DIAG(F("ModbusHR: %d %d %d %s"), _currentNode->getNodeID(), 0, _currentNode->getNumHoldingRegisters(), errorStrings[error]);
error = _modbusmaster->writeMultipleCoils(_currentNode->getNodeID(), 0, _currentNode->coils, _currentNode->getNumCoils());
if (error != 0) DIAG(F("ModbusMC: %d %d %d %s"), _currentNode->getNodeID(), 0, _currentNode->getNumCoils(), errorStrings[error]);
//DIAG(F("ModbusHR: %d %d %d %s"), _currentNode->getNodeID(), 0, _currentNode->getNumHoldingRegisters(), errorStrings[error]);
//error = _modbusmaster->writeMultipleCoils(_currentNode->getNodeID(), 0, _currentNode->coils, _currentNode->getNumCoils());
DIAG(F("ModbusMC: T%d F%d N%d %s"), _currentNode->getNodeID(), 0, _currentNode->getNumCoils(), errorStrings[error]);
if (error == MODBUS_RTU_MASTER_EXCEPTION_RESPONSE) {
DIAG(F(": %s"), _modbusmaster->getExceptionResponse());
}
error = _modbusmaster->readDiscreteInputs(_currentNode->getNodeID(), 0, _currentNode->discreteInputs, _currentNode->getNumDiscreteInputs());
if (error != 0) DIAG(F("ModbusDI: %d %d %d %s"), _currentNode->getNodeID(), 0, _currentNode->getNumDiscreteInputs(), errorStrings[error]);
DIAG(F("ModbusDI: T%d F%d N%d %s"), _currentNode->getNodeID(), 0, _currentNode->getNumDiscreteInputs(), errorStrings[error]);
//error = _modbusmaster->readInputRegisters(_currentNode->getNodeID(), 0, _currentNode->inputRegisters, _currentNode->getNumInputRegisters());
//if (error != 0) DIAG(F("ModbusIR: %d %d %d %s"), _currentNode->getNodeID(), 0, _currentNode->getNumInputRegisters(), errorStrings[error]);
//DIAG(F("ModbusIR: %d %d %d %s"), _currentNode->getNodeID(), 0, _currentNode->getNumInputRegisters(), errorStrings[error]);
_currentNode = _currentNode->getNext();
//delayUntil(_currentMicros + _cycleTime * 1000UL);
_cycleStartTime = _currentMicros;
}
}
// Link to chain of Modbus instances
Modbus *Modbus::_busList = NULL;
@ -567,10 +563,14 @@ Modbusnode::Modbusnode(VPIN firstVpin, int nPins, uint8_t busNo, uint8_t nodeID,
_nPins = nPins;
_busNo = busNo;
_nodeID = nodeID;
coils[numCoils];
discreteInputs[numDiscreteInputs];
holdingRegisters[numHoldingRegisters];
inputRegisters[numInputRegisters];
_numCoils = numCoils;
_numDiscreteInputs = numDiscreteInputs;
_numHoldingRegisters = numHoldingRegisters;
_numInputRegisters = numInputRegisters;
coils[_numCoils];
discreteInputs[_numDiscreteInputs];
holdingRegisters[_numHoldingRegisters];
inputRegisters[_numInputRegisters];
if ((unsigned int)_nPins < numDiscreteInputs + numCoils)
DIAG(F("Modbusnode: bus:%d nodeID:%d WARNING number of Vpins does not cover all inputs and outputs"), _busNo, _nodeID);
@ -582,11 +582,12 @@ Modbusnode::Modbusnode(VPIN firstVpin, int nPins, uint8_t busNo, uint8_t nodeID,
// Add this device to HAL device list
IODevice::addDevice(this);
_display();
// Add Modbusnode to Modbus object.
Modbus *bus = Modbus::findBus(_busNo);
if (bus != NULL) {
bus->addNode(this);
return;
}
}

View File

@ -189,16 +189,16 @@ private:
char _type;
Modbusnode *_next = NULL;
bool _initialised = false;
uint8_t numCoils;
uint8_t numDiscreteInputs;
uint8_t numHoldingRegisters;
uint8_t numInputRegisters;
uint8_t _numCoils;
uint8_t _numDiscreteInputs;
uint8_t _numHoldingRegisters;
uint8_t _numInputRegisters;
public:
static void create(VPIN firstVpin, int nPins, uint8_t busNo, uint8_t nodeID, uint8_t numCoils=0, uint8_t numDiscreteInputs=0, uint8_t numHoldingRegisters=0, uint8_t numInputRegisters=0) {
if (checkNoOverlap(firstVpin, nPins)) new Modbusnode(firstVpin, nPins, busNo, nodeID, numCoils, numDiscreteInputs, numHoldingRegisters, numInputRegisters);
}
Modbusnode(VPIN firstVpin, int nPins, uint8_t busNo, uint8_t nodeID, uint8_t numCoils=0, uint8_t numDiscreteInputs=0, uint8_t numHoldingRegisters=0, uint8_t numInputRegisters=0);
Modbusnode(VPIN firstVpin, int nPins, uint8_t busNo, uint8_t nodeID, uint8_t numCoils, uint8_t numDiscreteInputs, uint8_t numHoldingRegisters, uint8_t numInputRegisters);
bool *coils;
bool *discreteInputs;
uint16_t *holdingRegisters;
@ -208,16 +208,16 @@ public:
return _nodeID;
}
uint8_t getNumCoils() {
return numCoils;
return _numCoils;
}
uint8_t getNumDiscreteInputs() {
return numDiscreteInputs;
return _numDiscreteInputs;
}
uint8_t getNumHoldingRegisters() {
return numHoldingRegisters;
return _numHoldingRegisters;
}
uint8_t getNumInputRegisters() {
return numInputRegisters;
return _numInputRegisters;
}
Modbusnode *getNext() {
return _next;
@ -232,14 +232,14 @@ public:
_initialised = true;
}
void _begin() {
void _begin() override {
_initialised = false;
}
int _read(VPIN vpin) override {
// Return current state from this device
uint16_t pin = vpin - _firstVpin;
if (pin < numDiscreteInputs) {
if (pin < _numDiscreteInputs) {
return discreteInputs[pin];
} else
return 0;
@ -247,14 +247,14 @@ public:
int _readAnalogue(VPIN vpin) override {
// Return acquired data value, e.g.
int pin = vpin - _firstVpin - numDiscreteInputs;
int pin = vpin - _firstVpin - _numDiscreteInputs;
return 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;
if (pin < numCoils) {
uint16_t pin = vpin - _firstVpin - _numDiscreteInputs - _numInputRegisters;
if (pin < _numCoils) {
if (value)
coils[pin] = value;
else
@ -262,9 +262,9 @@ public:
}
}
void writeAnalogue(VPIN vpin, int value) {
uint16_t pin = vpin - _firstVpin - numDiscreteInputs - numInputRegisters - numCoils;
if (pin < numHoldingRegisters) {
void _writeAnalogue(VPIN vpin, int value, uint8_t param1=0, uint16_t param2=0) override {
uint16_t pin = vpin - _firstVpin - _numDiscreteInputs - _numInputRegisters - _numCoils;
if (pin < _numHoldingRegisters) {
if (value)
holdingRegisters[pin] = value;
else
@ -273,23 +273,23 @@ public:
}
void saveIncomingData(uint8_t index, uint8_t data) {
if (index < numDiscreteInputs)
if (index < _numDiscreteInputs)
discreteInputs[index] = data;
}
uint8_t getOutputStates(uint8_t index) {
if (index < numCoils)
if (index < _numCoils)
return coils[index];
else
return 0;
}
uint16_t getNumInputs() {
return numDiscreteInputs;
return _numDiscreteInputs;
}
uint16_t getNumOutputs() {
return numCoils;
return _numCoils;
}
char getType() {
@ -301,9 +301,9 @@ public:
}
void _display() override {
DIAG(F("Modbusnode type:'%c' configured on bus:%d nodeID:%d VPINs:%u-%u (in) %u-%u (out)"),
_type, _busNo, _nodeID, _firstVpin, _firstVpin+numDiscreteInputs-1,
_firstVpin+numDiscreteInputs, _firstVpin+numDiscreteInputs+numCoils-1);
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);
}
};
@ -322,7 +322,7 @@ private:
uint8_t _busNo;
unsigned long _baud;
int16_t _transmitEnablePin = VPIN_NONE;
int8_t _transmitEnablePin;
Modbusnode *_nodeListStart = NULL, *_nodeListEnd = NULL;
Modbusnode *_currentNode = NULL;
@ -339,21 +339,29 @@ private:
static Modbus *_busList; // linked list of defined bus instances
public:
static void create(uint8_t busNo, HardwareSerial& serial, unsigned long baud, uint16_t cycleTimeMS=500, int16_t transmitEnablePin=51) {
static void create(uint8_t busNo, HardwareSerial& serial, unsigned long baud, uint16_t cycleTimeMS=500, int8_t transmitEnablePin=0) {
new Modbus(busNo, serial, baud, cycleTimeMS, transmitEnablePin);
}
HardwareSerial *_serial;
HardwareSerial *_serialD;
ModbusRTUMaster *_modbusmaster;
// Device-specific initialisation
void _begin() override;
void _begin() override {
ModbusRTUMaster _modbusmaster(*_serialD, _transmitEnablePin, -1);
_serialD->begin(_baud);
_modbusmaster.begin(_baud);
#if defined(DIAG_IO)
_display();
#endif
}
// Loop function (overriding IODevice::_loop(unsigned long))
void _loop(unsigned long currentMicros) override;
// Display information about the device
void _display() override {
DIAG(F("Modbus %d configured, speed=%d baud, cycle=%d ms"), _busNo, _baud, _cycleTime/1000);
DIAG(F("Modbus Configured on %d Vpins:%d-%d %S"), _transmitEnablePin, _firstVpin, _firstVpin+_nPins-1,
_deviceState == DEVSTATE_FAILED ? F("OFFLINE") : F("OK"));
}
// Locate Modbusnode object with specified nodeID.
@ -373,11 +381,11 @@ public:
_nodeListEnd = newNode;
else
_nodeListEnd->setNext(newNode);
DIAG(F("bus: 260h nodeID: _nodeListStart:%d _nodeListEnd:%d"), _nodeListStart, _nodeListEnd);
//DIAG(F("Modbus: 260h nodeID:%d _nodeListStart:%d _nodeListEnd:%d"), newNode, _nodeListStart, _nodeListEnd);
}
protected:
Modbus(uint8_t busNo, HardwareSerial serial, unsigned long baud, uint16_t cycleTimeMS, int16_t transmitEnablePin);
Modbus(uint8_t busNo, HardwareSerial serial, unsigned long baud, uint16_t cycleTimeMS, int8_t transmitEnablePin);
public: