Note that there are some explanatory texts on larger screens.

plurals
  1. POserialport responding to EventHandler, but not ReadExisting or ReadLine?
    text
    copied!<p>i have a program that's reading from serial port in c#. i need to quickly write to a port, read from it, then close it. i cannot leave it open. i understand that serial ports read and write slowly, I've tried to set the ReadTimeout and WriteTimeout properties high, and added a thread.Sleep to try to drag the read and write times out for the devices. here's a little bit of code:</p> <p>my method to write to port:</p> <pre><code> private void CheckPorts(string testMessage) { foreach (string s in SerialPort.GetPortNames()) { portNumber = Int32.Parse(s.Remove(0, 3)); testSerial = new SerialPort(s, baudRate, Parity.None, 8, StopBits.One); if (testSerial.IsOpen) { testSerial.Close(); } testSerial.ReadTimeout = 2000; testSerial.WriteTimeout = 1000; testSerial.Open(); if (testSerial.IsOpen) { string received; testSerial.DiscardInBuffer(); try { //testSerial.DataReceived += new SerialDataReceivedEventHandler(testSerialPort_DataReceived); testSerial.Write(testMessage); System.Threading.Thread.Sleep(2000); received = testSerial.ReadExisting(); //EITHER I USE THIS OR EVENT HANDLER, NOT BOTH } catch (TimeoutException e) { testSerial.Close(); continue; } if (received.Length &gt; 0) { MessageReceived(received); } testSerial.Close(); } } } private void testSerialPort_DataReceived(object sender, SerialDataReceivedEventArgs e) { string received = testSerial.ReadExisting(); int y = received.IndexOf("\r"); while (y == -1) { received = received + testSerial.ReadExisting(); y = received.IndexOf("\r"); } if (testSerial.IsOpen) { testSerial.Close(); } } </code></pre> <p>i'm wondering, if i absolutely have to use datahandler, how do i keep the serial port open long enough to read from it, but close the serialport before the next port needs to be opened?</p> <p>see, the first method gets called a few times, and it iterates through a foreach loop, trying a message on a few ports, then trying to read a response. so, at some point i have to close the ports, or else the next time it goes through it, it doesn't work properly because the port is still open</p> <p>HERE'S MY UPDATED CODE (still not working):</p> <pre><code> private void CheckPorts(string testMessage, int baudRate) { foreach (string s in SerialPort.GetPortNames()) { var interval = 3000; // ms var timer = new System.Timers.Timer(interval); timer.Elapsed += (o, e) =&gt; { timer.Enabled = false; if (testSerial.IsOpen) testSerial.Close(); // may not be necessary with Dispose? testSerial.Dispose(); timer.Dispose(); }; portNumber = Int32.Parse(s.Remove(0, 3)); testSerial = new SerialPort(s, baudRate, Parity.None, 8, StopBits.One); testSerial.ReadTimeout = 2000; testSerial.WriteTimeout = 2000; if (testSerial.IsOpen) { testSerial.Close(); } testSerial.Open(); timer.Enabled = true; if (testSerial.IsOpen) { string received; //testSerial.DiscardInBuffer(); //autoEvent = new AutoResetEvent(false); try { // testSerial.DataReceived += new SerialDataReceivedEventHandler(testSerialPort_DataReceived); // autoEvent.Reset(); lblPortNum.Content = s; lblPortNum.Refresh(); testSerial.Write(testMessage); //System.Threading.Thread.Sleep(2000); //testSerial.NewLine = "\r\n"; byte[] rBuff = new byte[2]; int rCnt = testSerial.Read(rBuff, 0, 2); System.Text.Encoding enc = System.Text.Encoding.ASCII; received = enc.GetString(rBuff); //received = testSerial.ReadLine(); } catch (TimeoutException e) { testSerial.Close(); continue; } if (received.Length &gt; 0) { MessageReceived(received, Int16.Parse(s.Remove(0, 3))); } /* if (autoEvent.WaitOne(2000)) { // the port responded // testSerial.Close(); autoEvent.Dispose(); lblPortNum.Content = "HEY I RESPONDED"; } else { testSerial.Close(); autoEvent.Dispose(); continue; // port did not respond within 2 seconds }*/ //testSerial.Close(); } } } </code></pre> <p>UPDATED AGAIN (still not working properly)</p> <pre><code>private void CheckPorts(string testMessage, int baudRate) { foreach (string s in SerialPort.GetPortNames()) { portNumber = Int32.Parse(s.Remove(0, 3)); // MUST BE LOCAL var serialOneOfMany = new SerialPort(s, baudRate, Parity.None, 8, StopBits.One); serialOneOfMany.ReadTimeout = 2000; serialOneOfMany.WriteTimeout = 2000; if (serialOneOfMany.IsOpen) { serialOneOfMany.Close(); } // timer must be defined _after_ serialOneOfMany var interval = 3000; // ms var timer = new System.Timers.Timer(interval); timer.Elapsed += (o, e) =&gt; { timer.Enabled = false; if (serialOneOfMany.IsOpen) serialOneOfMany.Close(); // may not be necessary with Dispose? serialOneOfMany.Dispose(); timer.Dispose(); }; if (serialOneOfMany.IsOpen) { string received; try { lblPortNum.Content = s; lblPortNum.Refresh(); serialOneOfMany.Write(testMessage); byte[] rBuff = new byte[2]; int rCnt = serialOneOfMany.Read(rBuff, 0, 2); System.Text.Encoding enc = System.Text.Encoding.ASCII; received = enc.GetString(rBuff); } catch (TimeoutException e) { serialOneOfMany.Close(); continue; } if (received.Length &gt; 0) { CheckIfTheMessageMatches(received, Int16.Parse(s.Remove(0, 3))); } } } } </code></pre> <p>so with this update, it just blows through the code, i can step through the code line by line, but it doesn't stop for 3 seconds at all. if i run it without any debugging breaks, it just goes through it i a fraction of a second</p> <p>UPDATE 10-25-11</p> <pre><code> private void CheckPorts(string testMessage, int baudRate) { foreach (string s in SerialPort.GetPortNames()) { string received = ""; testSerial = new SerialPort(s,baudRate, Parity.None, 8, StopBits.One); lblStatus.Content = "Scanning..."; lblStatus.Refresh(); if (testSerial.IsOpen) { testSerial.Close(); } else { testSerial.Open(); } if (testSerial.IsOpen) { try { testSerial.NewLine = "\r"; lblPortNum.Content = s; lblPortNum.Refresh(); testSerial.WriteTimeout= 500; testSerial.ReadTimeout = 1000; testSerial.WriteLine(testMessage); System.Threading.Thread.Sleep(500); /*THIS DOESN'T WORK byte[] buffer = new byte[testSerial.BytesToRead]; int rCnt = testSerial.Read(buffer, 0, buffer.Length); received = enc.GetString(buffer);*/ //received = Convert.ToString(testSerial.BaseStream.Read(buffer, 0, (int)buffer.Length)); received = testSerial.ReadLine(); int y = received.IndexOf("\r"); while (y == -1) { received = received + testSerial.ReadExisting(); y = received.Length; } if (lblInfo.Dispatcher.Thread == Thread.CurrentThread) { CheckIfTheMessageMatches(received, s); received = received + lblInfo.Content; lblInfo.Content = received; } else { lblInfo.Dispatcher.Invoke(DispatcherPriority.Normal, new ThreadCheck(threadCheck), received); } if (testSerial.IsOpen) { testSerial.Close(); } /*I USE THIS WITH THE sPort.Read() METHOD while (rCnt &gt; 0) { if (lblInfo.Dispatcher.Thread == Thread.CurrentThread) { CheckIfTheMessageMatches(received, s); rCnt = 0; received = received + lblInfo.Content; lblInfo.Content = received; } else { lblInfo.Dispatcher.Invoke(DispatcherPriority.Normal, new ThreadCheck(threadCheck), received); } } */ if (testSerial.IsOpen) { testSerial.Close(); } } catch (TimeoutException e) { testSerial.Close(); continue; } received = null; } } lblStatus.Content = "Finished Scanning."; lblPortNum.Content = ""; } </code></pre> <p>UPDATED CODE here's some new code, still not working, dataeventhandler not even called once. i know it's getting messages because i have another program that works with the serial devices</p> <pre><code>private void CheckPorts(string testMessage, int baudRate) { foreach (string s in SerialPort.GetPortNames()) { var serialOneOfMany = new SerialPort(s, baudRate, Parity.None, 8, StopBits.One); serialOneOfMany.ReadTimeout = 700; serialOneOfMany.WriteTimeout = 100; var interval = 500; // ms var timer = new System.Timers.Timer(interval); timer.Elapsed += (o, e) =&gt; { timer.Enabled = false; if (serialOneOfMany.IsOpen) serialOneOfMany.Close(); // may not be necessary with Dispose? serialOneOfMany.Dispose(); timer.Dispose(); }; timer.Enabled = true; lblStatus.Content = "Scanning..."; lblStatus.Refresh(); if (serialOneOfMany.IsOpen) { serialOneOfMany.Close(); } else { serialOneOfMany.Open(); } if (serialOneOfMany.IsOpen) { string received; try { lblPortNum.Content = s; lblPortNum.Refresh(); serialOneOfMany.WriteLine(testMessage); System.Threading.Thread.Sleep(400); serialOneOfMany.DataReceived += new SerialDataReceivedEventHandler(testSerialPort_DataReceived); } catch (TimeoutException e) { serialOneOfMany.Close(); continue; } } } lblStatus.Content = "Finished Scanning."; lblPortNum.Content = ""; } private void testSerialPort_DataReceived(object sender, SerialDataReceivedEventArgs e) { SerialPort receivingSerial = sender as SerialPort; string received = receivingSerial.ReadExisting(); int y = received.IndexOf("\r"); while (y == -1) { received = received + receivingSerial.ReadExisting(); y = received.IndexOf("\r"); } if (lblInfo.Dispatcher.Thread == Thread.CurrentThread) { string name = receivingSerial.PortName; received = received + lblInfo.Content; lblInfo.Content = received; CheckIfTheMessageMatches(received, name); } else { lblInfo.Dispatcher.Invoke(DispatcherPriority.Normal, new ThreadCheck(threadCheck), received); } if (receivingSerial.IsOpen) { receivingSerial.Close(); } } </code></pre>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload