9 Replies - 525 Views - Last Post: 24 April 2014 - 06:18 AM Rate Topic: -----

#1 bunkerway@aol.com  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 5
  • Joined: 23-April 14

unable to continuously read more lines of text

Posted 23 April 2014 - 01:03 PM

This code works, but not fully
This code reads com ports, when a string is available, I check to see if it contains some keywords defined in array
If it does, i print out the string itself.

The problem i am having is that it seems to stop processing the data at some point but I do know that there are more
strings to be read. So, it does keep reading more lines of data
using System;
using System.Text;
using System.Collections.Generic;
using System.ComponentModel;
using System.Windows.Forms;
using System.IO;
using System.IO.Ports;

namespace SerialPortApplication
{
    public partial class Form1 : Form
    {
        private System.IO.Ports.SerialPort comPort = null;

        // Logger Variables
        private bool mIsValidPath = false;
        private string mLogPath = Path.Combine(Directory.GetCurrentDirectory(),    "AttLog.txt");

        private string[] mKeywords = new string[2]
        {

          "data=9000",
            "data=david"
        };

        public Form1()
        {
            InitializeComponent();
        }

        private void btn_Connect_Click(object sender, EventArgs e)
        {
            // Get the value from the numericUpDown
            string portName = "COM" + numericUpDown1.Value.ToString();

            if (this.comPort != null)
            {
                MessageBox.Show("Already Connected. Please Disconnect first");
                return;
            }

            try
            {
                this.comPort = new System.IO.Ports.SerialPort(portName, 115200);

                //set the default properties of our SerialPort Object
                this.comPort.DataBits = 8;
                this.comPort.Parity = Parity.None;
                this.comPort.StopBits = StopBits.One;
                this.comPort.Handshake = Handshake.None;
                this.comPort.ReadTimeout = 500;
                this.comPort.WriteTimeout = 500;

                //first check if the port is already open
                if (comPort.IsOpen == true)
                    comPort.Close();

                this.comPort.Open(); //now open the port
                this.comPort.DataReceived += new SerialDataReceivedEventHandler(comPort_DataReceived);
                this.comPort.ErrorReceived += new SerialErrorReceivedEventHandler(comPort_ErrorReceived);
                this.comPort.Disposed += new EventHandler(comPort_Disposed);

                //display message
                this.writeData("Succesfully Connected to Serial Port " + portName);
            }
            catch (Exception exc)
            {
                MessageBox.Show("Error Occured while Connecting to Serial Port");
                this.comPort = null;
            }
        }

        void comPort_Disposed(object sender, EventArgs e)
        {
            this.writeData("SerialPort Disposed");
        }

        void comPort_ErrorReceived(object sender, SerialErrorReceivedEventArgs e)
        {
            this.writeData("Error Occured on SerialPort - " + e.EventType.ToString());

            switch (e.EventType)
            {
                case SerialError.Frame:
                    break;
                case SerialError.Overrun:
                    break;
                case SerialError.RXOver:
                    this.comPort.DiscardInBuffer();
                    break;
                case SerialError.RXParity:
                    break;
                case SerialError.TXFull:
                    this.comPort.DiscardOutBuffer();
                    break;
                default:
                    break;
            }
        }

          //So, in this block of code, I am checking the strings to see if they contain     certain keywords, then print out the string
        void comPort_DataReceived(object sender, SerialDataReceivedEventArgs e)
        {
            lock(this)
            {
                try
                {
                    string raw_message = comPort.ReadLine();
                    //this.writeData(raw_message);

                    // If the list doesnot contain any element, show all
                    if (mKeywords.Length == 0)
                    {
                        this.writeData(raw_message);

                        // Write the data to log file
                        File.AppendAllText(this.mLogPath, raw_message);
                    }
                    else
                    {
                        foreach (string s in mKeywords)
                        {
                            if (raw_message.Contains(s))
                            {
                                // Write the data to log file
                                // File.AppendAllText(this.mLogPath, raw_message);

                                this.writeData(raw_message);
                                break;
                            }
                        }
                    }
                }
                catch (Exception ex)
                {
                    this.writeData("Exception Occured while reading the data from Serial Port");
                }
            }
        }

        void writeData(string msg)
        {
            string message1 = string.Format("\n{0:HH:mm:ss:fff}, {1}", DateTime.Now, msg);

            if (InvokeRequired)
            {
                BeginInvoke((MethodInvoker)delegate
                {
                    this.richTextBox1.AppendText(message1);
                });
            }
            else
            {
                this.richTextBox1.AppendText(message1);
            }
        }

        private void btn_Disconnect_Click(object sender, EventArgs e)
        {
            if (comPort.IsOpen)
            {
                this.comPort.DataReceived -= comPort_DataReceived;
                this.comPort.ErrorReceived -= comPort_ErrorReceived;
                this.comPort.Disposed -= comPort_Disposed;
                comPort.Dispose();
            }
            comPort = null;
        }

        private void clearLogToolStripMenuItem_Click(object sender, EventArgs e)
        {
            this.richTextBox1.Clear();
        }


        /// <summary>
        /// 
        /// </summary>
        public string LogFilePath
        {
            set
            {
                this.mLogPath = value.ToString();
                this.mIsValidPath = true;
            }
            get { return this.mLogPath; }
        }
    }
}



This post has been edited by Curtis Rutland: 23 April 2014 - 01:44 PM
Reason for edit:: removed question from code


Is This A Good Question/Topic? 0
  • +

Replies To: unable to continuously read more lines of text

#2 Skydiver  Icon User is offline

  • Code herder
  • member icon

Reputation: 3574
  • View blog
  • Posts: 11,112
  • Joined: 05-May 12

Re: unable to continuously read more lines of text

Posted 23 April 2014 - 05:27 PM

