Laden...

Daten über Serielle Schnittstelle versenden.

Letzter Beitrag vor 9 Monaten 4 Posts 507 Views
Daten über Serielle Schnittstelle versenden.

Hallo ich brauch Hilfe bei einem Programm.

Zum Testen des Seriellen Port an einem PC möchte ich ein Programm schreiben.

In der Testumgebung werden 2 PC über Serielle Verbindung verbunden. 
Auf jedem PC soll ein Programm gestartet werden, dass einen String zwischen beiden PCs hin und her sendet. (in einer Schleife zB 100x)

Auf dem PC der den String gesendet hat soll dann zwischen zwischen jedem Sendevorgang überprüft werden ob der empfangene und der gesendete String identisch ist. Der zweite PC muss nichts weiter machen als den String zu empfangen und wieder zurück zu senden.

Spricht.

1 PC 1 sendet den String und wartet auf Antwort von PC 2 
2 PC 2 empfängt den String und sendet ihn wieder zurück an PC 1
3 PC 1 empfängt den String vergleicht ihn und beginnt wieder bei 1 und sendet den String an PC 2

Das Problem bei meinem bisherigen Programm ist der das zwischen der Kommunikation Datenbits verloren gehen. Das wird daran liegen das beide PCs die Daten gleichzeitig senden. Daher möchte ich in das Programm die Warte Funktion einbauen.m so das ein Ping Pong zwischen den Beiden PCs  entsteht. 
Und hier weis ich nicht so recht wie ich das umsetzen kann.

Hier mal die beiden Programme die ich bisher habe

PC 1 Sender

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

namespace Serial_Transmitter
{
    public class Program
    {
        static void Main()
        {
            SerialPort serialPort = new SerialPort();
            // Allow the user to set the appropriate properties.
            serialPort.PortName = SetPortName(serialPort.PortName);
            serialPort.BaudRate = SetPortBaudRate(serialPort.BaudRate);
            serialPort.Parity = SetPortParity(serialPort.Parity);
            serialPort.DataBits = SetPortDataBits(serialPort.DataBits);
            serialPort.StopBits = SetPortStopBits(serialPort.StopBits);
            serialPort.Handshake = SetPortHandshake(serialPort.Handshake);
        
            // open serial port
            serialPort.Open();
            int repeatInt;

            while (true)
            {
                Console.WriteLine("Value to be sent:");
                string dataToSend = Console.ReadLine();
                
                Console.WriteLine("How often sent?");
                Convert_repeat:
                string repeat = Console.ReadLine();
                try
                {
                    repeatInt = Convert.ToInt32(repeat);
                }
                catch (Exception e)
                {
                    Console.WriteLine(e.Message);
                    Console.WriteLine("Please insert integer, try again.");
                    goto Convert_repeat;
                }

                for (int i=1; i <= repeatInt; i++)
                serialPort.WriteLine(dataToSend); // Daten über die serielle Schnittstelle senden
                Thread.Sleep(300);


                string receivedData = serialPort.ReadLine(); // Daten von der seriellen Schnittstelle empfangen
                Console.WriteLine("Received: " + receivedData);

                if (dataToSend == receivedData)
                {
                    Console.WriteLine("Strings are identical.");
                }
                else
                {
                    Console.WriteLine("Strings are not identical.");
                }

            }

           // serialPort.Close(); // Serielle Schnittstelle schließen
        }

