1

I am trying to communicate with Stellaris uC and i have a problem. uC is actually sending data to COM4 at baudrate: 115200 and i am able to see it in Putty.

But, when i try to read it in C# with this code, i get nothing:

public class MySerialReader : IDisposable

{ 
private SerialPort serialPort;
private Queue<byte> recievedData = new Queue<byte>();

public MySerialReader()
{
    serialPort = new SerialPort("COM4", 115200, Parity.None, 8, StopBits.One);
    serialPort.Open();
    serialPort.DataReceived += serialPort_DataReceived;
}

void serialPort_DataReceived(object s, SerialDataReceivedEventArgs e)
{
    byte[] data = new byte[serialPort.BytesToRead];
    serialPort.Read(data, 0, data.Length);
    processData();
}

void processData()
{
    // Determine if we have a "packet" in the queue
    if (recievedData.Count > 50)
    {
        var packet = Enumerable.Range(0, 50).Select(i => recievedData.Dequeue());
    }
}

public void Dispose()
{
    if (serialPort != null)
    {
        serialPort.Dispose();
    }
}
}

Serial port options are correct and the event is not triggering.

Tnx.

EDIT: This is the shorter version, but still no success.

    _serialPort = new SerialPort("COM", 115200, Parity.None, 8
        , StopBits.One);

    _serialPort.Open();

    _serialPort.DataReceived += (sender, e) =>
        {
            SerialPort sp = (SerialPort)sender;
            string indata = sp.ReadLine();
            Console.WriteLine("Data Received:");
            Console.Write(indata);        
        };

