mirror of
https://github.com/DCC-EX/CommandStation-EX.git
synced 2025-01-11 21:31:02 +01:00
Remove blocking behaviour?
This commit is contained in:
parent
9e5b864055
commit
a85fa6d9c2
@ -222,9 +222,17 @@ void ModbusRTUComm::setTimeout(unsigned long timeout) {
|
|||||||
ModbusRTUCommError ModbusRTUComm::readAdu(ModbusADU& adu) {
|
ModbusRTUCommError ModbusRTUComm::readAdu(ModbusADU& adu) {
|
||||||
adu.setRtuLen(0);
|
adu.setRtuLen(0);
|
||||||
unsigned long startMillis = millis();
|
unsigned long startMillis = millis();
|
||||||
while (!_serial.available()) {
|
if (!_serial.available()) {
|
||||||
if (millis() - startMillis >= _readTimeout) return MODBUS_RTU_COMM_TIMEOUT;
|
//if (millis() - startMillis >= _readTimeout) return MODBUS_RTU_COMM_TIMEOUT;
|
||||||
|
_waiting_for_read = true;
|
||||||
|
if (millis() - startMillis >= _readTimeout) {
|
||||||
|
return MODBUS_RTU_COMM_TIMEOUT;
|
||||||
|
} else {
|
||||||
|
return MODBUS_RTU_COMM_WAITING;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
_waiting_for_read = false;
|
||||||
uint16_t len = 0;
|
uint16_t len = 0;
|
||||||
unsigned long startMicros = micros();
|
unsigned long startMicros = micros();
|
||||||
do {
|
do {
|
||||||
@ -323,7 +331,7 @@ ModbusRTUMasterError Modbus::writeMultipleCoils(uint8_t id, uint16_t startAddres
|
|||||||
bitClear(adu.data[5 + (i >> 3)], i & 7);
|
bitClear(adu.data[5 + (i >> 3)], i & 7);
|
||||||
}
|
}
|
||||||
adu.setDataLen(5 + byteCount);
|
adu.setDataLen(5 + byteCount);
|
||||||
_rtuComm.writeAdu(adu);
|
if (_rtuComm._waiting_for_read == false) _rtuComm.writeAdu(adu);
|
||||||
if (id == 0) return MODBUS_RTU_MASTER_SUCCESS;
|
if (id == 0) return MODBUS_RTU_MASTER_SUCCESS;
|
||||||
ModbusRTUCommError commError = _rtuComm.readAdu(adu);
|
ModbusRTUCommError commError = _rtuComm.readAdu(adu);
|
||||||
if (commError) return _translateCommError(commError);
|
if (commError) return _translateCommError(commError);
|
||||||
@ -355,7 +363,7 @@ ModbusRTUMasterError Modbus::writeMultipleHoldingRegisters(uint8_t id, uint16_t
|
|||||||
adu.setDataRegister(5 + (i * 2), buf[i]);
|
adu.setDataRegister(5 + (i * 2), buf[i]);
|
||||||
}
|
}
|
||||||
adu.setDataLen(5 + byteCount);
|
adu.setDataLen(5 + byteCount);
|
||||||
_rtuComm.writeAdu(adu);
|
if (_rtuComm._waiting_for_read == false) _rtuComm.writeAdu(adu);
|
||||||
if (id == 0) return MODBUS_RTU_MASTER_SUCCESS;
|
if (id == 0) return MODBUS_RTU_MASTER_SUCCESS;
|
||||||
ModbusRTUCommError commError = _rtuComm.readAdu(adu);
|
ModbusRTUCommError commError = _rtuComm.readAdu(adu);
|
||||||
if (commError) return _translateCommError(commError);
|
if (commError) return _translateCommError(commError);
|
||||||
@ -389,7 +397,7 @@ ModbusRTUMasterError Modbus::_readValues(uint8_t id, uint8_t functionCode, uint1
|
|||||||
adu.setDataRegister(0, startAddress);
|
adu.setDataRegister(0, startAddress);
|
||||||
adu.setDataRegister(2, quantity);
|
adu.setDataRegister(2, quantity);
|
||||||
adu.setDataLen(4);
|
adu.setDataLen(4);
|
||||||
_rtuComm.writeAdu(adu);
|
if (_rtuComm._waiting_for_read == false) _rtuComm.writeAdu(adu);
|
||||||
ModbusRTUCommError commError = _rtuComm.readAdu(adu);
|
ModbusRTUCommError commError = _rtuComm.readAdu(adu);
|
||||||
if (commError) return _translateCommError(commError);
|
if (commError) return _translateCommError(commError);
|
||||||
if (adu.getUnitId() != id) return MODBUS_RTU_MASTER_UNEXPECTED_ID;
|
if (adu.getUnitId() != id) return MODBUS_RTU_MASTER_UNEXPECTED_ID;
|
||||||
@ -417,7 +425,7 @@ ModbusRTUMasterError Modbus::_readValues(uint8_t id, uint8_t functionCode, uint1
|
|||||||
adu.setDataRegister(0, startAddress);
|
adu.setDataRegister(0, startAddress);
|
||||||
adu.setDataRegister(2, quantity);
|
adu.setDataRegister(2, quantity);
|
||||||
adu.setDataLen(4);
|
adu.setDataLen(4);
|
||||||
_rtuComm.writeAdu(adu);
|
if (_rtuComm._waiting_for_read == false) _rtuComm.writeAdu(adu);
|
||||||
ModbusRTUCommError commError = _rtuComm.readAdu(adu);
|
ModbusRTUCommError commError = _rtuComm.readAdu(adu);
|
||||||
if (commError) return _translateCommError(commError);
|
if (commError) return _translateCommError(commError);
|
||||||
if (adu.getUnitId() != id) return MODBUS_RTU_MASTER_UNEXPECTED_ID;
|
if (adu.getUnitId() != id) return MODBUS_RTU_MASTER_UNEXPECTED_ID;
|
||||||
@ -443,7 +451,7 @@ ModbusRTUMasterError Modbus::_writeSingleValue(uint8_t id, uint8_t functionCode,
|
|||||||
adu.setDataRegister(0, address);
|
adu.setDataRegister(0, address);
|
||||||
adu.setDataRegister(2, value);
|
adu.setDataRegister(2, value);
|
||||||
adu.setDataLen(4);
|
adu.setDataLen(4);
|
||||||
_rtuComm.writeAdu(adu);
|
if (_rtuComm._waiting_for_read == false) _rtuComm.writeAdu(adu);
|
||||||
if (id == 0) return MODBUS_RTU_MASTER_SUCCESS;
|
if (id == 0) return MODBUS_RTU_MASTER_SUCCESS;
|
||||||
ModbusRTUCommError commError = _rtuComm.readAdu(adu);
|
ModbusRTUCommError commError = _rtuComm.readAdu(adu);
|
||||||
if (commError) return _translateCommError(commError);
|
if (commError) return _translateCommError(commError);
|
||||||
@ -471,6 +479,8 @@ ModbusRTUMasterError Modbus::_translateCommError(ModbusRTUCommError commError) {
|
|||||||
return MODBUS_RTU_MASTER_FRAME_ERROR;
|
return MODBUS_RTU_MASTER_FRAME_ERROR;
|
||||||
case MODBUS_RTU_COMM_CRC_ERROR:
|
case MODBUS_RTU_COMM_CRC_ERROR:
|
||||||
return MODBUS_RTU_MASTER_CRC_ERROR;
|
return MODBUS_RTU_MASTER_CRC_ERROR;
|
||||||
|
case MODBUS_RTU_COMM_WAITING:
|
||||||
|
return MODBUS_RTU_MASTER_WAITING;
|
||||||
default:
|
default:
|
||||||
return MODBUS_RTU_MASTER_UNKNOWN_COMM_ERROR;
|
return MODBUS_RTU_MASTER_UNKNOWN_COMM_ERROR;
|
||||||
}
|
}
|
||||||
@ -521,31 +531,36 @@ void Modbus::_loop(unsigned long currentMicros) {
|
|||||||
#endif
|
#endif
|
||||||
uint8_t error;
|
uint8_t error;
|
||||||
// send reads and writes, DIAG on errors other than 0 (Success), or 3 (Invalid Quantity)
|
// 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());
|
switch (_operationCount) {
|
||||||
if (error != 0 && error != 3) DIAG(F("ModbusHR: T%d F%d N%d %s"), _currentNode->getNodeID(), 0, _currentNode->getNumHoldingRegisters(), errorStrings[error]);
|
case 0:
|
||||||
#ifdef DIAG_IO
|
error = writeMultipleHoldingRegisters(_currentNode->getNodeID(), 0, (uint16_t*) _currentNode->holdingRegisters, _currentNode->getNumHoldingRegisters());
|
||||||
if (error == 0) DIAG(F("ModbusHR: T%d Success!"), _currentNode->getNodeID());
|
if (error != 0 && error != 3) DIAG(F("ModbusHR: T%d F%d N%d %s"), _currentNode->getNodeID(), 0, _currentNode->getNumHoldingRegisters(), errorStrings[error]);
|
||||||
#endif
|
if (error != 0 && error != 3) flagOK = false;
|
||||||
if (error != 0 && error != 3) flagOK = false;
|
break;
|
||||||
error = writeMultipleCoils(_currentNode->getNodeID(), 0, (int*) _currentNode->coils, _currentNode->getNumCoils());
|
case 1:
|
||||||
if (error != 0 && error != 3) DIAG(F("ModbusMC: T%d F%d N%d %s"), _currentNode->getNodeID(), 0, _currentNode->getNumCoils(), errorStrings[error]);
|
error = writeMultipleCoils(_currentNode->getNodeID(), 0, (int*) _currentNode->coils, _currentNode->getNumCoils());
|
||||||
#ifdef DIAG_IO
|
if (error != 0 && error != 3) DIAG(F("ModbusMC: T%d F%d N%d %s"), _currentNode->getNodeID(), 0, _currentNode->getNumCoils(), errorStrings[error]);
|
||||||
if (error == 0) DIAG(F("ModbusMC: T%d Success!"), _currentNode->getNodeID());
|
if (error != 0 && error != 3) flagOK = false;
|
||||||
#endif
|
break;
|
||||||
if (error != 0 && error != 3) flagOK = false;
|
case 2:
|
||||||
error = readDiscreteInputs(_currentNode->getNodeID(), 0, (int*) _currentNode->discreteInputs, _currentNode->getNumDiscreteInputs());
|
error = readDiscreteInputs(_currentNode->getNodeID(), 0, (int*) _currentNode->discreteInputs, _currentNode->getNumDiscreteInputs());
|
||||||
if (error != 0 && error != 3) 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 && error != 3) flagOK = false;
|
||||||
if (error == 0) DIAG(F("ModbusDI: T%d Success!"), _currentNode->getNodeID());
|
break;
|
||||||
#endif
|
case 3:
|
||||||
if (error != 0 && error != 3) flagOK = false;
|
error = readInputRegisters(_currentNode->getNodeID(), 0, (uint16_t*) _currentNode->inputRegisters, _currentNode->getNumInputRegisters());
|
||||||
error = readInputRegisters(_currentNode->getNodeID(), 0, (uint16_t*) _currentNode->inputRegisters, _currentNode->getNumInputRegisters());
|
if (error != 0 && error != 3) 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]);
|
if (error != 0 && error != 3) flagOK = false;
|
||||||
#ifdef DIAG_IO
|
break;
|
||||||
if (error == 0) DIAG(F("ModbusIR: T%d Success!"), _currentNode->getNodeID());
|
}
|
||||||
#endif
|
if (error != MODBUS_RTU_MASTER_WAITING) {
|
||||||
if (error != 0 && error != 3) flagOK = false;
|
if (_operationCount < 3) {
|
||||||
|
_operationCount++;
|
||||||
|
} else {
|
||||||
|
_operationCount = 0;
|
||||||
|
_currentNode = _currentNode->getNext();
|
||||||
|
}
|
||||||
|
}
|
||||||
#if defined(MODBUS_STM_OK)
|
#if defined(MODBUS_STM_OK)
|
||||||
if (flagOK == true) {
|
if (flagOK == true) {
|
||||||
ArduinoPins::fastWriteDigital(MODBUS_STM_OK,HIGH);
|
ArduinoPins::fastWriteDigital(MODBUS_STM_OK,HIGH);
|
||||||
@ -563,7 +578,7 @@ void Modbus::_loop(unsigned long currentMicros) {
|
|||||||
#if defined(MODBUS_STM_COMM)
|
#if defined(MODBUS_STM_COMM)
|
||||||
ArduinoPins::fastWriteDigital(MODBUS_STM_COMM,LOW);
|
ArduinoPins::fastWriteDigital(MODBUS_STM_COMM,LOW);
|
||||||
#endif
|
#endif
|
||||||
_currentNode = _currentNode->getNext();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Link to chain of Modbus instances
|
// Link to chain of Modbus instances
|
||||||
|
@ -102,7 +102,8 @@ enum ModbusRTUCommError : uint8_t {
|
|||||||
MODBUS_RTU_COMM_SUCCESS = 0,
|
MODBUS_RTU_COMM_SUCCESS = 0,
|
||||||
MODBUS_RTU_COMM_TIMEOUT = 1,
|
MODBUS_RTU_COMM_TIMEOUT = 1,
|
||||||
MODBUS_RTU_COMM_FRAME_ERROR = 2,
|
MODBUS_RTU_COMM_FRAME_ERROR = 2,
|
||||||
MODBUS_RTU_COMM_CRC_ERROR = 3
|
MODBUS_RTU_COMM_CRC_ERROR = 3,
|
||||||
|
MODBUS_RTU_COMM_WAITING = 4
|
||||||
};
|
};
|
||||||
|
|
||||||
class ModbusRTUComm {
|
class ModbusRTUComm {
|
||||||
@ -111,6 +112,7 @@ class ModbusRTUComm {
|
|||||||
void begin(unsigned long baud, uint32_t config = SERIAL_8N1);
|
void begin(unsigned long baud, uint32_t config = SERIAL_8N1);
|
||||||
void setTimeout(unsigned long timeout);
|
void setTimeout(unsigned long timeout);
|
||||||
ModbusRTUCommError readAdu(ModbusADU& adu);
|
ModbusRTUCommError readAdu(ModbusADU& adu);
|
||||||
|
bool _waiting_for_read = false;
|
||||||
void writeAdu(ModbusADU& adu);
|
void writeAdu(ModbusADU& adu);
|
||||||
void clearRxBuffer();
|
void clearRxBuffer();
|
||||||
Stream& _serial;
|
Stream& _serial;
|
||||||
@ -140,7 +142,8 @@ enum ModbusRTUMasterError : uint8_t {
|
|||||||
MODBUS_RTU_MASTER_UNEXPECTED_BYTE_COUNT = 12,
|
MODBUS_RTU_MASTER_UNEXPECTED_BYTE_COUNT = 12,
|
||||||
MODBUS_RTU_MASTER_UNEXPECTED_ADDRESS = 13,
|
MODBUS_RTU_MASTER_UNEXPECTED_ADDRESS = 13,
|
||||||
MODBUS_RTU_MASTER_UNEXPECTED_VALUE = 14,
|
MODBUS_RTU_MASTER_UNEXPECTED_VALUE = 14,
|
||||||
MODBUS_RTU_MASTER_UNEXPECTED_QUANTITY = 15
|
MODBUS_RTU_MASTER_UNEXPECTED_QUANTITY = 15,
|
||||||
|
MODBUS_RTU_MASTER_WAITING = 16
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -307,7 +310,7 @@ private:
|
|||||||
unsigned long _currentMicros; // last value of micros() from _loop function.
|
unsigned long _currentMicros; // last value of micros() from _loop function.
|
||||||
unsigned long _postDelay; // delay time after transmission before switching off transmitter (in us)
|
unsigned long _postDelay; // delay time after transmission before switching off transmitter (in us)
|
||||||
unsigned long _byteTransmitTime; // time in us for transmission of one byte
|
unsigned long _byteTransmitTime; // time in us for transmission of one byte
|
||||||
|
int _operationCount = 0;
|
||||||
static Modbus *_busList; // linked list of defined bus instances
|
static Modbus *_busList; // linked list of defined bus instances
|
||||||
ModbusRTUMasterError _readValues(uint8_t id, uint8_t functionCode, uint16_t startAddress, int buf[], uint16_t quantity);
|
ModbusRTUMasterError _readValues(uint8_t id, uint8_t functionCode, uint16_t startAddress, int buf[], uint16_t quantity);
|
||||||
ModbusRTUMasterError _readValues(uint8_t id, uint8_t functionCode, uint16_t startAddress, uint16_t buf[], uint16_t quantity);
|
ModbusRTUMasterError _readValues(uint8_t id, uint8_t functionCode, uint16_t startAddress, uint16_t buf[], uint16_t quantity);
|
||||||
|
Loading…
Reference in New Issue
Block a user