        // Display Port values and prompt user to enter a port.
        public static string SetPortName(string defaultPortName)
        {
            string portName;

            Console.WriteLine("Available Ports:");
            foreach (string s in SerialPort.GetPortNames())
            {
                Console.WriteLine("   {0}", s);
            }

            Console.Write("Enter COM port value (Default: {0}): ", defaultPortName);
            portName = Console.ReadLine();

            if (portName == "" || !(portName.ToLower()).StartsWith("com"))
            {
                portName = defaultPortName;
            }
            return portName;
        }
        // Display BaudRate values and prompt user to enter a value.
        public static int SetPortBaudRate(int defaultPortBaudRate)
        {
            string baudRate;

            Console.Write("Baud Rate(default:{0}): ", defaultPortBaudRate);
            baudRate = Console.ReadLine();

            if (baudRate == "")
            {
                baudRate = defaultPortBaudRate.ToString();
            }

            return int.Parse(baudRate);
        }
        // Display PortParity values and prompt user to enter a value.
        public static Parity SetPortParity(Parity defaultPortParity)
        {
            string parity;

            Console.WriteLine("Available Parity options:");
            foreach (string s in Enum.GetNames(typeof(Parity)))
            {
                Console.WriteLine("   {0}", s);
            }

            Console.Write("Enter Parity value (Default: {0}):", defaultPortParity.ToString(), true);
            parity = Console.ReadLine();

            if (parity == "")
            {
                parity = defaultPortParity.ToString();
            }

            return (Parity)Enum.Parse(typeof(Parity), parity, true);
        }
        // Display DataBits values and prompt user to enter a value.
        public static int SetPortDataBits(int defaultPortDataBits)
        {
            string dataBits;

            Console.Write("Enter DataBits value (Default: {0}): ", defaultPortDataBits);
            dataBits = Console.ReadLine();

            if (dataBits == "")
            {
                dataBits = defaultPortDataBits.ToString();
            }

            return int.Parse(dataBits.ToUpperInvariant());
        }

        // Display StopBits values and prompt user to enter a value.
        public static StopBits SetPortStopBits(StopBits defaultPortStopBits)
        {
            string stopBits;

            Console.WriteLine("Available StopBits options:");
            foreach (string s in Enum.GetNames(typeof(StopBits)))
            {
                Console.WriteLine("   {0}", s);
            }

            Console.Write("Enter StopBits value (None is not supported and \n" +
             "raises an ArgumentOutOfRangeException. \n (Default: {0}):", defaultPortStopBits.ToString());
            stopBits = Console.ReadLine();

            if (stopBits == "")
            {
                stopBits = defaultPortStopBits.ToString();
            }

            return (StopBits)Enum.Parse(typeof(StopBits), stopBits, true);
        }
        public static Handshake SetPortHandshake(Handshake defaultPortHandshake)
        {
            string handshake;

            Console.WriteLine("Available Handshake options:");
            foreach (string s in Enum.GetNames(typeof(Handshake)))
            {
                Console.WriteLine("   {0}", s);
            }

            Console.Write("Enter Handshake value (Default: {0}):", defaultPortHandshake.ToString());
            handshake = Console.ReadLine();

            if (handshake == "")
            {
                handshake = defaultPortHandshake.ToString();
            }

            return (Handshake)Enum.Parse(typeof(Handshake), handshake, true);
        }
    }
}

Und auf PC 2 Empfänger

using System;
using System.IO.Ports;

namespace Serial_Receiver
{
    public class Program
    {
        static void Main()
        {
            SerialPort serialPort = new SerialPort();
            // Allow the user to set the appropriate properties.
            serialPort.PortName = SetPortName(serialPort.PortName);
            serialPort.BaudRate = SetPortBaudRate(serialPort.BaudRate);
            serialPort.Parity = SetPortParity(serialPort.Parity);
            serialPort.DataBits = SetPortDataBits(serialPort.DataBits);
            serialPort.StopBits = SetPortStopBits(serialPort.StopBits);
            serialPort.Handshake = SetPortHandshake(serialPort.Handshake);

           // open serial port
            serialPort.Open();
            string receivedData; 


            while (true)
            {    
                    receivedData = serialPort.ReadLine(); 
                    Console.WriteLine("Received: " + receivedData);

                serialPort.WriteLine(receivedData);

                serialPort.DiscardInBuffer();
                serialPort.DiscardOutBuffer();

            }

          //  serialPort.Close(); // Serielle Schnittstelle schließen
        }

