C# communication serie entre une application UWP et un peripherique COM
Bonjour,
Je développe une application UWP en C# hébergée sur un raspberry PI 3 qui communique par liaison série avec une carte arduino, pour la partie com série j'utilise un bout du code fournit par Microsoft comme exemple "Serial Sample" https://developer.microsoft.com/en-u...les/serialuart
Le problème est que la carte arduino transmet en continue des informations par le port série et que cela plante la réception sur l'application une fois le buffer plein, message d'exeption "out of range".
Hors je souhaite traiter à la volé les informations transmises par la carte, je pense comprendre qu'il faut ajouter un mécanisme pour d’interrompre la lecture puis de vider le buffer et enfin de relancer la lecture.
Ci-dessous la partie du code fournit par Microsoft que j'utilise pour faire de la lecture
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89
|
private async void Listen()
{
try
{
if (serialPort != null)
{
dataReaderObject = new DataReader(serialPort.InputStream);
// keep reading the serial input
while (true)
{
await ReadAsync(ReadCancellationTokenSource.Token);
}
}
}
/*catch (TaskCanceledException tce)
{
status.Text = "Reading task was cancelled, closing device and cleaning up";
CloseDevice();
}*/
catch (Exception ex)
{
status.Text = ex.Message;
}
finally
{
/* // Cleanup once complete
if (dataReaderObject != null)
{
dataReaderObject.DetachStream();
dataReaderObject = null;
}*/
}
}
/// <summary>
/// ReadAsync: Task that waits on data and reads asynchronously from the serial device InputStream
/// </summary>
/// <param name="cancellationToken"></param>
/// <returns></returns>
public async Task ReadAsync(CancellationToken cancellationToken)
{
Task<UInt32> loadAsyncTask;
uint ReadBufferLength = 41;
// 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)
{
rcvdText.Text = dataReaderObject.ReadString(bytesRead);
string rcvd = dataReaderObject.ReadString(bytesRead);
//TRAME
//GPIOxxxxxinsidexxxxoutsidexxxxeauxxxxtensxxxxpresxxxxfin
rcvdGPIO = rcvd.Substring(rcvd.IndexOf("GPIO") + 4 , rcvd.IndexOf("inside") - (rcvd.IndexOf("GPIO") + 4));
rcvdin = rcvd.Substring(rcvd.IndexOf("inside") + 6, rcvd.IndexOf("outside") - (rcvd.IndexOf("inside") + 6));
rcvdout = rcvd.Substring(rcvd.IndexOf("outside") + 7, rcvd.IndexOf("eau") - (rcvd.IndexOf("outside") + 7));
rcvdeau = rcvd.Substring(rcvd.IndexOf("eau") + 3,rcvd.IndexOf("tens") - (rcvd.IndexOf("eau") + 3));
rcvd_tens = rcvd.Substring(rcvd.IndexOf("tens") + 4, rcvd.IndexOf("pres") - (rcvd.IndexOf("tens") + 4));
rcvd_pres = rcvd.Substring(rcvd.IndexOf("pres") + 4, rcvd.IndexOf("fin") - (rcvd.IndexOf("pres") + 4));
// GPIO();
//aff_info();
rcvdGPIO = "";
rcvdin = "";
rcvdout = "";
rcvdeau = "";
rcvd_tens = "";
rcvd_pres = "";
rcvdText.Text = "";
status.Text = "bytes read successfully!";
}
}
} |
Avez-vous une idée de comment traiter ce problème ?
Merci à tous.