I just got my serial port code to work. I ran into a number of issues, so I thought I would share my experience. (and save somebody a few hours of head scratching)
(Cobra II, latest firmware & libraries, Gadgateer serial port)
My initial goal was simple: write a line to the serial port and read the response. This is just to see if the proper device was connected to the port.
-
Using the LineReceivedEventHandler causes an exception:
Exception System.InvalidOperationException - 0x00000000 (4)
Message:
System.IO.Ports.SerialPort::set_ReadTimeout [IP: 0009]
Gadgeteer.Interfaces.Serial::ReadLineProcess [IP: 0015]
This happens because the initialization (“rs232.Initialize()”? ) automatically opens the port. set_ReadTimeout can’t be called on an open port. Setting the LineReceivedEventHandler/AutoReadLineEnabled calls set_ReadTimeout. So I needed to close the port before setting up the event:
serialPort.Close(); // close automatically opened port
serialPort.AutoReadLineEnabled = true;
serialPort.LineReceivedEventDelimiter = "\r\n";
serialPort.LineReceived += new Serial.LineReceivedEventHandler(ReadLine);
serialPort.Open();
- I would write the message line to the serial port and then wait (ManualResetEvent using a WaitOne with timeout). The response never comes … until much later. (no matter how long I wait). I tried the call in both ProgramStated() and in a GT.Timer.TickEventHandler. Both of these are apparently in the same thread as the LineReceivedEventHandler, so waiting for the response blocks the line reciever. I put the send/receive on it’s own thread and it works great.
I am putting these work-arounds and a few more features into serial wrapper class and will submit to the codeshare.
[ul]string SendLine(string line) method that writes, waits for a response, and returns the response value[/ul]
[ul]int WriteInterval value that enforces a minimum delay between line writes (to prevent buffer overruns on the serial device)[/ul]
[ul]It’s own LineReceivedEventHandler that can handle lengthy processing times. Lines from the serial port are pushed onto a fifo. A thread pops these off and send them to registered event handlers. The handlers can take as long as they need without worrying about buffer overruns or blocking the ‘SendLine’ method[/ul]
[ul]debug switches that reports the timing of read & writes to monitor performance[/ul]
This made it pretty easy make a serial/tcp bridge, I’ll include that example.