






I had a requirement of communicating on Serial Port in C#. I have tried to leverage the System.IO.Ports.SerialPort class to meet the needs. Here is the class CgSerialPort which derives from SerialPort and provides access to some custom events. Most of the time, the messages which are communicated have a header-message-footer structure. I have kept the same structure in mind while writing this class. Though, if you have a plain structure -message-, just ignore the ExpectedHeaders/ExpectedFooters part, and do not subscribe to the header/footer related events and you will be fine. The XML comments for each class/method/field/property are self explanatory. Enjoy ...
1 // No Copyright © . Use it anywhere you want.
2
3 using System;
4 using System.Collections.Generic;
5 using System.ComponentModel;
6 using System.IO;
7 using System.IO.Ports;
8 using System.Text;
9
10 namespace SerialProto
11 {
12 // *************************************************************************
13 /// <summary>
14 /// The class represents a serial port resource.
15 /// </summary>
16 /// <remarks>
17 /// <para>The serial port on a PC is a full-duplex device meaning that
18 /// it can send and receive data at the same time. In order to be able to
19 /// do this, it uses separate lines for transmitting and receiving data.
20 /// Some types of serial devices support only one-way communication, and
21 /// therefore, use only two wires in the cable - the transmit line and the
22 /// signal ground.
23 /// </para>
24 /// <para> In serial communication, a byte of data is transferred through a
25 /// single wire one bit at a time. The packets contain a start bit, data,
26 /// and stop bit. Once the start bit has been sent, the transmitter sends
27 /// the actual data bits. There may either be 5, 6, 7, or 8 data bits,
28 /// depending on the number you have selected. Both receiver and the
29 /// transmitter must agree on the number of data bits, as well as the
30 /// baud rate.
31 /// </para>
32 /// <para> A Null Modem cable simply crosses the receive and transmit lines
33 /// so that transmit on one end is connected to receive on the other end
34 /// and vice versa. In addition to transmit and receive, DTR & DSR, as well
35 /// as RTS & CTS are also crossed in a Null Modem connection.
36 /// </para>
37 /// <para>
38 /// The pin (Male RS232 DB9) looks like this on a 9 pin connection on a DTE
39 /// device:
40 /// ------------------
41 /// \ 1 2 3 4 5 /
42 /// \ 6 7 8 9 /
43 /// --------------
44 /// or in some of the pins it may be like this:
45 /// ------------------
46 /// \ 5 4 3 2 1 /
47 /// \ 9 8 7 6 /
48 /// --------------
49 /// Here is what each pin is usually meant for:
50 /// Pin # Direction of signal
51 /// 1 Carrier detect (CD)
52 /// 2 Received data (RD)
53 /// 3 Transmitted data (TD)
54 /// 4 Data terminal ready (DTR)
55 /// 5 Signal ground common reference voltage
56 /// 6 Data set ready (DSR)
57 /// 7 Request to send (RTS)
58 /// 8 Clear to send (CTS)
59 /// 9 Ring indicator (RI) (from DCE) incoming signal from modem
60 /// </para>
61 /// <para>If you do not want to use any handshake, you will use three wire
62 /// connections in which you will connect pin 2(RD) of one connector to
63 /// pin 3(TD) of the other. For both the connectors, connect pin 5 (ground)
64 /// of both the connectors with each other (common ground).If you want,
65 /// you can use only one PC as both transmitter and receiver for test
66 /// communication. Then, just take a DB 9 connector and a small wire, and
67 /// connect pin no 2 and 3 using the wire that will connect a loop back.
68 /// That is, whatever you will send, the same data you will be receiving.
69 /// </para>
70 /// <para><seealso cref="SerialPort"/></para>
71 /// <author>Authors:Praveen K. Jha</author>
72 /// </remarks>
73 public class CgSerialPort : SerialPort
74 {
75 #region events and delegates
76
77 /// <summary> Serial port message header received event.</summary>
78 [field: NonSerialized]
79 public event EventHandler<CgSerialPortEventArgs> HeaderReceived;
80 /// <summary> Serial port message footer received event.</summary>
81 [field: NonSerialized]
82 public event EventHandler<CgSerialPortEventArgs> FooterReceived;
83 /// <summary> Serial port message data received event.</summary>
84 [field: NonSerialized]
85 public event EventHandler<CgSerialPortEventArgs> MessageReceived;
86 /// <summary> Serial port header data receive error event.</summary>
87 [field: NonSerialized]
88 public event EventHandler<CgSerialPortEventArgs> HeaderRecvError;
89 /// <summary> Serial port footer data receive error event.</summary>
90 [field: NonSerialized]
91 public event EventHandler<CgSerialPortEventArgs> FooterRecvError;
92 /// <summary> Serial port message data receive error event.</summary>
93 [field: NonSerialized]
94 public event EventHandler<CgSerialPortEventArgs> MessageRecvError;
95 /// <summary> Serial port error event.</summary>
96 [field: NonSerialized]
97 public event EventHandler<CgSerialPortEventArgs> PortError;
98
99 //**********************************************************************
100 /// <summary>
101 /// Delegate for use by this class to manage data received.
102 /// </summary>
103 /// <remarks>
104 /// The delegate is set by <see cref="CgSerialPort"/> and is invoked
105 /// during the DataReceived event handling.
106 /// </remarks>
107 private delegate void DataReceivedCb();
108
109 #endregion events and delegates
110
111 #region private fields
112
113 /// <summary>The Delegate for use by this class to manage data received.
114 /// The delegate is set by <see cref="CgSerialPort"/> and is invoked
115 /// during the DataReceived event handling.</summary>
116 [NonSerialized]
117 private DataReceivedCb DataRcvdCb;
118
119 /// <summary> Read/write timeout values in milliseconds.</summary>
120 private const int TIMEOUT = 500;
121 private SerialDataReceivedEventHandler DataRcvdHandler;
122 private IList<char> m_expectedHeaders;
123 private IList<char> m_expectedFooters;
124
125 private int m_headerIndex = -1;
126 private int m_footerIndex = -1;
127 private StringBuilder m_sbHdr;
128 private StringBuilder m_sbFtr;
129
130 #endregion private fields
131
132 #region Constructors and overrides
133
134 // *********************************************************************
135 /// <summary>
136 /// Initializes a new instance of the <see cref="CgSerialPort"/> class.
137 /// </summary>
138 public CgSerialPort() : base()
139 {
140 this.Parity = Parity.Even;
141 this.ReadTimeout = TIMEOUT;
142 this.WriteTimeout = TIMEOUT;
143 }
144
145 // *********************************************************************
146 /// <summary>
147 /// Initializes a new instance of the <see cref="CgSerialPort"/> class
148 /// using the specified port name.
149 /// </summary>
150 /// <param name="portName"> The port to use (for example, COM1).</param>
151 /// <exception cref="IOException">
152 /// The specified port could not be found or opened.
153 /// </exception>
154 public CgSerialPort(string portName)
155 : base(portName)
156 {
157 this.Parity = Parity.Even;
158 }
159
160 // *********************************************************************
161 /// <summary>
162 /// Initializes a new instance of the <see cref="CgSerialPort"/> class
163 /// using the specified port name.
164 /// </summary>
165 /// <param name="portName"> The port to use (for example, COM1).</param>
166 /// <param name="baudRate">The baud rate.</param>
167 /// <exception cref="IOException">
168 /// The specified port could not be found or opened.
169 /// </exception>
170 public CgSerialPort(string portName, int baudRate)
171 : base(portName, baudRate)
172 {
173 this.Parity = Parity.Even;
174 }
175
176 // *********************************************************************
177 /// <summary>
178 /// Initializes a new instance of the <see cref="CgSerialPort"/> class
179 /// using the specified port name.
180 /// </summary>
181 /// <param name="portName"> The port to use (for example, COM1).</param>
182 /// <param name="baudRate">The baud rate.</param>
183 /// <param name="parity">One of the <see cref="SerialPort.Parity"/>
184 /// values.</param>
185 /// <exception cref="IOException">
186 /// The specified port could not be found or opened.
187 /// </exception>
188 public CgSerialPort(string portName, int baudRate, Parity parity)
189 :base(portName, baudRate, parity)
190 {
191 }
192
193 // *********************************************************************
194 /// <summary>
195 /// Initializes a new instance of the <see cref="CgSerialPort"/> class
196 /// using the specified port name.
197 /// </summary>
198 /// <param name="portName"> The port to use (for example, COM1).</param>
199 /// <param name="baudRate"> The baud rate.</param>
200 /// <param name="parity"> One of the <see cref="SerialPort.Parity"/>
201 /// <param name="dataBits"> The databits value.</param>
202 /// values.</param>
203 /// <exception cref="IOException">
204 /// The specified port could not be found or opened.
205 /// </exception>
206 public CgSerialPort(string portName, int baudRate, Parity parity,
207 int dataBits)
208 : base(portName, baudRate, parity, dataBits)
209 {
210 }
211
212 // *********************************************************************
213 /// <summary>
214 /// Initializes a new instance of the <see cref="CgSerialPort"/> class
215 /// using the specified port name.
216 /// </summary>
217 /// <param name="portName"> The port to use (for example, COM1).</param>
218 /// <param name="baudRate"> The baud rate.</param>
219 /// <param name="parity"> One of the <see cref="SerialPort.Parity"/>
220 /// <param name="dataBits"> The databits value.</param>
221 /// <param name="stopBits"> One of the <see cref="SerialPort.StopBits"/>
222 /// values.</param>
223 /// values.</param>
224 /// <exception cref="IOException">
225 /// The specified port could not be found or opened.
226 /// </exception>
227 public CgSerialPort(string portName, int baudRate, Parity parity,
228 int dataBits, StopBits stopBits)
229 : base(portName, baudRate, parity, dataBits, stopBits)
230 {
231 }
232
233 //**********************************************************************
234 /// <summary>
235 /// Releases the unmanaged resources used by this class and
236 /// optionally releases the managed resources.
237 /// </summary>
238 /// <param name="disposing"><see langword="true"/> to release both
239 /// managed and unmanaged resources; <see langword="false"/> to release
240 /// only unmanaged resources.</param>
241 protected override void Dispose(bool disposing)
242 {
243 if (disposing)
244 {
245 // Free managed objects here; set references to null.
246 }
247 // Free unmanaged objects here; set references to null.
248 base.Dispose(disposing);
249 }
250
251 #endregion Constructors and overrides
252
253 #region Utility methods and properties
254
255 // *********************************************************************
256 /// <summary>
257 /// Gets or sets the list of char values which are expected to be
258 /// received in header.
259 /// </summary>
260 /// <value> A list of char values.</value>
261 public IList<char> ExpectedHeaders
262 {
263 get { return m_expectedHeaders; }
264 set { m_expectedHeaders = value; }
265 }
266
267 // *********************************************************************
268 /// <summary>
269 /// Gets or sets the list of char values which are expected to be
270 /// received in footer.
271 /// </summary>
272 /// <value> A list of char values.</value>
273 public IList<char> ExpectedFooters
274 {
275 get { return m_expectedFooters; }
276 set { m_expectedFooters = value; }
277 }
278
279 // *********************************************************************
280 /// <summary>
281 /// Starts the serial port communication on the specified port.
282 /// </summary>
283 /// <returns> <see langword="true"/> if the serial port was opened and
284 /// started successfully; <see langword="false"/> otherwise.</returns>
285 public bool Start()
286 {
287 bool success = false;
288 try
289 {
290 this.Open();
291 DataRcvdHandler =
292 new SerialDataReceivedEventHandler(HandleDataReceived);
293 this.DataReceived += DataRcvdHandler;
294 DataRcvdCb = ReadHeader;
295 success = true;
296 }
297 catch (Exception e)
298 {
299 // Do error handling
300 OnPortError(new CgSerialPortEventArgs(e.ToString()));
301 }
302 return success;
303 }
304
305 // *********************************************************************
306 /// <summary>
307 /// Stops communicating on serial port and closes it.
308 /// </summary>
309 public void Stop()
310 {
311 this.DataReceived -= DataRcvdHandler;
312 DataRcvdCb = null;
313 this.Close();
314 }
315
316 #endregion Utility methods and properties
317
318 #region Message data receive handling
319
320 // *********************************************************************
321 /// <summary>
322 /// Handles the <see cref="SerialPort.DataReceived"/> event for serial port.
323 /// </summary>
324 /// <param name="sender">The original object who started this event.</param>
325 /// <param name="e">A <see cref="SerialDataReceivedEventArgs"/>
326 /// containing the event data.</param>
327 private void HandleDataReceived
328 (
329 object sender,
330 SerialDataReceivedEventArgs e
331 )
332 {
333 DataRcvdCb();
334 }
335
336 // *********************************************************************
337 /// <summary>
338 /// Reads the header of the message (if any).
339 /// </summary>
340 private void ReadHeader()
341 {
342 // See if we've already received header details
343 if (ExpectedHeaders != null && ExpectedHeaders.Count > 0 &&
344 m_headerIndex < ExpectedHeaders.Count - 1)
345 {
346 m_headerIndex++;
347 try
348 {
349 if (m_sbHdr == null) m_sbHdr = new StringBuilder();
350 // Read the next available header
351 string hdr = this.ReadTo(ExpectedHeaders[m_headerIndex].ToString());
352 m_sbHdr.Append(hdr);
353 if (m_headerIndex == ExpectedHeaders.Count - 1)
354 {
355 m_sbHdr.Append(((List<char>) ExpectedHeaders).ToArray());
356 DataRcvdCb = ReadMessage;
357 OnHeaderReceived(new CgSerialPortEventArgs(m_sbHdr.ToString()));
358 }
359 }
360 catch (TimeoutException)
361 {
362 // Handle timeout exception
363 OnHeaderRecvError(new CgSerialPortEventArgs(m_sbHdr.ToString()));
364 }
365 }
366 else
367 {
368 DataRcvdCb = ReadMessage;
369 ReadMessage();
370 }
371 } // end ReadHeader
372
373 // *********************************************************************
374 /// <summary>
375 /// Reads the footer of the message (if any).
376 /// </summary>
377 private void ReadFooter()
378 {
379 // See if we've already received header details
380 if (ExpectedFooters != null && ExpectedFooters.Count > 0 &&
381 m_footerIndex < ExpectedFooters.Count - 1)
382 {
383 m_footerIndex++;
384 try
385 {
386 if (m_sbFtr == null) m_sbFtr = new StringBuilder();
387 // Read the next available footer
388 string ftr = this.ReadTo(ExpectedFooters[m_footerIndex].ToString());
389 m_sbFtr.Append(ftr);
390 if (m_footerIndex == ExpectedFooters.Count - 1)
391 {
392 m_sbFtr.Append(((List<char>) ExpectedFooters).ToArray());
393 DataRcvdCb = ReadHeader;
394 OnFooterReceived(new CgSerialPortEventArgs(m_sbFtr.ToString()));
395 }
396 }
397 catch (TimeoutException)
398 {
399 // Handle timeout exception
400 OnFooterRecvError(new CgSerialPortEventArgs(m_sbFtr.ToString()));
401 }
402 }
403 else
404 {
405 DataRcvdCb = ReadHeader;
406 ReadHeader();
407 }
408 } // end ReadFooter
409
410 // *********************************************************************
411 /// <summary>
412 /// Reads the full message content.
413 /// </summary>
414 private void ReadMessage()
415 {
416 // See if we've already received header details
417 if (ExpectedFooters != null && ExpectedFooters.Count > 0)
418 {
419 string msg = string.Empty;
420 try
421 {
422 m_footerIndex = 0;
423 string ftrStart = ExpectedFooters[0].ToString();
424 // Read the message content
425 msg = this.ReadTo(ftrStart);
426 DataRcvdCb = ReadFooter;
427 OnMessageReceived(new CgSerialPortEventArgs(msg));
428 if (ExpectedFooters.Count == 1)
429 {
430 // There is only one footer character, meaning we've already
431 // received all footers
432 StringBuilder sb = new StringBuilder();
433 DataRcvdCb = ReadHeader;
434 OnFooterReceived(new CgSerialPortEventArgs(ftrStart));
435 }
436 }
437 catch (TimeoutException)
438 {
439 // Handle timeout exception
440 OnMessageRecvError(new CgSerialPortEventArgs(msg.ToString()));
441 }
442 }
443 else
444 {
445 // Nothing in footer is specified, so assume that newline is the
446 // end of message.
447 // Read the message content
448 string msg = this.ReadTo(this.NewLine);
449 DataRcvdCb = ReadFooter;
450 OnMessageReceived(new CgSerialPortEventArgs(msg));
451 }
452 } // end ReadMessage
453
454 //**********************************************************************
455 /// <summary>
456 /// Raise header received notification event for registered listeners.
457 /// </summary>
458 /// <param name="e">The <see cref="CgSerialPortEventArgs"/> instance
459 /// associated with this notification event.</param>
460 private void OnHeaderReceived(CgSerialPortEventArgs e)
461 {
462 EventHandler<CgSerialPortEventArgs> h = HeaderReceived;
463 if (h != null)
464 {
465 h(this, e);
466 }
467 m_headerIndex = -1;
468 m_sbHdr = null;
469 }
470
471 //**********************************************************************
472 /// <summary>
473 /// Raise header receive error notification event for registered listeners.
474 /// </summary>
475 /// <param name="e">The <see cref="CgSerialPortEventArgs"/> instance
476 /// associated with this notification event.</param>
477 private void OnHeaderRecvError(CgSerialPortEventArgs e)
478 {
479 EventHandler<CgSerialPortEventArgs> h = HeaderRecvError;
480 if (h != null)
481 {
482 h(this, e);
483 }
484 m_headerIndex = -1;
485 m_sbHdr = null;
486 DataRcvdCb = ReadMessage;
487 }
488
489 //**********************************************************************
490 /// <summary>
491 /// Raise footer received notification event for registered listeners.
492 /// </summary>
493 /// <param name="e">The <see cref="CgSerialPortEventArgs"/> instance
494 /// associated with this notification event.</param>
495 private void OnFooterReceived(CgSerialPortEventArgs e)
496 {
497 EventHandler<CgSerialPortEventArgs> h = FooterReceived;
498 if (h != null)
499 {
500 h(this, e);
501 }
502 m_footerIndex = -1;
503 m_sbFtr = null;
504 }
505
506 //**********************************************************************
507 /// <summary>
508 /// Raise footer receive error notification event for registered listeners.
509 /// </summary>
510 /// <param name="e">The <see cref="CgSerialPortEventArgs"/> instance
511 /// associated with this notification event.</param>
512 private void OnFooterRecvError(CgSerialPortEventArgs e)
513 {
514 EventHandler<CgSerialPortEventArgs> h = FooterRecvError;
515 if (h != null)
516 {
517 h(this, e);
518 }
519 m_footerIndex = -1;
520 m_sbFtr = null;
521 DataRcvdCb = ReadHeader;
522 }
523
524 //**********************************************************************
525 /// <summary>
526 /// Raise message received notification event for registered listeners.
527 /// </summary>
528 /// <param name="e">The <see cref="CgSerialPortEventArgs"/> instance
529 /// associated with this notification event.</param>
530 private void OnMessageReceived(CgSerialPortEventArgs e)
531 {
532 EventHandler<CgSerialPortEventArgs> h = MessageReceived;
533 if (h != null)
534 {
535 h(this, e);
536 }
537 m_headerIndex = -1;
538 }
539
540 //**********************************************************************
541 /// <summary>
542 /// Raise message receive error notification event for registered listeners.
543 /// </summary>
544 /// <param name="e">The <see cref="CgSerialPortEventArgs"/> instance
545 /// associated with this notification event.</param>
546 private void OnMessageRecvError(CgSerialPortEventArgs e)
547 {
548 EventHandler<CgSerialPortEventArgs> h = MessageRecvError;
549 if (h != null)
550 {
551 h(this, e);
552 }
553 m_headerIndex = -1;
554 m_footerIndex = -1;
555 DataRcvdCb = ReadFooter;
556 }
557
558 //**********************************************************************
559 /// <summary>
560 /// Raises port open errors to registered listeners.
561 /// </summary>
562 /// <param name="e">The <see cref="CgSerialPortEventArgs"/> instance
563 /// associated with this notification event.</param>
564 private void OnPortError(CgSerialPortEventArgs e)
565 {
566 EventHandler<CgSerialPortEventArgs> h = PortError;
567 if (h != null)
568 {
569 h(this, e);
570 }
571 }
572
573 #endregion Message data receive handling
574
575 } // end class CgSerialPort
576 } // end namespace SerialProto
The CgSerialPort class uses and EventArgs class to notify the subscribers. It just has a property which contains the message that is received (or partial/error message in case of error). And here is the code for the CgSerialPortEventArgs:
577 // No Copyright © . Use it anywhere you want.
578
579 using System;
580
581 namespace SerialProto
582 {
583 // *************************************************************************
584 /// <summary>
585 /// An eventargs class to cater to the <see cref="CgSerialPort"/> class needs.
586 /// </summary>
587 /// <remarks>
588 /// <para><seealso cref="System.IO.Ports.SerialPort"/></para>
589 /// <author>Authors:Praveen K. Jha</author>
590 /// </remarks>
591 public class CgSerialPortEventArgs : EventArgs
592 {
593 private string m_message;
594
595 // *********************************************************************
596 /// <summary>
597 /// Initializes a new instance of the <see cref="CgSerialPortEventArgs"/>
598 /// class.
599 /// </summary>
600 /// <param name="message"> The message that is received.</param>
601 public CgSerialPortEventArgs(string message)
602 {
603 m_message = message;
604 }
605
606 // *********************************************************************
607 /// <summary>
608 /// Gets the message associated with this eventargs.
609 /// </summary>
610 /// <value> The message string.</value>
611 public string Message
612 {
613 get { return m_message; }
614 }
615
616 } // end class CgSerialPortEventArgs
617 } // end namespace SerialProto
Finally here is the sample project file which will demonstrate the use of the above classes. Just copy paste the codes here in your project and you should be good to go.
618 using System;
619 using System.Collections.Generic;
620 using System.IO.Ports;
621
622 using SerialProto;
623
624 public class PortChat
625 {
626 static bool _continue;
627 static CgSerialPort _serialPort;
628
629 public static void Main()
630 {
631 string name;
632 string message;
633 StringComparer stringComparer = StringComparer.OrdinalIgnoreCase;
634
635 // Create a new SerialPort object with default settings.
636 _serialPort = new CgSerialPort();
637
638 // Allow the user to set the appropriate properties.
639 _serialPort.PortName = SetPortName(_serialPort.PortName);
640 _serialPort.BaudRate = SetPortBaudRate(_serialPort.BaudRate);
641 _serialPort.Parity = SetPortParity(_serialPort.Parity);
642 _serialPort.DataBits = SetPortDataBits(_serialPort.DataBits);
643 _serialPort.StopBits = SetPortStopBits(_serialPort.StopBits);
644 _serialPort.Handshake = SetPortHandshake(_serialPort.Handshake);
645
646 // Set the read/write timeouts
647 _serialPort.ReadTimeout = 500;
648 _serialPort.WriteTimeout = 500;
649
650 _serialPort.MessageReceived +=
651 new EventHandler<CgSerialPortEventArgs>(_serialPort_MessageReceived);
652 _serialPort.PortError +=
653 new EventHandler<CgSerialPortEventArgs>(_serialPort_PortError);
654 _serialPort.MessageRecvError +=
655 new EventHandler<CgSerialPortEventArgs>(_serialPort_MessageRecvError);
656
657 // Uncomment these if you have header/footer requirements
658 //_serialPort.HeaderReceived +=
659 // new EventHandler<CgSerialPortEventArgs>(_serialPort_HeaderReceived);
660 //_serialPort.FooterReceived +=
661 // new EventHandler<CgSerialPortEventArgs>(_serialPort_FooterReceived);
662 //List<char> expHdr = new List<char>();
663 //expHdr.Add('?');
664 //expHdr.Add('?');
665 //List<char> expFtr = new List<char>();
666 //expFtr.Add('?');
667 //expFtr.Add('?');
668 //_serialPort.ExpectedHeaders = expHdr;
669 //_serialPort.ExpectedFooters = expFtr;
670 //_serialPort.HeaderRecvError +=
671 // new EventHandler<CgSerialPortEventArgs>(_serialPort_HeaderRecvError);
672 //_serialPort.FooterRecvError +=
673 // new EventHandler<CgSerialPortEventArgs>(_serialPort_FooterRecvError);
674
675 if (_serialPort.Start())
676 {
677 _continue = true;
678
679 Console.Write("Name: ");
680 name = Console.ReadLine();
681
682 Console.WriteLine("Type QUIT to exit");
683
684 while (_continue)
685 {
686 message = Console.ReadLine();
687
688 if (stringComparer.Equals("quit", message))
689 {
690 _continue = false;
691 }
692 else
693 {
694 Console.WriteLine("XMIT:" + message);
695 _serialPort.WriteLine(message);
696 }
697 }
698
699 _serialPort.Stop();
700 }
701 else
702 {
703 Console.ReadLine();
704 }
705 }
706
707 static void _serialPort_MessageRecvError(object sender, CgSerialPortEventArgs e)
708 {
709 Console.WriteLine("Msg RECV error" + e.Message);
710 }
711
712 static void _serialPort_FooterRecvError(object sender, CgSerialPortEventArgs e)
713 {
714 Console.WriteLine("Ftr RECV error" + e.Message);
715 }
716
717 static void _serialPort_HeaderRecvError(object sender, CgSerialPortEventArgs e)
718 {
719 Console.WriteLine("Hdr RECV error" + e.Message);
720 }
721
722 static void _serialPort_PortError(object sender, CgSerialPortEventArgs e)
723 {
724 Console.WriteLine( e.Message);
725 }
726
727 static void _serialPort_MessageReceived(object sender, CgSerialPortEventArgs e)
728 {
729 Console.WriteLine("RECVMSG:" + e.Message);
730 }
731
732 static void _serialPort_FooterReceived(object sender, CgSerialPortEventArgs e)
733 {
734 Console.WriteLine("RECVFTR:" + e.Message);
735 }
736
737 static void _serialPort_HeaderReceived(object sender, CgSerialPortEventArgs e)
738 {
739 Console.WriteLine("RECVHDR:" + e.Message);
740 }
741
742
743 public static string SetPortName(string defaultPortName)
744 {
745 string portName;
746
747 Console.WriteLine("Available Ports:");
748 foreach (string s in SerialPort.GetPortNames())
749 {
750 Console.WriteLine(" {0}", s);
751 }
752
753 Console.Write("COM port({0}): ", defaultPortName);
754 portName = Console.ReadLine();
755
756 if (portName == "")
757 {
758 portName = defaultPortName;
759 }
760 return portName;
761 }
762
763 public static int SetPortBaudRate(int defaultPortBaudRate)
764 {
765 string baudRate;
766
767 Console.Write("Baud Rate({0}): ", defaultPortBaudRate);
768 baudRate = Console.ReadLine();
769
770 if (baudRate == "")
771 {
772 baudRate = defaultPortBaudRate.ToString();
773 }
774
775 return int.Parse(baudRate);
776 }
777
778 public static Parity SetPortParity(Parity defaultPortParity)
779 {
780 string parity;
781
782 Console.WriteLine("Available Parity options:");
783 foreach (string s in Enum.GetNames(typeof(Parity)))
784 {
785 Console.WriteLine(" {0}", s);
786 }
787
788 Console.Write("Parity({0}):", defaultPortParity.ToString());
789 parity = Console.ReadLine();
790
791 if (parity == "")
792 {
793 parity = defaultPortParity.ToString();
794 }
795
796 return (Parity) Enum.Parse(typeof(Parity), parity);
797 }
798
799 public static int SetPortDataBits(int defaultPortDataBits)
800 {
801 string dataBits;
802
803 Console.Write("Data Bits({0}): ", defaultPortDataBits);
804 dataBits = Console.ReadLine();
805
806 if (dataBits == "")
807 {
808 dataBits = defaultPortDataBits.ToString();
809 }
810
811 return int.Parse(dataBits);
812 }
813
814 public static StopBits SetPortStopBits(StopBits defaultPortStopBits)
815 {
816 string stopBits;
817
818 Console.WriteLine("Available Stop Bits options:");
819 foreach (string s in Enum.GetNames(typeof(StopBits)))
820 {
821 Console.WriteLine(" {0}", s);
822 }
823
824 Console.Write("Stop Bits({0}):", defaultPortStopBits.ToString());
825 stopBits = Console.ReadLine();
826
827 if (stopBits == "")
828 {
829 stopBits = defaultPortStopBits.ToString();
830 }
831
832 return (StopBits) Enum.Parse(typeof(StopBits), stopBits);
833 }
834
835 public static Handshake SetPortHandshake(Handshake defaultPortHandshake)
836 {
837 string handshake;
838
839 Console.WriteLine("Available Handshake options:");
840 foreach (string s in Enum.GetNames(typeof(Handshake)))
841 {
842 Console.WriteLine(" {0}", s);
843 }
844
845 Console.Write("Handshake({0}):", defaultPortHandshake.ToString());
846 handshake = Console.ReadLine();
847
848 if (handshake == "")
849 {
850 handshake = defaultPortHandshake.ToString();
851 }
852
853 return (Handshake) Enum.Parse(typeof(Handshake), handshake);
854 }
855 }
Let me know how you think the codes helped you ... :)
which compiler should I use to successfully use this code? I have MS Visual C/C++ v.1.52 for DOS and Windows. Can I use the code and make an exe file with my compiler? Or should I go and get MS Visual Studio .Net 2003 Professional?
ReplyDeletemy e-mail: gk1@onet.eu
You will need Visual studio 2005 or above to compile this code. Check http://www.microsoft.com/exPress/download/.
ReplyDeleteDear Sir,
ReplyDeleteWhich is better for this project:
Visual Studio 2005 Standard or Visual Studio 2005 Professional?
Best regards
Greg Krupinski
Greg,
ReplyDeleteYou could use any of these editions. They are equally good. VS 2005 Pro just gives you a few more options. See http://msdn.microsoft.com/en-us/vstudio/aa700921.aspx for comparison.
Thx
Dear Praveen,
ReplyDeleteDo you have any simple C/C++ program for RS232 port that could be compiled with MS VC/C++ ver.1.52 for DOS/Windows.
I prefer Microsoft, since this was my first compiler, and I still use it for simple programming under DOS and Windows 98.
There must be a way of using either simple assembler code with direct register handling, or making simple functions to control the serial ports without much of a headache.
=====================================================================================================
Have you ever tried to do it with Borland Turbo Pascal, Borland Pascal 7.0, Borland Delphi or Borland C++ 4.2 all for DOS/Win'98?
I will appreciate any suggestions from your experience.
All I need is a simple connection between the screen (DOS/Win'98)) or Windows Form(Windows XP) and the RS232 port with writing all bytes to a text datafile as long as the port is open and data is received - all written in C/C++ (MS Visual C/C++ 5.0 or MSVC/C++ 1.52)
I have bought the MS Visual Studio 2003 .Net Professional a year ago, but I could not find any SerialPort Component in it, and they told me it was included with Visual Studio 2005 Professional. So now I either use old DOS machine with good old compiler for DOS?Win'98 or I need to buy the whole MSVS 2005 Pro.
Next I will need to receive, send confirmation character (or string) to the port and then receive the next record from the serial device connected to the serial port.
I had many modules like this in the past, but they told me they were obsolete, and the old computer was scrapped.
After many years of working with ready made applications I see the need to recover old programming solutions for simple dataloggers etc. with RS232 ports.
Many old programs written with MSVC/C++ 1.52 for Windows 98 are running successfully under Windows XP, so I would very much tru to continue with the simple compiler and use it for RS232 programming (under Windows XP).
Is this possible?
Thank you for you help
Greg
Hi Greg,
ReplyDeleteI am sure, at some point I had written a small piece of code for VS 2003 when there was no serial port support in .Net. I can't find it right now. If I do, I'll send it to you or publish it on my blog. I would suggest at this time to see the following links which I think might help you:
For VS2003:
* http://msdn.microsoft.com/en-us/magazine/cc301786.aspx
* http://www.lvr.com/serport.htm
For Borland C++:
* http://www.activexperts.com/activcomport/howto/cppbuilder/
* http://www.daniweb.com/forums/thread56329.html#
* http://simpleserial.com/
Hope this helps. Good luck!
-Praveen
Unfortunate the .NET 2.0/3.4 seems to have lots of known problems with handling the serial!
ReplyDeleteI found this article:
http://www.innovatic.dk/knowledg/SerialCOM/SerialCOM.htm
Thats really sad.
Im not sure how it would work with the old WIN32 API calls and than write an wrapper class ??
Im planning to use serial-232 for a datalogger, but im not sure anymore if it can be trusted in WIN32 at all!