Корзина

0  Товары

0.00 RUB

Вход

Классический вход

Сообщество

Блог

Visual Studio C#: работа с последовательным портом.

Эта статья показывает, как записывать и читать данные от устройства, подключенного к последовательному порту (COM-порт) из приложения на языке C# в среде .NET. В этой статье мы создадим class RS485Server для работы с нашим газоанализатором по интерфейсу RS485. В недалеком прошлом для работы с Serial Port в среде .Net 1.1, мы должны были использовать либо Windows API, либо использовать управление из сторонних библиотек. В среде .Net 2.0 (и в более поздних версиях .NET) компания Microsoft добавила поддержку последовательного порта включением класса SerialPort как части пространства имен System.IO.Ports. Реализация класса RS485Server сделана очень прямо и очевидно. Для начала опишем используемые классом переменные:

C# Code:
  1. SerialPort _serialPort;
  2. // Статус клиента
  3. private bool client_running;
  4. private int loc_req;
  5. // Статус приемника
  6. private string returnData = "";
  7. private bool start_ok = false;
  8. private bool parse_ok = false;

На следующем этапе реализуем функцию Connect, отвечающую за открытие нашего com порта:

C# Code:
  1. public bool Connect(string Name, int Speed)
  2. {
  3. client_running = false;
  4. _serialPort = new SerialPort(Name,
  5. Speed,
  6. Parity.None,
  7. 8,
  8. StopBits.One);
  9. _serialPort.Handshake = Handshake.None;
  10. _serialPort.WriteTimeout = 50;
  11. _serialPort.ReadTimeout = 50;
  12. _serialPort.DataReceived += new SerialDataReceivedEventHandler(Receiver);
  13. try
  14. {
  15. _serialPort.Open();
  16. }
  17. catch (Exception ex)
  18. {
  19. Console.WriteLine("ERROR: " + ex.ToString() + "MESSAGE " + ex.Message);
  20. }
  21.  
  22. if (_serialPort.IsOpen)
  23. {
  24. client_running = true;
  25. }
  26. else
  27. {
  28. MessageBox.Show(
  29. "Не могу открыть порт!",
  30. "Ошибка",
  31. MessageBoxButtons.OK,
  32. MessageBoxIcon.Information,
  33. MessageBoxDefaultButton.Button1,
  34. MessageBoxOptions.DefaultDesktopOnly);
  35. }
  36.  
  37. return client_running;
  38. }

Как видите функция получилась достаточно простой. В качестве аргументов она принимает имя com порта и требуюмую скорость. Для определения существующих com портов удобно пользоваться следующей конструкцией:

C# Code:
  1. string[] portnames = System.IO.Ports.SerialPort.GetPortNames();
  2. domainUpDown1.Items.Clear();
  3. foreach (string port in portnames)
  4. {
  5. domainUpDown1.Text = port;
  6. domainUpDown1.Items.Add(port);
  7. }

Для приема данных нам нужно создать обработчик события EventHandler для "SerialDataReceivedEventHandler". В качестве этого приемника будет выступать метод Receiver:

C# Code:
  1. public void Receiver(object sender, SerialDataReceivedEventArgs e)
  2. {
  3. if (client_running == true)
  4. {
  5. if (_serialPort.IsOpen)
  6. {
  7. SerialPort sp = (SerialPort)sender;
  8. int buferSize = sp.BytesToRead;
  9. for (int i = 0; i < buferSize; ++i)
  10. {
  11. // читаем по одному байту
  12. char bt = (char)sp.ReadByte();
  13.  
  14. if (bt == '{' && start_ok == false) { start_ok = true; returnData = ""; }
  15.  
  16. if (start_ok == true)
  17. {
  18. returnData = returnData + bt.ToString();
  19. }
  20.  
  21. if (bt == '}' && start_ok == true) { start_ok = false; parse_ok = true; }
  22. }
  23.  
  24. if (parse_ok == true)
  25. {
  26. parse_ok = false;
  27. Console.WriteLine("RS485 --> " + returnData.ToString());
  28. try
  29. {
  30. if (loc_req == 1)//GET Device
  31. {
  32. Ans_Device newDevice = JsonConvert.DeserializeObject(returnData);
  33. Form1.myForm.Device1.DrawDeviceData(newDevice);
  34. newDevice = null;
  35. }
  36. }
  37. catch (Exception ex)
  38. {
  39. Console.WriteLine("ERROR: " + ex.ToString() + "MESSAGE " + ex.Message);
  40. }
  41. }
  42. }
  43. }
  44. }

Мы уже писали про использование формата JSON для общения наших устройств с серверным ПО. По этому в потоке происходит чтение данных с нашего com порта, и поиск данных заключенных в фигурные скобки { }. Далее для десериализации принятых данных используется компонент JsonConvert Class. Использовать его достаточно просто, для парсинга принятых данных, необходимо создать класс, соответствующий нашему запросу:

C# Code:
  1. //Класс ответа девайса
  2. public class Ans_Device
  3. {
  4. public string ANSWER { get; set; }
  5. public string NAME { get; set; }
  6. public int SENSORS { get; set; }
  7. public byte RS485_ADRESS { get; set; }
  8. public int[] IP_ADDRESS { get; set; }
  9. public int[] NETMASK { get; set; }
  10. public int[] GATEWAY { get; set; }
  11. }

Для десеарилизации наших данных достаточно создать экземпляр класса Ans_Device с нашими десериализованными данными:

C# Code:
  1. Ans_Device newDevice = JsonConvert.DeserializeObject(returnData);

Для завершения создания нашего класса осталось реализовать два простых метода. Первый, это метод Send, отправляющий данные в com порт:

C# Code:
  1. public void Send(string datagram, int request)
  2. {
  3. loc_req = request;
  4. _serialPort.Write(datagram.ToString());
  5. Console.WriteLine("RS485 <-- " + datagram.ToString());
  6. }

Второй, это метод Close, закрывающий наш порт, если он открыт:

C# Code:
  1. public void DisConnect()
  2. {
  3. try
  4. {
  5. if (_serialPort.IsOpen)
  6. {
  7. client_running = false;
  8. Thread.Sleep(500);
  9. _serialPort.Close();
  10. }
  11. }
  12. catch (Exception ex)
  13. {
  14. Console.WriteLine("ERROR: " + ex.ToString() + "MESSAGE " + ex.Message);
  15. }
  16. }

Ниже можно наблюдать видео работы получившегося класса.

Карта сайта Визуальная электроника Полезные ссылки сайта Визуальная электроника

Алиса это умеет

Оплата товаров

Cookies make it easier for us to provide you with our services. With the usage of our services you permit us to use cookies.
More information Ok