wtorek, 6 lutego 2018

C# - Klasa obsługująca port szeregowy

W tym poście przedstawię opis klasy obsługującej połączenie szeregowe przez port COM.

[Źródło: https://docs.microsoft.com/en-us/dotnet/]

Opis Funkcji:


Pierwsza funkcja publiczna odpowiada za inicjalizowanie nowego wystąpienia klasy SerialPort.

  1. public void pub_comPortInitialization()
  2. {
  3.     ComPort = new SerialPort();
  4. }

Następnie funkcja mająca za zadanie wyszukanie podłączonych portów COM:

  1. public string[] pub_getSerialPortName()
  2. {
  3.     string[] enableComPorts = new string[30];
  4.     byte i = 0;
  5.     foreach (String s in SerialPort.GetPortNames())
  6.     {
  7.         enableComPorts[i] = s;

  8.   i++;
  9.     }
  10.     return enableComPorts;
  11. }

Zamknięcie otwartego portu COM:

  1. public void pub_comPortClose()
  2. {
  3.     if (ComPort.IsOpen)
  4.     {
  5.         ComPort.Close();
  6.     }
  7. }

Odczytanie długości wiadomości:

  1. public int pub_readMsgLength()
  2. {
  3.     int readBytes = ComPort.BytesToRead;
  4.     return readBytes;
  5. }

Odczytanie wiadomości o podanej długości:

  1. public byte[] pub_receiveData(int readBytes)
  2. {
  3.     byte[] buffer = new byte[readBytes];        /* New buffer with received data */
  4.     ComPort.Read(buffer, 0, readBytes);         /* Read number of bytes */
  5.     return buffer;
  6. }

Funkcje przesyłająca dane przez otwarty port COM:

  1. public bool pub_comPortSendData(byte[] toSend)
  2. {
  3.     return comPortSendData(toSend);
  4. }

  1. private bool comPortSendData(byte[] dataToSend)
  2. {
  3.     try
  4.     {
  5.         ComPort.Write(dataToSend, 0, dataToSend.Length);
  6.     }
  7.     catch
  8.     {
  9.         return false;
  10.     }
  11.     return true;
  12. }

Funkcja publiczna wywołuje funkcje prywatną, która w przypadku błędu podczas przesyłania zwraca wartość false.

W przypadku gdy chcę przesłać część tablicy z danymi wykorzystuje zmodyfikowaną funkcję do której podaje się ilość danych do wysłania:

  1. public bool pub_comPortSendData(byte[] toSend, byte dataLength)
  2. {
  3.     return comPortSendData(toSend, dataLength);
  4. }

  5. private bool comPortSendData(byte[] dataToSend, byte dataLength)
  6. {
  7.     try
  8.     {
  9.         ComPort.Write(dataToSend, 0, dataLength);
  10.     }
  11.     catch
  12.     {
  13.         return false;
  14.     }
  15.     return true;
  16. }

Przesłanie ciągu znaków:

  1. private bool comPortSendData(string dataToSend)
  2. {
  3.    char[] charTable = dataToSend.ToCharArray();
  4.    try
  5.    {
  6.         ComPort.Write(charTable, 0, dataToSend.Length);
  7.    }
  8.    catch
  9.    {
  10.        return false;
  11.    }
  12.    return true;
  13. }
  14. public bool pub_comPortSendData(string toSend)
  15. {
  16.    return comPortSendData(toSend);
  17. }

Wykonanie połączenia z podanymi parametrami:

  1. public byte pub_connectSerialPort(string portName, string baudRate, string dataBits,
  2.                                   string parity, string stopBits)
  3. {
  4.     byte status = 0;
  5.     status = connectSerialPort(portName, baudRate, dataBits,
  6.                        parity, stopBits);
  7.     return status;
  8. }

  1. private byte connectSerialPort()
  2. {
  3.     if (ComPort.IsOpen)
  4.     {
  5.         ComPort.Close();
  6.         return 2; /* Com port was open, now we close it */
  7.     }
  8.     else
  9.     {
  10.         try
  11.         {
  12.             ComPort.PortName = connectPortName;
  13.             ComPort.BaudRate = connectBaudRate;
  14.             ComPort.DataBits = connectDataBits;
  15.             ComPort.Parity = connectParity;
  16.             ComPort.StopBits = connectStopBits;
  17.             ComPort.Open();
  18.             return 1; /* Ok*/
  19.         }
  20.         catch
  21.         {
  22.             return 0; /* Error */
  23.         }
  24.     }
  25. }

Jako argumenty pobieram wartości tekstowe ponieważ wyciągam je bezpośrednio z kontrolek Combo Box w aplikacji.

Można się połączyć poprzez edycję wcześniejszą edycję danych z informacjami o połączeniu, które zostały zdefiniowane w klasie:

  1. public static System.IO.Ports.SerialPort ComPort;
  2. private string connectPortName = "";
  3. private Int32 connectBaudRate = 115200;
  4. private byte connectDataBits = 8;
  5. private Parity connectParity = Parity.None;
  6. private StopBits connectStopBits = StopBits.One;
  7. public string ap_connectPortName
  8. {
  9.     get { return this.connectPortName; }
  10.     set { this.connectPortName = value; }
  11. }
  12. public Int32 ap_connectBaudRate
  13. {
  14.     get { return this.connectBaudRate; }
  15.     set { this.connectBaudRate = value; }
  16. }
  17. public byte ap_connectDataBits
  18. {
  19.     get { return this.connectDataBits; }
  20.     set { this.connectDataBits = value; }
  21. }
  22. public Parity ap_connectParity
  23. {
  24.     get { return this.connectParity; }
  25.     set { this.connectParity = value; }
  26. }
  27. public StopBits ap_connectStopBits
  28. {
  29.     get { return this.connectStopBits; }
  30.     set { this.connectStopBits = value; }
  31. }
  32. public byte pub_connectSerialPort()
  33. {
  34.     byte status = 0;
  35.     status = connectSerialPort();
  36.     return status;
  37. }
  38. private byte connectSerialPort()
  39. {
  40.     if (ComPort.IsOpen)
  41.     {
  42.         ComPort.Close();
  43.         return 2; /* Com port was open, now we close it */
  44.     }
  45.     else
  46.     {
  47.         try
  48.         {
  49.             ComPort.PortName = ap_connectPortName;
  50.             ComPort.BaudRate = ap_connectBaudRate;
  51.             ComPort.DataBits = ap_connectDataBits;
  52.             ComPort.Parity = ap_connectParity;
  53.             ComPort.StopBits = ap_connectStopBits;
  54.             ComPort.Open();
  55.             return 1; /* Ok*/
  56.          }
  57.          catch
  58.          {
  59.             return 0; /* Error */
  60.          }
  61.    }
  62. }

Cały kod można pobrać z dysku Google pod tym linkiem.