[Okta Webinar] Learn how to a build a cloud-first strategyRegister Now

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 884
  • Last Modified:

C# Invoke(new StringDelegate(OnDataReceived), new object[] { dataIn });

Why am I getting error when I lower the time to read the serial port?
public void OnDataReceived(string dataIn)
        {
            //Handle multi-threading
            if (InvokeRequired)
            {
                Invoke(new StringDelegate(OnDataReceived), new object[] { dataIn });
                return;
            }

            // pause scrolling to speed up output of multiple lines
            bool saveScrolling = scrolling;
            scrolling = false;

            // if we detect a line terminator, add line to output
            int index;
            while (dataIn.Length > 0 &&
                ((index = dataIn.IndexOf("\r")) != -1 ||
                (index = dataIn.IndexOf("\n")) != -1))
            {
                String StringIn = dataIn.Substring(0, index);
                dataIn = dataIn.Remove(0, index + 1);

                logFile_writeLine(AddData(StringIn).Str);
                logFile_writeLine1(AddData(StringIn).Str);
                //listBox3.Items.Add(AddData(StringIn).Str);
                partialLine = null;	// terminate partial line
            }

            // if we have data remaining, add a partial line
            if (dataIn.Length > 0)
            {
                partialLine = AddData(dataIn);
            }

            // restore scrolling
            scrolling = saveScrolling;
            outputList_Scroll();
            listBox1_Scroll();
        }

Open in new window

0
ocaccy
Asked:
ocaccy
  • 6
  • 2
3 Solutions
 
AndyAinscowCommented:
Letting us know what error you are getting could help.
0
 
ocaccyAuthor Commented:
I have 6 devices connected to the PC via a converter RS485/USB.
From 10 to 10 seconds, sending the commands:
XX or YY.
In the XX, sending the same command twice due to the fact that only send one time, I get no return.
My devices names is id01, id02, id03, id04, id05, id06.
In the YY, sending the command only one time; the returns is id01......, id03......, id05.......
I know has a mistake in the Thread.Sleep () after the  com.send, i need fix this too.
The error Lenght happens if I reduce the time of Thread.Sleep.
How to send only one time the command, wait the return, if the returns is OK, send the next command.
Like this: ZZ
XX
private void button33_Click(object sender, EventArgs e)
        {
            timer3.Enabled = true;
            inicio = DateTime.Now;
            #region TRABALHA ID01
            timr_ID06.Enabled = true;
            Thread.Sleep(150); // Dorme por 150 segundos
            string s_ID01_c = "id01";
            CommPort com = CommPort.Instance;
            s_ID01_c = ConvertEscapeSequences(s_ID01_c); ;
            com.Send(s_ID01_c);
            Thread.Sleep(150); // Dorme por 150 segundos
            com.Send(s_ID01_c);
            #endregion

            for (int i = 0; i <= 10; i++)
                for (int j = 0; j <= 20; j++)
                { }

            #region TRABALHA ID02
            //timr_ID06.Enabled = true;
            Thread.Sleep(150); // Dorme por 150 segundos
            string s_ID02_c = "id02";
            //CommPort com = CommPort.Instance;
            s_ID02_c = ConvertEscapeSequences(s_ID02_c); ;
            com.Send(s_ID02_c);
            Thread.Sleep(150); // Dorme por 150 segundos
            com.Send(s_ID02_c);
            #endregion

            for (int i = 0; i <= 10; i++)
                for (int j = 0; j <= 20; j++)
                { }

            #region TRABALHA ID03
            //timr_ID06.Enabled = true;
            Thread.Sleep(150); // Dorme por 150 segundos
            string s_ID03_c = "id03";
            //CommPort com = CommPort.Instance;
            s_ID03_c = ConvertEscapeSequences(s_ID03_c); ;
            com.Send(s_ID03_c);
            Thread.Sleep(150); // Dorme por 150 segundos
            com.Send(s_ID03_c);
            #endregion

            for (int i = 0; i <= 10; i++)
                for (int j = 0; j <= 20; j++)
                { }

            #region TRABALHA ID04
            //timr_ID06.Enabled = true;
            Thread.Sleep(150); // Dorme por 150 segundos
            string s_ID04_c = "id04";
            //CommPort com = CommPort.Instance;
            s_ID04_c = ConvertEscapeSequences(s_ID04_c); ;
            com.Send(s_ID04_c);
            Thread.Sleep(150); // Dorme por 150 segundos
            com.Send(s_ID04_c);
            #endregion

            for (int i = 0; i <= 10; i++)
                for (int j = 0; j <= 20; j++)
                { }

            #region TRABALHA ID05
            //timr_ID06.Enabled = true;
            Thread.Sleep(150); // Dorme por 150 segundos
            string s_ID05_c = "id05";
            //CommPort com = CommPort.Instance;
            s_ID05_c = ConvertEscapeSequences(s_ID05_c); ;
            com.Send(s_ID05_c);
            Thread.Sleep(150); // Dorme por 150 segundos
            com.Send(s_ID05_c);
            #endregion

            for (int i = 0; i <= 10; i++)
                for (int j = 0; j <= 20; j++)
                { }

            #region TRABALHA ID06
            //timr_ID06.Enabled = true;
            Thread.Sleep(150); // Dorme por 150 segundos
            string s_ID06_c = "id06";
            //CommPort com = CommPort.Instance;
            s_ID06_c = ConvertEscapeSequences(s_ID06_c); ;
            com.Send(s_ID06_c);
            Thread.Sleep(150); // Dorme por 150 segundos
            com.Send(s_ID06_c);
            #endregion

            for (int i = 0; i <= 10; i++)
                for (int j = 0; j <= 20; j++)
                { }

        }

