Работа с данными COM порта (C#)
Возникла проблема при обработке данных COM порта.
Имеется очень примитивный метод считывания данных по нажатию кнопки.
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
SerialPort arduino = new SerialPort("COM3", 9600, Parity.None, 8, StopBits.One);
private void button1_Click(object sender, EventArgs e)
{
arduino.Open();
}
private void button2_Click(object sender, EventArgs e)
{
string s = arduino.ReadExisting();
textBox1.Text = s;
}
private void button3_Click(object sender, EventArgs e)
{
arduino.Close();
}
}
}
Данные последов. порта приходят с заданным мной интервалом (5 сек). Как мне проследить получение данных? То есть мне нужен такой обработчик, который бы получив сигнал о том, что данные пришли, записал эти данные куда мне нужно и ждал бы следующего сообщения с данными.
SerialPort.DataReceived по-моему должен помочь. Но я не знаю как работать с событиями в С#. Я только начинаю работать с этим языком.
Заранее благодарен.
private void SetText(Label Info, string Text)
{
if (Info.InvokeRequired)
{
StDelegate DDD = new StDelegate(SetText);
Info.Invoke(DDD, new object[] { Info, Text });
}
else
{
Info.Text = Text;
}
}
Вызов такой :
SetText(this.labelStatus, "Stopped!");
и вместо textbox1.Text = indata;
SetText(this.textbox1, indata);
UPD: ещё один хинт, если тебе не хочется учиться пользоваться гуглом, то почти для каждого метода, свойства, класса, конструктора и евента на офигенном сайте для программеров под dot.net и не только - msdn.microsoft.com - есть пример кода. Для твоей задачи тоже код имеется.
Разбирался с кодом мсдн на мою тему и возникла проблема.
Есть вот такой кусок:
object sender,
SerialDataReceivedEventArgs e)
{
SerialPort sp = (SerialPort)sender;
string indata = sp.ReadExisting();
Console.WriteLine("Data Received:");
Console.Write(indata);
}
Я все перенес в формы и хотел внести необходимые изменения. Ну, например, чтобы мои данные отображались в TextBox. Проблема в том, что textBox1 не виден внутри этой функции (или это событие, не знаю как правильно назвать). И переменную indata оттуда никак не вытащить.
Это функция. Текст бокс не виден, потому, что вам нужно разобраться в отличиях статических и динамических переменных.
Данные из ком-порта по моему, должны быть в SerialDataReceivedEventArgs e - сделайте у себя е. - и посмотрите, что там есть, не надо будет самостоятельно вытаскивать.
Но это только начало сложностей - этот эвент (SerialDataReceived) вызывается обьектом ком-порта в другом потоке.
И вам в винформах надо будет использовать Invoke. - чтобы уведомить винформ контрол (текст бокс) о изменении свойства Text.
Крутовато вы взялись - первое приложение и уже интеграция.
Взялся, потому что это очень необходимо. Вопрос жизни и смерти. Я готов во всем разобраться.
Есть такой код, после компиляции которого возникает ошибка несогласования потоков в строке с текстбокс1 (вы упоминали об этом):
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;
namespace com_data
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
SerialPort mySerialPort = new SerialPort("COM4");
string s;
private void button1_Click(object sender, EventArgs e)
{
mySerialPort.BaudRate = 9600;
mySerialPort.Parity = Parity.None;
mySerialPort.StopBits = StopBits.One;
mySerialPort.DataBits = 8;
mySerialPort.Handshake = Handshake.None;
mySerialPort.DataReceived += new SerialDataReceivedEventHandler(DataReceivedHandler);
mySerialPort.Open();
}
private void DataReceivedHandler(object sender, SerialDataReceivedEventArgs e)
{
SerialPort sp = (SerialPort)sender;
string indata = sp.ReadExisting();
textbox1.Text = indata;
}
private void button3_Click(object sender, EventArgs e)
{
mySerialPort.Close();
}
{
if (progressWindow.InvokeRequired)
{
StopProgressDel del = new StopProgressDel(HideProgressBar);
progressWindow.Invoke(del, null);
}
else
if (progressWindow != null)
progressWindow.Hide();
}
А зачем второй аргумент объект класса текстбокс?
А на каком языке проще всего работать с последовательными портами? Мне кажется, что на C#. В нем столько готовых средств, облегчающих программирование. Или я заблуждаюсь...
Похоже, заблуждаешься.
Класс SerialPort - это не часть языка, это часть фреймворка .NET. Так же и класс Form - часть фреймворка, а не языка. Эти и многие другие классы доступны в любом языке под платформу .NET.
Однако, язык C# весьма удобный, мощный, и в то же время довольно простой. Продолжай осваивать его.
А зачем второй аргумент объект класса текстбокс?
Чтобы использовать эту функцию для любого текстбокса на форме, а не только одного-единственного.
По правилам программирования, каждая функция должна быть максимально закрыта, и получать все, что ей нужно для работы через параметры.
Соблюдение этого принципа очень помогает потом делать изменения.
На этом моя работа не останавливается. Теперь мне необходимо научится подключаться к MySQL и записывать туда данные. Слышал что есть удобный коннектор для .NET языков от MySQL.
Для этой задачи лучше завести новую тему или продолжать тут, если возникнут вопросы?