none
Serial Port, send command to 10 devices RS485/USB on C#. RRS feed

  • 質問

  • Hi, 

    I have 10 devices connected to the computer through a converter RS485/USB.

    I have serial port class, SerialPort.cs

    I send the command below. AA and receive in the BB, but sometimes did not receive data or get duplicated. How to fix this? 

    I will appreciate any help.

      AA   private void button14_Click(object sender, EventArgs e)
            {
                timer3.Enabled = true;
                inicio = DateTime.Now;
    
                #region Wrk ID01
                timr_ID06.Enabled = true;
                string s_ID01_c = "id01";
                CommPort com = CommPort.Instance;
                s_ID01_c = ConvertEscapeSequences(s_ID01_c); ;
                com.Send(s_ID01_c);
                com.Send(s_ID01_c);
                #endregion
    
                #region Wrk ID02
                string s_ID02_c = "id02";
                s_ID02_c = ConvertEscapeSequences(s_ID02_c); ;
                com.Send(s_ID02_c);
                com.Send(s_ID02_c);
                #endregion
    
                #region Wrk ID03
                string s_ID03_c = "id03";
                s_ID03_c = ConvertEscapeSequences(s_ID03_c); ;
                com.Send(s_ID03_c);
                com.Send(s_ID03_c);
                #endregion
    
                #region Wrk ID04
                string s_ID04_c = "id04";
                s_ID04_c = ConvertEscapeSequences(s_ID04_c); ;
                com.Send(s_ID04_c);
                com.Send(s_ID04_c);
                #endregion
    
                #region Wrk ID05
                string s_ID05_c = "id05";
                s_ID05_c = ConvertEscapeSequences(s_ID05_c); ;
                com.Send(s_ID05_c);
                com.Send(s_ID05_c);
                #endregion
    
                #region Wrk ID06
                string s_ID06_c = "id06";
                s_ID06_c = ConvertEscapeSequences(s_ID06_c); ;
                com.Send(s_ID06_c);
                com.Send(s_ID06_c);
                #endregion
    
            }
    

     

    BB   #region Event handling - data received and status changed
    
            /// <summary>
            /// Prepare a string for output by converting non-printable characters.
            /// </summary>
            /// <param name="StringIn">input string to prepare.</param>
            /// <returns>output string.</returns>
            private String PrepareData(String StringIn)
            {
                // The names of the first 32 characters
                string[] charNames = {
                                     // "NUL", "SOH", "STX", "ETX", "EOT",
                    //"ENQ", "ACK", "BEL", "BS", "TAB", "LF", "VT", "FF", "CR", "SO", "SI",
                    //"DLE", "DC1", "DC2", "DC3", "DC4", "NAK", "SYN", "ETB", "CAN", "EM", "SUB",
                    //"ESC", "FS", "GS", "RS", "US", "Space"
                                     };
    
                string StringOut = "";
    
                foreach (char c in StringIn)
                {
                    if (Settings.Option.HexOutput)
                    {
                        StringOut = StringOut + String.Format("{0:X2} ", (int)c);
                    }
                    else if (c < 32 && c != 9)
                    {
                        StringOut = StringOut + "";// +"<"+charNames[c]+">";
    
                         //StringOut = StringOut + String.Format("[{0:X2}]", (int)c);
                    }
                    else
                    {
                        StringOut = StringOut + c;
                    }
                }
                return StringOut;
            }
    
            /// <summary>
            /// Partial line for AddData().
            /// </summary>
            private Line partialLine = null;
    
            /// <summary>
            /// Add data to the output.
            /// </summary>
            /// <param name="StringIn"></param>
            /// <returns></returns>
            private Line AddData(String StringIn)
            {
                String StringOut = PrepareData(StringIn);
    
                // if we have a partial line, add to it.
                if (partialLine != null)
                {
                    // tack it on
                    partialLine.Str = partialLine.Str + StringOut;
                    outputList_Update(partialLine);
                    return partialLine;
                }
    
                return outputList_Add(StringOut, receivedColor);
            }
    
            // delegate used for Invoke
            internal delegate void StringDelegate(string data);
    
            /// <summary>
            /// Handle data received event from serial port.
            /// </summary>
            /// <param name="data">incoming data</param>
            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();
            }
    
            /// <summary>
            /// Update the connection status
            /// </summary>
            public void OnStatusChanged(string status)
            {
                //Handle multi-threading
                if (InvokeRequired)
                {
                    Invoke(new StringDelegate(OnStatusChanged), new object[] { status });
                    return;
                }
    
                textBox1.Text = status;
            }
    
            #endregion
    


     

     


    Obrigado por sua participação.
    2011年11月1日 9:06

回答

すべての返信

  • Hello Silvio Pontes,

    Thank you for posting your question to our forum.
    However, unfortunately, I'm afraid it might be difficult for you to get a reply since people usually use Japanase here...
    I'd like to suggest you post your question in an English forum.
    Please click here to find an appropreate forum (category) depending on the type of your question.
    I hope you find some useful information!
    Thank you,
    --------------
    Harumi Yamamoto (MSKK)

    2011年11月2日 2:09
  • Oh, Dear Harumi.

    Ok, I live in Japan.

    I can try to communicate in Japanese.

    Because, I think it would be more efficient to solve my problem.

    svilp


    Obrigado por sua participação.
    2011年11月2日 2:48
  • Silvio-san

    I also recommend that you should provide background information about the "SerialPort.cs", "CommPort" class, etc. and how they are expected to work with your 10 devices through the RS485/USB converter.

    I believe that you are NOT using the .Net Framework-standard "Serial Port" class described in the following URL:
    http://msdn.microsoft.com/ja-jp/library/system.io.ports.serialport(v=VS.100).aspx

    Kotaro TONOIKE

     


    (ホームページを再開しました)
    • 回答の候補に設定 山本春海 2011年12月1日 9:38
    • 回答としてマーク 山本春海 2011年12月2日 7:46
    2011年11月2日 3:03
  • Kotaro TONOIKE -San, 

    Thank you, below has my SerialPort.cs.

     

    //SerialPort.cs
    using System;
    using System.IO;
    using System.IO.Ports;
    using System.Threading;
    
    namespace NanoFX
    {
        /// <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
    					{
    						// If there are bytes available on the serial port,
    						// Read returns up to "count" bytes, but will not block (wait)
    						// for the remaining bytes. If there are no bytes available
    						// on the serial port, Read will block until at least one byte
    						// is available on the port, up until the ReadTimeout milliseconds
    						// have elapsed, at which time a TimeoutException will be thrown.
    						int count = _serialPort.Read(readBuffer, 0, _serialPort.ReadBufferSize);
    						String SerialIn = System.Text.Encoding.Default.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);
                }
            }
        }
    }
    



    Obrigado por sua participação.
    2011年11月2日 8:13
  • Silvio-san

    Could you summarize your code?   I mean, could you explain how you understand your own code "SerialPort.cs"?

    You are behaving in a very typical manner that users of this forum may avoid to discuss with you.  Very few people read and analyze your code. 

    Necessary is NOT showing all code BUT brief explanation:

    what you have understood and achieved,
    what you intend next, and
    what your problem is.

    We know the last two items because you already told.  But, we do not know at all your knowledge base.

     Kotaro TONOIKE


    (ホームページを再開しました)
    • 編集済み 外池 2011年11月2日 9:03
    • 回答の候補に設定 山本春海 2011年12月1日 9:39
    2011年11月2日 9:01