Open in new window

YY

private void button10_Click(object sender, EventArgs e)
        {
            //Thread.Sleep(150); // Dorme por 150 segundos
            timr_ID06.Enabled = true;

            a++;
            lbl_count.Text = a.ToString();
            textBox2.Clear();
            CommPort com = CommPort.Instance;

            for (int i = 0; i <= 12; i++)
            {
                //string idX = "id100";
                //if (i = 1||i=2||i=3||i=4||i=5||i=6)
                //{
                string vstr = "ID0" + i.ToString();
                vstr = ConvertEscapeSequences(vstr);
                com.Send(vstr);
                com.Send(vstr);
                //}
                // idX = ConvertEscapeSequences(idX);

                //Thread.Sleep(500);
                //com.Send(idX);

            }

        }

Open in new window

ZZ

private void button10_Click(object sender, EventArgs e)
        {
            timr_ID06.Enabled = true;

            CommPort com = CommPort.Instance;

            for (int i = 0; i <= 12; i++)
            {
                string vstr = "ID0" + i.ToString();
                vstr = ConvertEscapeSequences(vstr);
                com.Send(vstr);
                //wait the return
                
                OK, works and transfers the data to the arrays.
                NOT, com.Send(vstr)

                OK, works and transfers the data to the arrays.
                NOT, error code (); 

            }

        }

Open in new window

0
 
AndyAinscowCommented:
So, what error message do you get - or do you mean you don't get an error after all ?
0
Industry Leaders: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
ocaccyAuthor Commented:
Hi, AndyAinscow.
See the picture, please.
Error-on-receive-method.PNG
0
 
Mike TomlinsonMiddle School Assistant TeacherCommented:
What is the declaration for the delegate StringDelegate()?
0
 
ocaccyAuthor Commented:
Hi, Idle_Mind

Below is answer.
SerialPort.cs

using System;
using System.IO;
using System.IO.Ports;
using System.Collections;
using System.Threading;