As far as I know, the data received event is not fired on a per line basis. So if you got the event fired and there were 30 lines available, it looks like you are only processing the first line.
Was This Post Helpful? 0
  • +
  • -

#3 bunkerway@aol.com  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 5
  • Joined: 23-April 14

Re: unable to continuously read more lines of text

Posted 23 April 2014 - 05:58 PM

View PostSkydiver, on 23 April 2014 - 05:27 PM, said:

As far as I know, the data received event is not fired on a per line basis. So if you got the event fired and there were 30 lines available, it looks like you are only processing the first line.


@skydiver,

I am not sure if I understand your response ,but I know that as the lines of data come out, more than 500 lines came out and were processed. I know this to be true because the example data I have in this code is on line 200 and 900, respectively.
Was This Post Helpful? 0
  • +
  • -

#4 Momerath  Icon User is offline

  • D.I.C Lover
  • member icon

Reputation: 1010
  • View blog
  • Posts: 2,444
  • Joined: 04-October 09

Re: unable to continuously read more lines of text

Posted 23 April 2014 - 06:03 PM

What he is saying is that one event may have multiple lines queued for reading. You only read up to the first 'end-of-line'. There may be more. BytesToRead will tell you how many bytes are ready for reading.
Was This Post Helpful? 0
  • +
  • -

#5 bunkerway@aol.com  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 5
  • Joined: 23-April 14

Re: unable to continuously read more lines of text

Posted 23 April 2014 - 06:53 PM

@Momerath,

Thanks for the clarification. If I may, let me offer some more info to see if that helps me understand.

Keywords: "friday", "monday" "wednesday";

Let's say that the strings coming out from the port are like this:

"Today is April 10, its Monday".
"hello everyone, today is friday".
"You must turn in your homework every wednesday".

So, the keywords are in array.

So, if incoming message.contains(keywords)
{ print incoming message...

How does it queue multiple lines for reading since the keywords might be unique for each line? Or, are you saying that it queues each line anyway as it reads before checking if it contains keywords? If it queues it, why doesn't it print them?

I am lost.

What is the solution to this dilemma?
Was This Post Helpful? 0
  • +
  • -

#6 Skydiver  Icon User is offline

  • Code herder
  • member icon

Reputation: 3574
  • View blog
  • Posts: 11,112
  • Joined: 05-May 12

Re: unable to continuously read more lines of text

Posted 23 April 2014 - 07:06 PM

The data received event has know idea about how your code works. All it knows is that data has been received and that it should let you know. So when the event fires, the data it received maybe:
Today is April 10, its Monday\n


Or:
Today is April 10, its Monday\n
hello everyone


Or:
Today is April 10, its Mon


Or:
Today is April 10, its Monday\n
hello everyone, today is friday\n
You must turn in your homework every wednesday\n



Your code assumes that you are only always getting exactly one line each time the event is fired:
Today is April 10, its Monday\n


followed by another event:
hello everyone, today is friday\n


and then another:
You must turn in your homework every wednesday\n



It currently is not setup to handle a burst of 3 lines:
Today is April 10, its Monday\n
hello everyone, today is friday\n
You must turn in your homework every wednesday\n


or a partial line:
Today is April 10, its Mon



The usual solution is to buffer all the input into a queue and process the queue as you get complete input.
Was This Post Helpful? 0
  • +
  • -

#7 bunkerway@aol.com  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 5
  • Joined: 23-April 14

Re: unable to continuously read more lines of text

Posted 23 April 2014 - 07:25 PM

Very insightful @skydiver. Can you suggest how I might go about doing this buffering? and what does a complete input look like in this case?
Was This Post Helpful? 0
  • +
  • -

#8 Momerath  Icon User is offline

  • D.I.C Lover
  • member icon

Reputation: 1010
  • View blog
  • Posts: 2,444
  • Joined: 04-October 09

Re: unable to continuously read more lines of text

Posted 24 April 2014 - 01:17 AM

Read the entire input in. Find the first occurrence of Environment.NewLine and use up to that as the first input string. Continue looking for Enviroment.NewLine until you don't find any. When you next get the event fired, add whatever you read to what was left, and repeat this process until you are done.
Was This Post Helpful? 0
  • +
  • -

#9 Skydiver  Icon User is offline

  • Code herder
  • member icon

Reputation: 3574
  • View blog
  • Posts: 11,112
  • Joined: 05-May 12

Re: unable to continuously read more lines of text

Posted 24 April 2014 - 06:07 AM

I'm on the fence whether to use a MemoryStream, and a StreamReader. It seems trivial to read the bytes from the serial port and put it into the memory stream, and then have the stream reader on top of the memory stream to return characters and lines instead of bytes. The issue is that if there is an incomplete line, the read cursor on the stream needs to be reset back and you'll have to get the stream reader to know about that reset. It maybe faster/easier to roll my own combination buffered stream and stream reader than to use the classes that come with the framework.
Was This Post Helpful? 0
  • +
  • -

#10 bunkerway@aol.com  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 5
  • Joined: 23-April 14

Re: unable to continuously read more lines of text

Posted 24 April 2014 - 06:18 AM

@skydiver, I am loving the ideas but my programming experience is very limited at this point. It seems that I will have to tear up my code already to implement that idea. no? Secondly, I've never messed with memory stream and streamReader, so no idea how they work.

View PostMomerath, on 24 April 2014 - 01:17 AM, said:

Read the entire input in. Find the first occurrence of Environment.NewLine and use up to that as the first input string. Continue looking for Enviroment.NewLine until you don't find any. When you next get the event fired, add whatever you read to what was left, and repeat this process until you are done.


Would you mind throwing example code so I can see how this is done?
Was This Post Helpful? 0
  • +
  • -

Page 1 of 1