EDIT2:

    public class SerialWrapper : IDisposable
    {
    private SerialPort _port = new SerialPort();
    private BaudRate _baudRate = BaudRate.Default;

    private Queue<byte> _serialQueue = new Queue<byte>();
    private object _lock = new object();

    public SerialWrapper(string portName, BaudRate baudRate)
    {
        try
        {
            _port.PortName = portName;
            _port.BaudRate = (int)baudRate;
        }
        catch (ArgumentNullException ex)
        {
            Debug.WriteLine(ex.Message);
        }            
    }

    /// <summary>
    /// Sends byte array to COM port
    /// </summary>
    /// <param name="buffer">Buffer to send</param>
    public void Send(byte[] buffer)
    {
        if (Open() && buffer != null && buffer.GetLength(0) > 0)
        {
            Monitor.Enter(_lock);
            _port.Write(buffer, 0, buffer.GetLength(0));
            Monitor.Exit(_lock);
        }
    }

    /// <summary>
    /// Send string as message to COM port
    /// </summary>
    /// <param name="message">String message to send</param>
    public void Send(string message)
    {
        if (Open() && !String.IsNullOrWhiteSpace(message))
        {
            ASCIIEncoding encoding = new ASCIIEncoding();
            _port.Write(message);
        }
    }

    public Queue<byte> Get()
    {
        Queue<byte> buffer = new Queue<byte>();

        Monitor.Enter(_lock);

        if (_serialQueue.Count == 0)
        {
            Monitor.Exit(_lock);
            return null;
        }

        for (int i = 0; i < _serialQueue.Count; i++)
        {
            buffer.Enqueue(_serialQueue.Dequeue());
        }

        return buffer;
    }

    /// <summary>
    /// Dispose the object
    /// </summary>
    public void Dispose()
    {
        try
        {
            _port.Close();
            _port.Dispose();
        }
        catch (IOException ex)
        {
            Debug.WriteLine("Error disposing: " + _port.PortName + ". " + ex.Message);
        }
    }

    /// <summary>
    /// Open the port.
    /// </summary>
    /// <returns></returns>
    public bool Open()
    {
        if (_port.IsOpen)
        {
            return true;
        }

        try
        {
            _port.Close();
        }
        catch (IOException ex)
        {
            Debug.WriteLine("Error closing: " + _port.PortName + "." + ex.Message);
            return false;
        }

        _port.DataBits = 8;
        _port.DiscardNull = false;
        _port.DtrEnable = false;
        _port.Encoding = Encoding.ASCII;
        _port.Handshake = Handshake.None;
        _port.Parity = Parity.None;
        _port.ReadBufferSize = 16384;
        _port.ReadTimeout = -1;
        _port.RtsEnable = false;
        _port.StopBits = StopBits.One;
        _port.WriteBufferSize = 16384;            
        _port.DataReceived += _port_DataReceived;

        try
        {
            _port.Open();
        }
        catch (IOException ex)
        {
            Debug.WriteLine("Error opening: " + _port.PortName + ". " + ex.Message);
            return false;
        }


        return true;
    }

    /// <summary>
    /// Event handler 
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    private void _port_DataReceived(object sender, SerialDataReceivedEventArgs e)
    {
        Monitor.Enter(_lock);

        try
        {
            if (_port.IsOpen)
            {
                int itemsCount = _port.BytesToRead;
                if (itemsCount > 0)
                {
                    byte[] buffer = new byte[itemsCount];
                    _port.Read(buffer, 0, itemsCount);

                    _serialQueue.Clear();

                    for (int i = 0; i < itemsCount; i++)
                    {
                        _serialQueue.Enqueue(buffer[i]);
                    }

                }
            }
        }
        catch (Exception ex)
        {

        }

        Monitor.Exit(_lock);

    }


}
Bip
  • 893
  • 5
  • 14
  • 29
  • If you want to dequeue your data, it might be a good idea to ENQUEUE it first ... (You forgot to enqueue the content of the read buffer!) – igrimpe Dec 07 '12 at 13:29
  • i added new code. Despite the queue, do you know why DataReceived is not launching? – Bip Dec 07 '12 at 13:33
  • "COM"? -> "COM4" maybe? IF the second code is complete AND all settings are correct THEN the event should trigger. IF your µC does send something. – igrimpe Dec 07 '12 at 13:38
  • I've changed it, it was a typo. It's kind of strange because i don't see the part missing here :/ – Bip Dec 07 '12 at 13:49
  • Flow control settings perhaps? – Jon B Dec 07 '12 at 14:41
  • 1
    possible duplicate of [SerialPort DataReceived event not fire \[C# console application\]](http://stackoverflow.com/questions/8907490/serialport-datareceived-event-not-fire-c-console-application) – Hans Passant Dec 07 '12 at 14:47
  • uC sending newlines? Else `DataReceived` wont fired until the default buffer size is reached. – leppie Dec 07 '12 at 16:29
  • Hello everyone, again. Unfortunately, i did not manage to solve it. My uC is sending data ABCD\n\r and i can see the data in HyperTerminal/Putty, but not in Matlab/VS2010. Does anyone experienced anything similar? Tnx. in advanced – Bip Dec 17 '12 at 22:21
  • You did not heed the warning about having to take care of handshaking. Look at the duplicate question I linked again. If you did in fact change your code to take care of handshaking then you must update your snippets. – Hans Passant Dec 17 '12 at 23:10
  • I tried to add '_port.DtrEnable = true;_port.RtsEnable = true;' together with '_port.Handshake = Handshake.None;' with no result – Bip Dec 17 '12 at 23:22

1 Answers1

2

It still is not clear from your snippets whether you took care of handshaking properly. Time for a do-it-yourself approach. There's a very useful utility available from SysInternals, the PortMon tool shows you the low-level commands being set to the serial port driver.

Since you have it working with Putty, first run a Putty session. Copy and paste the PortMon trace into a text file. Now run your own program, still observing the driver commands with PortMon. You now have something to compare, focus on the differences in the traces of the Putty trace vs yours.

Reverse-engineering the difference to changes in your code can be a bit tricky, the driver commands are pretty obscure. But by all means make changes in your code and observe how that changes the driver commands to see the connection. You should thus be able to exactly duplicate the Putty configuration and make the communication work.

Hans Passant
  • 922,412
  • 146
  • 1,693
  • 2,536