Console C en lecture C # de port série

Bonjour à tous, je suis nouveau ici et j’ai beaucoup entendu parler de ce site Web qui l’aide vraiment. J’espère que vous pourrez m’aider!

J’ai un programme très simple dont le seul but est de lire à partir d’un port série et de l’imprimer 2 fois sur la fenêtre de la console en C #.

Je suis en train de tourner une résistance variable sur un micro-contrôleur qui est tout

Voici ci-dessous le code

using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.IO.Ports; namespace Testing_serial_v3._0 { class Program { static void Main(ssortingng[] args) { ssortingng buff; SerialPort port = new SerialPort("COM4", 9600, Parity.None, 8, StopBits.One); port.Open(); for (int i = 0; i < 2000; i++) { buff = port.ReadLine(); Console.WriteLine(buff); //Console.ReadLine(); } } } } 

Mais il y a une chose amusante qui se passe dans ce code. Lorsque la ligne de lecture de la console est commentée, comme indiqué dans le code ci-dessus, la valeur du port change lorsque je tourne le bouton de la résistance variable. Cela signifie donc que cela fonctionne bien. Par contre, si je fais en sorte que la readline arrive après chaque valeur, je dois appuyer sur une touche pour que le port lise la valeur actuelle et même si je change le bouton et appuie à nouveau sur enter, la valeur restra la première comme si elle ne réinitialisait pas du tout?

Devez-vous inclure d’autres lignes de commande pour que le port se réinitialise?

J’espère que vous comprenez mon problème et toutes les autres questions que vous devez savoir, n’hésitez pas, j’ai vraiment besoin que ce problème soit résolu dès que possible. Merci beaucoup et salutations

Les données qui transitent par le port sont un stream – lorsque vous lisez, vous utilisez progressivement le stream. Vous ne voyez pas “la valeur la plus récente”, vous voyez “la prochaine valeur dans le stream”. Lorsque vous ajoutez la ligne de lecture, vous ajoutez un délai, ce qui signifie qu’il existe un important arriéré de données. Ce n’est pas que “ça rest pareil” … Simplement que vous n’avez pas encore lu jusqu’à la fin (et les valeurs les plus récentes).

Dans de nombreux cas, il serait préférable de traiter l’IO du réseau via un rappel asynchrone afin que la lecture des valeurs du stream ne soit pas liée à des retards comme la saisie de données humaines. Cela peut impliquer une certaine connaissance du threading, cependant.

Vous envoyez des milliers de données du micro-contrôleur au port série (avec un retard de 1 ms par exemple), ce qui rend la mémoire tampon du port série remplie des mêmes valeurs! Si vous le lisez un à un en appuyant sur la touche Entrée, vous lisez les premiers reçus …

Je pense que si vous voulez lire vos données dans l’ordinateur avec la touche “Entrée”, vous devez envoyer la date depuis le micro-contrôleur via un bouton! Cela signifie que vous définissez la valeur par résistance, appuyez sur le bouton-poussoir, le micro envoie “Un octet” à l’ordinateur. Vous appuyez sur la touche Entrée de l’ordinateur et laissez votre ordinateur lire “Un octet” du port série!

Aussi quelques modifications à votre code:

 static void Main(ssortingng[] args) { int buff; // ssortingng to int SerialPort port = new SerialPort("COM4", 9600, Parity.None, 8, StopBits.One); port.Open(); for (int i = 0; i < 2000; i++) { Console.ReadLine(); // wait for the Enter key buff = port.ReadByte(); // read a byte Console.WriteLine(buff); } } 

J'espère que cela fonctionnera pour vous! 🙂

Vous pouvez également utiliser une tâche pour la lire dans un fil séparé et l’observer là-bas, en quelque sorte ce que @Marc Gravel mentionne. Vous devez simplement attendre que la tâche soit terminée ou appuyez sur Entrée pour l’annuler manuellement. Juste un autre exemple de déchargement de la tâche sur un autre thread.

Voici un exemple:

 using System; using System.IO; using System.Text; using System.Threading; using System.Threading.Tasks; namespace ReadStreamAsyncTask { internal class Program { private static CancellationToken _cancelTaskSignal; private static byte[] _serialPortBytes; private static MemoryStream _streamOfBytesFromPort; private static CancellationTokenSource _cancelTaskSignalSource; private static void Main() { _serialPortBytes = Encoding.ASCII.GetBytes("Mimic a bunch of bytes from the serial port"); _streamOfBytesFromPort = new MemoryStream(_serialPortBytes); _streamOfBytesFromPort.Position = 0; _cancelTaskSignalSource = new CancellationTokenSource(); _cancelTaskSignal = _cancelTaskSignalSource.Token; // Used to request cancel the task if needed. var readFromSerialPort = Task.Factory.StartNew(ReadStream, _cancelTaskSignal); readFromSerialPort.Wait(3000); // wait until task is complete(or errors) OR 3 seconds Console.WriteLine("Press enter to cancel the task"); _cancelTaskSignalSource.Cancel(); Console.ReadLine(); } private static void ReadStream() { // start your loop here to read from the port and print to console Console.WriteLine("Port read task started"); int bytesToReadCount = Buffer.ByteLength(_serialPortBytes); var localBuffer = new byte[bytesToReadCount]; int bytesRead = 0; bool finishedReading = false; try { while (!finishedReading) { _cancelTaskSignal.ThrowIfCancellationRequested(); bytesRead += _streamOfBytesFromPort.Read(localBuffer, 0, bytesToReadCount); finishedReading = (bytesRead - bytesToReadCount == 0); } } catch (TaskCanceledException) { Console.WriteLine("You cancelled the task"); } Console.WriteLine(Encoding.ASCII.GetSsortingng(localBuffer)); Console.WriteLine("Done reading stream"); } } }