2

The data received from the serial port in the variable myReceivedLines (code below) displays new line for every character as opposed to line by line for every "sentence".

Is there a way to get "sentences" to appear on separate lines as opposed to character?

   //Fields
    string myReceivedLines;

    //subscriber method for the port.DataReceived Event
    private void DataReceivedHandler(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
    {
        SerialPort sp = (SerialPort)sender;
        myReceivedLines = sp.ReadExisting();
    }


    protected override void SolveInstance(IGH_DataAccess DA)
    {

        List<string> gcode = new List<string>();
        DA.GetDataList(0, gcode);
        string selectedportname = default(string);
        DA.GetData(1, ref selectedportname);
        int selectedbaudrate = default(int);
        DA.GetData(2, ref selectedbaudrate);
        bool connecttodevice = default(bool);
        DA.GetData(3, ref connecttodevice);

        SerialPort port = new SerialPort(selectedportname, selectedbaudrate, Parity.None, 8, StopBits.One); //Create the serial port
        port.DtrEnable = true;   //enables the Data Terminal Ready (DTR) signal during serial communication (Handshaking)

        port.Open();             //Open the port

        if ((port.IsOpen) && (connecttodevice == true))
        {
            port.DataReceived += new SerialDataReceivedEventHandler(DataReceivedHandler);
            DA.SetDataList(0, myReceivedLines);
        }
Arthur Mamou-Mani
  • 2,303
  • 10
  • 43
  • 69

4 Answers4

2

Assuming you input contains new line characters, use ReadLine to achieve this. Be mindful that it is a blocking call if you do not setup the proper ReadTimeout. I would set ReceivedBytesThreshold to what an average line length is expected to be and also store my lines in whatever collection fits my needs.

//Fields
List<string> myReceivedLines;

//subscriber method for the port.DataReceived Event
private void DataReceivedHandler(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
{
    SerialPort sp = (SerialPort)sender;
    while(sp.BytesToRead > 0)
    {
        try 
        {
            myReceivedLines.Add(sp.ReadLine());
        }
        catch(TimeOutException) 
        {
            break;
        }
    }
}
zeFrenchy
  • 6,541
  • 1
  • 27
  • 36
  • Thank you very much Dominique, I get a message saying: `Field myReceivedLines is never assigned to, and will always have its default value null`. I also don't get any feedback from the device anymore. – Arthur Mamou-Mani Oct 14 '12 at 18:47
  • well somewhere in there you'll need to instantiate it with `myReceivedLines = new List();` – zeFrenchy Oct 14 '12 at 20:00
  • Sorry I wrote `List myReceivedLines = new List();` instead and it works better. – Arthur Mamou-Mani Oct 14 '12 at 20:00
  • 1
    Note that if you consume the lines in realtime, maybe a `Queue` is a more appropriate collection for you. – zeFrenchy Oct 14 '12 at 20:03
  • Thanks Dominique, what does it mean to `consume the lines in realtime`? Also, the new code builds with no errors and connects to my device but I don't receive any feedback. While debugging, i get the exceptions `Systen.InvalidOperationExcpetion` and `System.TimeoutException` on the RealLine() method. Is there a good way to double check and fix this? – Arthur Mamou-Mani Oct 14 '12 at 20:07
  • Most likely your port is not open ... see http://msdn.microsoft.com/en-us/library/system.io.ports.serialport.readline.aspx – zeFrenchy Oct 14 '12 at 20:10
  • Thanks Dominique, everything seems to work though, I have added an `if (port.IsOpen)` condition and it returns positive. not sure what to do... – Arthur Mamou-Mani Oct 14 '12 at 20:44
  • Actually, it is working when I send a short line to the device :) Thank you Dominique! You deserve the bounty. – Arthur Mamou-Mani Oct 14 '12 at 20:47
  • 1
    Thank you Arthur, I hope you get your device and your program talking :) – zeFrenchy Oct 14 '12 at 21:40
  • Thank you very much! Unfortunately, I am running into additional [issues](http://stackoverflow.com/questions/12886850/sending-the-right-gcode-string-to-a-serial-port) with sending information to it... – Arthur Mamou-Mani Oct 14 '12 at 22:00
1

I would suggest that you would first check via Wireshark that the data is really sent in the format which you assume, so that you can be sure that it is no Encoding issue.
This program allows you to record the data, so that you can check it in Wireshark.

weismat
  • 7,195
  • 3
  • 43
  • 58
1

See if enabling Xon/Xoff for the handshake helps.

UPDATE:

Here is the property to adjust handshake method. DTR (RequestToSend) is the more common:

serPort.Handshake = Handshake.XOnXOff
serPort.Handshake = Handshake.RequestToSendXOnXOff
serPort.Handshake = Handshake.RequestToSend
1

Try .ReadLine() instead of .ReadExisting() this should read until it hits a new line

or you could set up a loop to add each char to the string until you find whatever you need to signify a new line since you said sentence here you could check for a period

private void DataReceivedHandler(object sender,System.IO.Ports.SerialDataReceivedEventArgs e)
{
    SerialPort sp = (SerialPort)sender;
    String s=sp.ReadExisting();
    while(s != ".")
    {
        myReceivedLines += s;
        s=sp.ReadExisting();
    }
}
RustyH
  • 473
  • 7
  • 22
  • Thanks RustyH, it says `A local variable s cannot be declared in this scope because it would give a different meaning to s, which is already used in parent or current scope to denote something else` – Arthur Mamou-Mani Oct 14 '12 at 18:53