Ho un'applicazione che legge hardware diverso tramite rs232. È stato testato e funzionava perfettamente. Per l'applicazione finale avevo bisogno di introdurre un cavo di pochi metri, il che significa che ho convertitori RS485.Timeout della comunicazione seriale su timeout cavo lungo
Quando si esegue la mia applicazione per leggere l'hardware, viene visualizzato un errore di timeout per System.IO.Ports.SerialStream.Read. Ho aumentato il timeout a 20 sec purtroppo non ha risolto il problema
Ho provato diverse applicazioni per leggere l'hardware e hanno funzionato anche con 1 sec di frequenza di lettura.
La comunicazione utilizza il protocollo Modbus, che nella fase attuale presumo sia irrilevante in quanto non arrivo allo stadio per ricevere nulla.
Il mio codice sembra che: prima l'apertura della porta seriale e l'inizializzazione:
//get the right modbus data structure element
ModBus MB = (ModBus)s[0].sensorData;
//set up the serial port regarding the data structure's data
SerialPort sp = new SerialPort();
sp.PortName = MB.portName;
sp.BaudRate = Convert.ToInt32(MB.baudRate);
sp.DataBits = MB.dataBits;
sp.Parity = MB.parity;
sp.StopBits = MB.stopBits;
//Set time outs 20 sec for now
sp.ReadTimeout = 20000;
sp.WriteTimeout = 20000;
// aggiungete la porta a un elenco a cui si accede dal lettore portList.Add (sp); sp.Open();
Leggi hardware:
//get the right port for com
SerialPort sp = getRightPort();
ModBus MB = getRightModBusStructureelement();
try
{
//Clear in/out buffers:
sp.DiscardOutBuffer();
sp.DiscardInBuffer();
//create modbus read message
byte[] message = createReadModBusMessage();
try
{
sp.Write(message, 0, message.Length);
// FM.writeErrorLog output included for easier debug
FM.writeErrorLog(DateTime.Now + ": ModBus Message Sent");
FM.writeErrorLog(DateTime.Now + ": Read TimeOut = " + sp.ReadTimeout + " Write TimeOut = " + sp.WriteTimeout);
int offset = 0, bytesRead;
int bytesExpected = response.Length;
FM.writeErrorLog(DateTime.Now + ": start read");
while (bytesExpected > 0 && (bytesRead = sp.Read(response, offset, bytesExpected)) > 0)
{
FM.writeErrorLog(DateTime.Now + ": read - " + offset);
offset += bytesRead;
bytesExpected -= bytesRead;
}
}
catch (Exception err)
{
Console.WriteLine("ERROR Modbus Message to serial port ModBus: " + err);
FM.writeErrorLog(DateTime.Now + " - " + "ERROR Modbus Message to serial port ModBus: " + err);
}
}
Dopo aver provato l'applicazione ho ottenuto il seguente uscita dal ErroLog.txt:
14/01/2016 17:18:17: ModBus Message Sent
14/01/2016 17:18:17: Read TimeOut = 20000 Write TimeOut = 20000
14/01/2016 17:18:18: start read
14/01/2016 17:18:38 - ERROR Modbus Message to serial port ModBus: System.TimeoutException: The operation has timed out.
at System.IO.Ports.SerialStream.Read(Byte[] array, Int32 offset, Int32 count, Int32 timeout)
at System.IO.Ports.SerialStream.Read(Byte[] array, Int32 offset, Int32 count)
at System.IO.Ports.SerialPort.Read(Byte[] buffer, Int32 offset, Int32 count)
at ProbReader.SensorReader.modbusReading(List`1 mm, Int32 spCounter)
14/01/2016 17:18:38: 0
14/01/2016 17:18:38: 0
ho aumentato il timeout per 60sec ogni evenienza, ma lo stesso errore:
15/01/2016 11:11:51: ModBus Message Sent
15/01/2016 11:11:51: Read TimeOut = 60000 Write TimeOut = 60000
15/01/2016 11:11:51: start read
15/01/2016 11:12:51 - ERROR Modbus Message to serial port ModBus: System.TimeoutException: The operation has timed out.
at System.IO.Ports.SerialStream.Read(Byte[] array, Int32 offset, Int32 count, Int32 timeout)
at System.IO.Ports.SerialStream.Read(Byte[] array, Int32 offset, Int32 count)
at System.IO.Ports.SerialPort.Read(Byte[] buffer, Int32 offset, Int32 count)
at ProbReader.SensorReader.modbusReading(List`1 mm, Int32 spCounter)
15/01/2016 11:12:51: 0
15/01/2016 11:12:51: 0
Ho provato alcuni modi diversi di leggere la porta seriale, penso che il metodo attuale sembra il migliore che è il ciclo while nel mio codice di lettura.
Non ho incluso il resto del mio codice come prima e penso che sia irrilevante.
Non vedo alcuna prova di controllo del flusso hardware come RTS/CTS. Sarebbe stata la mia prima scelta anche prima di un controllo del flusso del software che sospetto non sia affidabile nella tua situazione attuale – MickyD
Inoltre, il tuo codice precedente non mostra in realtà _what values_ che stai usando per _parity; bit di dati; baud; fermare i bit; _ e così via. Qualche possibilità di scaricare i valori in 'MB'? – MickyD
Hai mai pensato di utilizzare un convertitore da COM a IP? Quindi potresti ricevere i tuoi dati attraverso una presa TCP e potresti gestire una lunga distanza. – etalon11