Написать программу опроса нескольких com портов - C#
Формулировка задачи:
Товарищи программисты, необходимо сделать программу опроса нескольких com портов. Опрос одного сделать оказалось просто, а вот нескольких - задача конкретно усложнилась. Сразу скажу - количество портов сразу не известно. Данные получаю с базу. т.е. число может меняться динамически.
вот код для одного ком порта
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
//-----
using System.IO.Ports;
using System.IO;
namespace comSobitie
{
public partial class Form1 : Form
{
// Таймер
Timer timer = new Timer();
// Порт
SerialPort port = new SerialPort("COM2", 9600, System.IO.Ports.Parity.None, 8, System.IO.Ports.StopBits.One);
string valu = "";
String indata = "";
public Form1()
{
InitializeComponent();
System.Windows.Forms.Control.CheckForIllegalCrossThreadCalls = false; //ОЧЕНЬ СПОРНОЕ РЕШЕНИЕ !!!!!!!!!!
// Подписались на приход данных
port.DataReceived += new SerialDataReceivedEventHandler(port_DataReceived);
// Задаем интервал таймеру
timer.Interval = 10000;
// Подписываемся на тики таймера
timer.Tick += new EventHandler(timer1_Tick);
// Стартуем таймер
timer.Start();
}
private void Form1_Load(object sender, EventArgs e)
{
}
private void timer1_Tick(object sender, EventArgs e)
{
// Открываем порт
if (port.IsOpen)
{
// Если порт открыт, значит какой-то косяк, девайс не ответил, здесь обрабатываем
// Закрываем
port.Close();
}
// Открываем
port.Open();
// Чето посылаем
port.Write("#10\r");
}
int i = 0;
// Пришли данные
void port_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
System.Threading.Thread.Sleep(100);
// Получаем пришедшие данные
indata = port.ReadExisting();
// Чето с ними делаем
textBox1.Text = " SELECT \"ID_TagName\"" + indata + " ;";
// Закрываем порт
if (port.IsOpen) port.Close();
}
}
}
есть еще такая красота, но не могу разобраться
/// <summary>
/// Класс работы с последовательным портом
/// </summary>
public class SerialPort : IDisposable
{
//--------------------------------------------------------------------------
//Construction, Destruction
//--------------------------------------------------------------------------
#region Construction, Destruction
/// <summary>
/// Оболочка для работы с СОМ-портом
/// </summary>
/// <param name="comNum">Номер СОМ-порта</param>
/// <param name="baudRate">Скорость</param>
public SerialPort(byte comNum, int baudRate)
{
this.comNum = comNum;
serialPort = new System.IO.Ports.SerialPort("COM" + comNum.ToString(), baudRate);
serialPort.Open();
thread = new System.Threading.Thread(ThreadFn);
thread.Start();
}
/// <summary>
/// Очистка ресурсов
/// </summary>
public void Dispose()
{
DisposeImpl(true);
}
/// <summary>
/// Finalizer
/// </summary>
~SerialPort()
{
DisposeImpl(false);
}
private void DisposeImpl(bool manualDispose)
{
if (manualDispose)
{
if (thread != null)
thread.Abort();
if (serialPort != null)
serialPort.Dispose();
}
}
#endregion Construction, Destruction
//--------------------------------------------------------------------------
//Public Interface
//--------------------------------------------------------------------------
#region Public Interface
/// <summary>
/// Отправить данные
/// </summary>
/// <param name="data">Массив данных</param>
/// <exception cref="Exception">Генерируется, если при работе с последовательным портом
/// возникнет исключение</exception>
public void SendData(Byte[] data)
{
serialPort.Write(data, 0, data.Length);
}
/// <summary>
/// Текущий номер СОМ-порта
/// </summary>
public Byte ComNum
{
get { return comNum; }
set
{
if (comNum != value)
{
comNum = value;
serialPort.Close();
serialPort.PortName = "COM" + value.ToString();
}
}
}
/// <summary>
/// Скорость передачи данных
/// </summary>
public int BaudRate
{
get { return serialPort.BaudRate; }
set { serialPort.BaudRate = value; }
}
/// <summary>
/// Состояние линии Dtr
/// </summary>
public bool DtrEnable
{
get { return serialPort.DtrEnable; }
set { serialPort.DtrEnable = value; }
}
/// <summary>
/// Состояние линии Rts
/// </summary>
public bool RtsEnable
{
get { return serialPort.RtsEnable; }
set { serialPort.RtsEnable = value; }
}
/// <summary>
/// Делегат приема байта
/// </summary>
/// <param name="data">Принятый байт данных</param>
public delegate void OnByteReceived(Byte data);
/// <summary>
/// Событие приема байт
/// </summary>
public event OnByteReceived ByteReceived;
#endregion Public Interface
//--------------------------------------------------------------------------
//Private Member Functions
//--------------------------------------------------------------------------
#region Private Member Functions
//Обработка принятого байта
private void OnReceiveByte(Byte data)
{
//Если на событие приема байт кто-то подписан, то отправляю ему байт
if (ByteReceived != null)
ByteReceived(data);
}
//Функция чтения данных в новом потоке
private void ThreadFn(object obj)
{
//создаю входной буффер. Сюда будут писаться данные из последовательного порта
Byte[] inputBuffer = new Byte[inputBufferSize];
while (true)
{
try
{
//получаю количество доступных байт
int availibleBytes = serialPort.BytesToRead;
if (availibleBytes > 0)
{
int bytesToRead = availibleBytes < inputBufferSize ? availibleBytes : inputBufferSize;
int readedBytes = serialPort.Read(inputBuffer, 0, bytesToRead);
for (int i = 0; i < readedBytes; i++)
OnReceiveByte(inputBuffer[i]);
}
System.Threading.Thread.Sleep(1);
}
catch (System.Threading.ThreadAbortException)
{
break;
}
catch (Exception e)
{
System.Diagnostics.Debug.Assert(false, e.Message);
}
}
}
#endregion Private Member Functions
//--------------------------------------------------------------------------
//Private Data Members
//--------------------------------------------------------------------------
#region Private Data Members
/// <summary>
/// Номер СОМ-порта
/// </summary>
private Byte comNum;
/// <summary>
/// Последовательный порт
/// </summary>
private System.IO.Ports.SerialPort serialPort;
/// <summary>
/// Поток. Нужен, т.к. данные читаются в новом потоке
/// </summary>
private System.Threading.Thread thread;
/// <summary>
/// Максимальный размер входного буффер
/// </summary>
private const int inputBufferSize = 1024;
#endregion Private Data Members
}//class RS232Решение задачи: «Написать программу опроса нескольких com портов»
textual
Листинг программы
class Pair<T>
{
public Pair(T first,T second)
{
First = first;
Second = second;
}
public T First { get; set; }
public T Second { get; set; }
}
class Program
{
static void Main(string[] args)
{
List<Pair<int>> mas = new List<Pair<int>>();
mas.Add(new Pair<int>(5, 7));
Console.WriteLine(mas[0].First + " " + mas[0].Second);
}
}