namespace Termie
{
    /// <summary> CommPort class creates a singleton instance
    /// of SerialPort (System.IO.Ports) </summary>
    /// <remarks> When ready, you open the port.
    ///   <code>
    ///   CommPort com = CommPort.Instance;
    ///   com.StatusChanged += OnStatusChanged;
    ///   com.DataReceived += OnDataReceived;
    ///   com.Open();
    ///   </code>
    ///   Notice that delegates are used to handle status and data events.
    ///   When settings are changed, you close and reopen the port.
    ///   <code>
    ///   CommPort com = CommPort.Instance;
    ///   com.Close();
    ///   com.PortName = "COM4";
    ///   com.Open();
    ///   </code>
    /// </remarks>
	public sealed class CommPort
    {
        SerialPort _serialPort;
		Thread _readThread;
		volatile bool _keepReading;

        //begin Singleton pattern
        static readonly CommPort instance = new CommPort();

		// Explicit static constructor to tell C# compiler
        // not to mark type as beforefieldinit
        static CommPort()
        {
        }

        CommPort()
        {
			_serialPort = new SerialPort();
			_readThread = null;
			_keepReading = false;
		}

		public static CommPort Instance
        {
            get
            {
                return instance;
            }
        }
        //end Singleton pattern

		//begin Observer pattern
        public delegate void EventHandler(string param);
        public EventHandler StatusChanged;
        public EventHandler DataReceived;
        //end Observer pattern

		private void StartReading()
		{
			if (!_keepReading)
			{
				_keepReading = true;
				_readThread = new Thread(ReadPort);
				_readThread.Start();
			}
		}

		private void StopReading()
		{
			if (_keepReading)
			{
				_keepReading = false;
				_readThread.Join();	//block until exits
				_readThread = null;
			}
		}

		/// <summary> Get the data and pass it on. </summary>
		private void ReadPort()
		{
			while (_keepReading)
			{
				if (_serialPort.IsOpen)
				{
					byte[] readBuffer = new byte[_serialPort.ReadBufferSize + 1];
					try
					{
						int count = _serialPort.Read(readBuffer, 0, _serialPort.ReadBufferSize);
						String SerialIn = System.Text.Encoding.ASCII.GetString(readBuffer,0,count);
						DataReceived(SerialIn);
					}
					catch (TimeoutException) { }
				}
				else
				{
					TimeSpan waitTime = new TimeSpan(0, 0, 0, 0, 50);
					Thread.Sleep(waitTime);
				}
			}
		}

		/// <summary> Open the serial port with current settings. </summary>
        public void Open()
        {
			Close();

            try
            {
                _serialPort.PortName = Settings.Port.PortName;
                _serialPort.BaudRate = Settings.Port.BaudRate;
                _serialPort.Parity = Settings.Port.Parity;
                _serialPort.DataBits = Settings.Port.DataBits;
                _serialPort.StopBits = Settings.Port.StopBits;
                _serialPort.Handshake = Settings.Port.Handshake;

				// Set the read/write timeouts
				_serialPort.ReadTimeout = 50;
				_serialPort.WriteTimeout = 50;

				_serialPort.Open();
				StartReading();
			}
            catch (IOException)
            {
                StatusChanged(String.Format("{0} does not exist", Settings.Port.PortName));
            }
            catch (UnauthorizedAccessException)
            {
                StatusChanged(String.Format("{0} already in use", Settings.Port.PortName));
            }
            catch (Exception ex)
            {
                StatusChanged(String.Format("{0}", ex.ToString()));
            }

            // Update the status
            if (_serialPort.IsOpen)
            {
                string p = _serialPort.Parity.ToString().Substring(0, 1);   //First char
                string h = _serialPort.Handshake.ToString();
                if (_serialPort.Handshake == Handshake.None)
                    h = "no handshake"; // more descriptive than "None"

                StatusChanged(String.Format("{0}: {1} bps, {2}{3}{4}, {5}",
                    _serialPort.PortName, _serialPort.BaudRate,
                    _serialPort.DataBits, p, (int)_serialPort.StopBits, h));
            }
            else
            {
                StatusChanged(String.Format("{0} already in use", Settings.Port.PortName));
            }
        }

