From bac97f8e57c35f51d8d0583d060cdcef98d17158 Mon Sep 17 00:00:00 2001 From: Thomas Wiedebusch Date: Fri, 15 Jul 2022 17:18:12 +0200 Subject: [PATCH] BaseSerialPort: - Flush buffer (DiscardInBuffer) removed as some bytes are missing from time to time. The IrDA sniffer showed these on the communication line, but they are incompletely received. Assuming the DiscardInBuffer may be delayed, so the incoming data will be scrapped. IrdaTransmitProtocol: - WakeUpMessage marked and debug output --- Common/.vs/config/applicationhost.config | 2 +- .../Ports/SerialPorts/BaseSerialPort.cs | 16 ++++++--- .../TransmitProtocol/IrdaTransmitProtocol.cs | 35 +++++++++++++++---- .../Genesis/GenesisCore/GenesisMeter.cs | 4 +-- .../RequestProtocol/RequestProtocol.cs | 4 +++ ...erRegisters.csproj.CoreCompileInputs.cache | 2 +- ...ToXlsHelper.csproj.CoreCompileInputs.cache | 2 +- 7 files changed, 49 insertions(+), 16 deletions(-) diff --git a/Common/.vs/config/applicationhost.config b/Common/.vs/config/applicationhost.config index ebc79eca..1b9332b4 100644 --- a/Common/.vs/config/applicationhost.config +++ b/Common/.vs/config/applicationhost.config @@ -155,7 +155,7 @@ - + diff --git a/Common/Hardware/Interfaces/Ports/SerialPorts/BaseSerialPort.cs b/Common/Hardware/Interfaces/Ports/SerialPorts/BaseSerialPort.cs index 26741203..4c753763 100644 --- a/Common/Hardware/Interfaces/Ports/SerialPorts/BaseSerialPort.cs +++ b/Common/Hardware/Interfaces/Ports/SerialPorts/BaseSerialPort.cs @@ -409,6 +409,11 @@ namespace Xylem.Common.Hardware.Interfaces.Ports.SerialPorts /// /// - Flush buffer if received length is 0. /// + /// + /// - Flush buffer (DiscardInBuffer) removed as some bytes are missing from time to time. + /// The IrDA sniffer showed these on the communication line, but they are incompletely received. + /// Assuming the DiscardInBuffer may be delayed, so the incoming data will be scrapped. + /// private void ReadingThreadLoop() { //put the receive thread to JoinWaitSleep to avoid reading and logger output for timeout on @@ -464,7 +469,7 @@ namespace Xylem.Common.Hardware.Interfaces.Ports.SerialPorts rxByte = (Byte)_serialPort.ReadByte(); //record raw data stream for output on missing sync-byte to investigate this issue rxRawRecord.Add(rxByte); - } while ((_serialPort.BytesToRead > 0) && (PortSettingsForTransmitProtocol.ProtSyncByte != rxByte)); + } while (_serialPort.BytesToRead > 0 && PortSettingsForTransmitProtocol.ProtSyncByte != rxByte); // if syncByte has not been detected skip read loop and wait for next incoming record if (PortSettingsForTransmitProtocol.ProtSyncByte == rxByte) @@ -545,10 +550,10 @@ namespace Xylem.Common.Hardware.Interfaces.Ports.SerialPorts catch (TimeoutException) { //flush receive buffer at timeout to force task to enter JoinWaitSleep state in finally - if (_serialPort.IsOpen) - { - _serialPort.DiscardInBuffer(); - } + //if (_serialPort.IsOpen) + //{ + // _serialPort.DiscardInBuffer(); + //} _byteDataLogger.Trace($"{Ident} Read timeout({InterByteReadDelayMs}ms)"); //_byteDataLogger.Trace($"{Ident} Read timeout({PortSettingsForTransmitProtocol.ResponseTimeoutMs}ms)"); @@ -655,6 +660,7 @@ namespace Xylem.Common.Hardware.Interfaces.Ports.SerialPorts _serialPort.Write(txByteList.ToArray(), 0, txByteList.Count); + //TODO THW flush before sending NOT after // flush the buffer for MOXA, to avoid two subsequent communications assembled to one communication! _serialPort.BaseStream.Flush(); diff --git a/Common/Hardware/Interfaces/Protocols/TransmitProtocol/IrdaTransmitProtocol.cs b/Common/Hardware/Interfaces/Protocols/TransmitProtocol/IrdaTransmitProtocol.cs index 2b43630f..4ea3211c 100644 --- a/Common/Hardware/Interfaces/Protocols/TransmitProtocol/IrdaTransmitProtocol.cs +++ b/Common/Hardware/Interfaces/Protocols/TransmitProtocol/IrdaTransmitProtocol.cs @@ -13,7 +13,6 @@ namespace Xylem.Common.Hardware.Interfaces.Protocols.TransmitProtocol // Format of IrDA transmit protocol: // IrdaSyncByte|IrdaSend/ReceiveHeader|IrdaPayLoadLength|IrdaCommand/Message| // IrdaPayLoad|IrdaCrc LSB|IrdaCrc MSB - private const Byte IrdaSyncByte = 0x9B; // Encoding of IrdaSendHeader (LAT: listen after talk, LAT 10b: 500ms) @@ -25,6 +24,7 @@ namespace Xylem.Common.Hardware.Interfaces.Protocols.TransmitProtocol // Bits: 0| 1| 10| 0| 001 // standard frame|register to adapter|LAT|reserved|optical message private const Byte IrdaReceiveHeader = 0x61; + // Mask out the LAT and the reserved bit for the IrdaReceiveHeader private const Byte IrdaReceiveHeaderMask = 0xC7; @@ -34,6 +34,10 @@ namespace Xylem.Common.Hardware.Interfaces.Protocols.TransmitProtocol // data from register (water meter) to adapter (software) referred as optical message private const Byte IrdaMessage = 0x03; + // wakeup from register (water meter) to adapter (software) wakeup message length of IrDA + private static readonly Byte[] IrdaWakeupMessage = + {IrdaSyncByte, 0x41, 0x03, 0x04, 0x00, 0xFF, 0xFF, 0xED, 0x6E }; + // IrdaSyncByte|IrdaReceiveHeader|IrdaPayLoadLength|IrdaMessage|CRC LSB|CRC MSB private const Int32 IrdaProtocolFrameLength = 6; @@ -49,7 +53,7 @@ namespace Xylem.Common.Hardware.Interfaces.Protocols.TransmitProtocol //private const Int32 DefaultResponseTimeoutMs = 50; private const Int32 DefaultResponseTimeoutMs = 150; private Int32 _responseTimeoutMs = DefaultResponseTimeoutMs; - + private const UInt32 BaudRate = 115200; private readonly UInt32? _receiveBufferFlushThreshold = 1; @@ -65,7 +69,7 @@ namespace Xylem.Common.Hardware.Interfaces.Protocols.TransmitProtocol _responseTimeoutMs = DefaultResponseTimeoutMs; } /// - public IrdaTransmitProtocol(String portName) : base (portName) + public IrdaTransmitProtocol(String portName) : base(portName) { } @@ -84,6 +88,9 @@ namespace Xylem.Common.Hardware.Interfaces.Protocols.TransmitProtocol /// /// - Removed IrdaMessage identifier check as it was observed receiving a 0x03 or a 0x04 in this field. /// + /// + /// - Wakeup message detection reported to log-file. + /// public override List DecodeDataForLogicLayer(List irdaRecord) { Logger.Info($"DecodeDataForPhysicalLayer Cordonel->PC({BitConverter.ToString(irdaRecord.ToArray())})"); @@ -92,11 +99,27 @@ namespace Xylem.Common.Hardware.Interfaces.Protocols.TransmitProtocol if (irdaRecord.Count < IrdaProtocolFrameLength + irdaRecord[IrdaPayLoadLengthIndex] || irdaRecord[IrdaSyncByteIndex] != IrdaSyncByte || (irdaRecord[IrdaHeaderIndex] & IrdaReceiveHeaderMask) != (IrdaReceiveHeader & IrdaReceiveHeaderMask) - || irdaRecord[IrdaMessageIndex] != IrdaMessage ) + || irdaRecord[IrdaMessageIndex] != IrdaMessage) { - var error = new ApplicationException("Reply format from IrDA is invalid. Decoding of transmit layer failed."); + var wakeUp = true; + for (var i = 0; i < IrdaWakeupMessage.Length; i++) + { + if (irdaRecord[i] != IrdaWakeupMessage[i]) + wakeUp = false; + } + if (wakeUp) + { + var error = new ApplicationException( + "Wakeup message from IrDA received. Retry of last message required."); + Logger.Error(error.Message, error); + } + else + { + var error = new ApplicationException( + "Reply format from IrDA is invalid. Decoding of transmit layer failed."); + Logger.Error(error.Message, error); + } - Logger.Error(error.Message, error); return new List(); } diff --git a/Common/Hardware/WaterMeter/Genesis/GenesisCore/GenesisMeter.cs b/Common/Hardware/WaterMeter/Genesis/GenesisCore/GenesisMeter.cs index 46f8d867..58077e02 100644 --- a/Common/Hardware/WaterMeter/Genesis/GenesisCore/GenesisMeter.cs +++ b/Common/Hardware/WaterMeter/Genesis/GenesisCore/GenesisMeter.cs @@ -2158,7 +2158,7 @@ namespace Xylem.Common.Hardware.WaterMeter.Genesis.GenesisCore while (retryLeft > 0 && !done) { - Thread.Sleep(100); + Thread.Sleep(50); var result = WriteRegister(a.Key.GetIdent(), 1); if (!result) { @@ -2173,7 +2173,7 @@ namespace Xylem.Common.Hardware.WaterMeter.Genesis.GenesisCore } // Wait for storing - Thread.Sleep(500); + Thread.Sleep(400); if (a.Key.AppName == "SENSUSRADIO") { done = true; diff --git a/Common/Hardware/WaterMeter/Genesis/Protocols/RequestProtocol/RequestProtocol.cs b/Common/Hardware/WaterMeter/Genesis/Protocols/RequestProtocol/RequestProtocol.cs index 12e81bf4..68253cf2 100644 --- a/Common/Hardware/WaterMeter/Genesis/Protocols/RequestProtocol/RequestProtocol.cs +++ b/Common/Hardware/WaterMeter/Genesis/Protocols/RequestProtocol/RequestProtocol.cs @@ -330,6 +330,9 @@ namespace Xylem.Common.Hardware.WaterMeter.Genesis.Protocols.RequestProtocol /// /// - Avoid activation of wakeup retry if record is meanwhile acknowledged. /// + /// + /// - Additional delay before retry. + /// public override void DecodeRecord(IPortDataEventArgs data) { //the request response record covers the entire request protocol @@ -348,6 +351,7 @@ namespace Xylem.Common.Hardware.WaterMeter.Genesis.Protocols.RequestProtocol _logger.Debug($"{_ident} WakeupMessageRetry(1)"); _recordInProcess.WakeupMessageRetryCtr = 1; _recordInProcess.RetryCtr--; + Thread.Sleep(10); } } diff --git a/Common/Hardware/WaterMeter/WaterMeterCore/WaterMeterRegisters/obj/Debug/WaterMeterRegisters.csproj.CoreCompileInputs.cache b/Common/Hardware/WaterMeter/WaterMeterCore/WaterMeterRegisters/obj/Debug/WaterMeterRegisters.csproj.CoreCompileInputs.cache index b81d5f66..d8b5c8f6 100644 --- a/Common/Hardware/WaterMeter/WaterMeterCore/WaterMeterRegisters/obj/Debug/WaterMeterRegisters.csproj.CoreCompileInputs.cache +++ b/Common/Hardware/WaterMeter/WaterMeterCore/WaterMeterRegisters/obj/Debug/WaterMeterRegisters.csproj.CoreCompileInputs.cache @@ -1 +1 @@ -46bd00889699f5a20a4981a22f62b66368323855 +1a3d4919c9c702245832d925951f2b7cb72fc333 diff --git a/Common/Tools/Tools.JsonToXlsHelper/obj/Debug/Tools.JsonToXlsHelper.csproj.CoreCompileInputs.cache b/Common/Tools/Tools.JsonToXlsHelper/obj/Debug/Tools.JsonToXlsHelper.csproj.CoreCompileInputs.cache index 874b3257..0028f628 100644 --- a/Common/Tools/Tools.JsonToXlsHelper/obj/Debug/Tools.JsonToXlsHelper.csproj.CoreCompileInputs.cache +++ b/Common/Tools/Tools.JsonToXlsHelper/obj/Debug/Tools.JsonToXlsHelper.csproj.CoreCompileInputs.cache @@ -1 +1 @@ -a50e8e35fe346dde3daa1dd9af1217ba2785aa48 +f64d563def603c89cafafa61a3219ba97e1e344c