Hi, I have posted in stackoverflow but the question was close as they deems it was duplicated.
I was given a suggestion which I still couldn't solve the issue i am facing.
I do understand the implication of Index Out of Range but I can't figure out where went wrong.
My scenario is as follow;
I have a RaspPi running windows iot core with USB-RS485 cable(FTDI-USB-RS485) communicating with multiple NXP K22 Arm MCU PCB via RS485. All works fine. I can transmit and receive both ways perfectly.
The data is being transmitted every 500ms with data packet size not more than 10 bytes.Now I am adding another RaspPi on the RS485 bus while the existing is running. I encounter the exception Index Out of Range. Must be non negative and less than the size of collection. once the app started after the serial port is initialized and run.
Debugging which I have done;
Once I have the new RaspPi running and connect to the existing Rs485 bus and set breakpoint after UInt32 bytesRead = await loadAsyncTask; the bufferarray size is 4 which the data is correct from the other RaspPi. but once I resume, it exited at catch (Exception ex) in Listen() with the Index Outof Range Exception.
the bufferarray size is smaller than ReadBufferLength which I can't understand.
Please help. Thanks.
serialPort = await SerialDevice.FromIdAsync(deviceId);
if (serialPort == null) return;
// Configure serial settings
serialPort.WriteTimeout = TimeSpan.FromMilliseconds(0);//10 //1000
serialPort.ReadTimeout = TimeSpan.FromMilliseconds(50);//100 //1000
//serialPort.BaudRate = 9600;
serialPort.BaudRate = 4800;
serialPort.Parity = SerialParity.None;
serialPort.StopBits = SerialStopBitCount.One;
serialPort.DataBits = 8;
serialPort.Handshake = SerialHandshake.None;
// Display configured settings
SerialComsDisplay.Text = "Serial port configured successfully: ";
SerialComsDisplay.Text += serialPort.BaudRate + "-";
SerialComsDisplay.Text += serialPort.DataBits + "-";
SerialComsDisplay.Text += serialPort.Parity.ToString() + "-";
SerialComsDisplay.Text += serialPort.StopBits;
SerialComsDisplay.Text = "Waiting for data...";
// Create cancellation token object to close I/O operations when closing the device
ReadCancellationTokenSource = new CancellationTokenSource();
if (serialPort != null)
{
dataWriteObject = new DataWriter(serialPort.OutputStream);
dataReaderObject = new DataReader(serialPort.InputStream);
Listen();
}
else MainStatusDisplay.Text = "RS485 Init Failed!";
private async void Listen()
{
try
{
if (dataReaderObject != null)
{
// keep reading the serial input
while (true)
{
await ReadAsync(ReadCancellationTokenSource.Token);
}
}
}
catch (TaskCanceledException tce)
{
SerialComsDisplay.Text = "Reading task was cancelled, closing device and cleaning up";
CloseDevice();
}
catch (Exception ex)
{
SerialComsDisplay.Text = ex.Message;
}
}
private async Task ReadAsync(CancellationToken cancellationToken)
{
Task<UInt32> loadAsyncTask;
uint ReadBufferLength = 64; //1024;
// If task cancellation was requested, comply
cancellationToken.ThrowIfCancellationRequested();
// Set InputStreamOptions to complete the asynchronous read operation when one or more bytes is available
dataReaderObject.InputStreamOptions = InputStreamOptions.Partial;
using (var childCancellationTokenSource = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken))
{
// Create a task object to wait for data on the serialPort.InputStream
loadAsyncTask = dataReaderObject.LoadAsync(ReadBufferLength).AsTask(childCancellationTokenSource.Token);
// Launch the task and wait
UInt32 bytesRead = await loadAsyncTask;
if (bytesRead > 0)
{
var bufferArray = dataReaderObject.ReadBuffer(bytesRead).ToArray();
var content = string.Empty;
RxBuffer.Clear();
foreach (var b in bufferArray)
{
content += Convert.ToString(b, 16).ToUpper() + " ";
RxBuffer.Add(b);
}
SerialComsDisplay.Text = content ;
//Process data
ProcessRxData();
}
}
}