        /// <summary> Close the serial port. </summary>
        public void Close()
        {
			StopReading();
			_serialPort.Close();
            StatusChanged("connection closed");
        }

        /// <summary> Get the status of the serial port. </summary>
        public bool IsOpen
        {
            get
            {
                return _serialPort.IsOpen;
            }
        }

        /// <summary> Get a list of the available ports. Already opened ports
        /// are not returend. </summary>
        public string[] GetAvailablePorts()
        {
            return SerialPort.GetPortNames();
        }

        /// <summary>Send data to the serial port after appending line ending. </summary>
        /// <param name="data">An string containing the data to send. </param>
        public void Send(string data)
        {
            if (IsOpen)
            {
                string lineEnding = "";
                switch (Settings.Option.AppendToSend)
                {
                    case Settings.Option.AppendType.AppendCR:
                        lineEnding = "\r"; break;
                    case Settings.Option.AppendType.AppendLF:
                        lineEnding = "\n"; break;
                    case Settings.Option.AppendType.AppendCRLF:
                        lineEnding = "\r\n"; break;
                }

                _serialPort.Write(data + lineEnding);
            }
        }
    }
}

Open in new window

public Form1()
        {
            InitializeComponent();

            splitContainer1.FixedPanel = FixedPanel.Panel1;
            splitContainer2.FixedPanel = FixedPanel.Panel2;

            AcceptButton = button5; //Send
            CancelButton = button4; //Close

			outputList_Initialize();

			Settings.Read();
            TopMost = Settings.Option.StayOnTop;

			// let form use multiple fonts
            origFont = Font;
            FontFamily ff = new FontFamily("Courier New");
            monoFont = new Font(ff, 8, FontStyle.Regular);
            Font = Settings.Option.MonoFont ? monoFont : origFont;

            CommPort com = CommPort.Instance;
            com.StatusChanged += OnStatusChanged;
            com.DataReceived += OnDataReceived;
            com.Open();
		}

Open in new window

0
 
ocaccyAuthor Commented:
Hi, AndyAinscow.

I will capture the screen and send you.
0
 
ocaccyAuthor Commented:
We had a problem of not receiving data, and receive duplicate data from the serial port with 6 devices RS485/USB, connected to the pc by a converter USB/RS485.

We solve the problem.

I used the code below.

Best Regards,
ocaccy.
// timer-10 interval= 10000ms
// timer-01 interval= 200ms
// timer-02 interval= 200ms
// timer-03 interval= 200ms
// timer-04 interval= 200ms
// timer-05 interval= 200ms
// timer-06 interval= 200ms

 private void GetData_Click(object sender, EventArgs e)
        {
            timer_10.Enabled = true;
        }

 private void timer_10_Tick(object sender, EventArgs e)
        {
            timer_01.Enabled = true;
        }


#region timer_01_Tick 
private void timer_01_Tick(object sender, EventArgs e)
        {
            #region WORKING ID01
            this.dataReceived = false;
            send_t = 0;
            free1.Enabled = true;
            #endregion
        }

private void free1_Tick(object sender, EventArgs e)
       {
            if (send_t == 3)
            {
                this.dataReceived = true;
            }
            if (this.dataReceived == false)
            {
                string s_ID01_c = "id01";
                CommPort com = CommPort.Instance;
                s_ID01_c = ConvertEscapeSequences(s_ID01_c);
                com.Send(s_ID01_c);
                send_t = send_t + 1;

            }
            else
            {
                free1.Enabled = false;
                timer_02.Enabled = true;
                timer_01.Enabled = false;
            }
        }
        #endregion

// After ends 01, chage to 02, to 03...........

Open in new window

0
 
ocaccyAuthor Commented:
This problem is solved!

Ignoring all the details of communication with the serial port, threw several questions that had the same answer.
Thanks for the help.
Ocaccy
0

Featured Post

Industry Leaders: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

  • 6
  • 2
Tackle projects and never again get stuck behind a technical roadblock.
Join Now