        // Display Port values and prompt user to enter a port.
        public static string SetPortName(string defaultPortName)
        {
            string portName;

            Console.WriteLine("Available Ports:");
            foreach (string s in SerialPort.GetPortNames())
            {
                Console.WriteLine("   {0}", s);
            }

            Console.Write("Enter COM port value (Default: {0}): ", defaultPortName);
            portName = Console.ReadLine();

            if (portName == "" || !(portName.ToLower()).StartsWith("com"))
            {
                portName = defaultPortName;
            }
            return portName;
        }
        // Display BaudRate values and prompt user to enter a value.
        public static int SetPortBaudRate(int defaultPortBaudRate)
        {
            string baudRate;

            Console.Write("Baud Rate(default:{0}): ", defaultPortBaudRate);
            baudRate = Console.ReadLine();

            if (baudRate == "")
            {
                baudRate = defaultPortBaudRate.ToString();
            }

            return int.Parse(baudRate);
        }
        // Display PortParity values and prompt user to enter a value.
        public static Parity SetPortParity(Parity defaultPortParity)
        {
            string parity;

            Console.WriteLine("Available Parity options:");
            foreach (string s in Enum.GetNames(typeof(Parity)))
            {
                Console.WriteLine("   {0}", s);
            }

            Console.Write("Enter Parity value (Default: {0}):", defaultPortParity.ToString(), true);
            parity = Console.ReadLine();

            if (parity == "")
            {
                parity = defaultPortParity.ToString();
            }

            return (Parity)Enum.Parse(typeof(Parity), parity, true);
        }
        // Display DataBits values and prompt user to enter a value.
        public static int SetPortDataBits(int defaultPortDataBits)
        {
            string dataBits;

            Console.Write("Enter DataBits value (Default: {0}): ", defaultPortDataBits);
            dataBits = Console.ReadLine();

            if (dataBits == "")
            {
                dataBits = defaultPortDataBits.ToString();
            }

            return int.Parse(dataBits.ToUpperInvariant());
        }

        // Display StopBits values and prompt user to enter a value.
        public static StopBits SetPortStopBits(StopBits defaultPortStopBits)
        {
            string stopBits;

            Console.WriteLine("Available StopBits options:");
            foreach (string s in Enum.GetNames(typeof(StopBits)))
            {
                Console.WriteLine("   {0}", s);
            }

            Console.Write("Enter StopBits value (None is not supported and \n" +
             "raises an ArgumentOutOfRangeException. \n (Default: {0}):", defaultPortStopBits.ToString());
            stopBits = Console.ReadLine();

            if (stopBits == "")
            {
                stopBits = defaultPortStopBits.ToString();
            }

            return (StopBits)Enum.Parse(typeof(StopBits), stopBits, true);
        }
        public static Handshake SetPortHandshake(Handshake defaultPortHandshake)
        {
            string handshake;

            Console.WriteLine("Available Handshake options:");
            foreach (string s in Enum.GetNames(typeof(Handshake)))
            {
                Console.WriteLine("   {0}", s);
            }

            Console.Write("Enter Handshake value (Default: {0}):", defaultPortHandshake.ToString());
            handshake = Console.ReadLine();

            if (handshake == "")
            {
                handshake = defaultPortHandshake.ToString();
            }

            return (Handshake)Enum.Parse(typeof(Handshake), handshake, true);
        }
    }
}

Also abgesehen von größeren Strukturprobleme, der Verwendung von goto und anderen Dingen...ist Dein Problem, dass der Code eben blockiert. Das ist nie eine gute Idee.

Eine saubere Umsetzung wirst Du nur hin bekommen, wenn Du grundlegend neu beginnst - und zwar so, wie es auch in den Docs gezeigt wird.
Du hast zwar 50% aus den Docs kopiert - aber Du hast die Verarbeitung im Thread offenbar einfach raus gelöscht - und genau das is die Wurzel des Problems hier.


Die SerialPort Docs sind übrigens etwas alt; man würde heutzutage eher Tasks nehmen als Threads; ebenso asynchrone Implementierungen.
Hier im Forum findest Du viele andere Beispiele, zB Template SerialPort | myCSharp.de

Und lass sowas wie goto hier weg... goto hat nichts in strukturierten Sprachen zu suchen. Existiert nur noch für ganz wenige Fälle in C# - das hier ist keiner.

PS: Docs sind dazu da Dir zu zeigen/erklären, wie etwas funktioniert. Seltenst sind die die Samples 1:1 gedacht für produktiven Code zu verwenden.
Sind eben Samples, keine Templates.