Main Site Documentation

Serial port quirks


#1

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.

  1. 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(); 
  1. 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.