在事件处理方法中调用RefreshInfoTextBox方法

时间:2022-03-07 04:05:02

在给Arduino编程的时候,因为没有调试工具,经常要通过使用串口通讯的方法挪用Serial.print和Serial.println输出Arduino运行过程中的相关信息,然后在电脑上用Arduino IDE的Serial Monitor来检察print出来的信息。Serial Monitor不只可以接受Arduino发送到电脑的数据,还可以向Arduino发送数据,进行双向通讯。但是这种通讯方法太过于简陋,是纯粹的手工方法,只适合调试。如果需要在电脑上通过可视化界面与Arduino进行交互,或者对Arduino发送到电脑上的数据进行措置惩罚惩罚,就需要在电脑上编程了。说的专业一点就是上位机与下位机的通讯。本文就介绍一下如何使用C#实现Arduino与电脑进行串行通讯。

1、C#串口编程根本

在C#中有一个串口类System.IO.Ports.SerialPort,这个类的实例就对应设备打点器中的串口。

好比 SerialPort port = new SerialPort("COM4")

这句代码就界说了一个串口实例,对应下图中的USB Serial Port(COM4)

在事件处理方法中调用RefreshInfoTextBox方法

SerialPort常用要领包孕Open, Close, Read, ReadLine, Write, WriteLine。这些要领通过名称就很容易理解它们的用法。

具体类信息可以参考MSDN:(v=vs.100).aspx

 

2、Arduino串口编程根本

Arduino中的Serial和C#的SerialPort用法类似,有available, begin, read, readBytes, write, print, println,从名称上也很容易理解。具体用法可以参考官方文档:

一般我们会在Arduino代码的setup要领中添加Serial.begin(9600),然后在serialEvent要领中读取接收到的数据。

 

3、实例

实例的场景为:

1、Arduino上接一个光线传感器,通过模拟口周期性读取亮度值。

2、在电脑上向Arduino发送一个开始发送数据的命令后,点亮Arduino上13号数字口的LED,然后Arduino通过串口向电脑发送亮度值。

3、在电脑上向Arduino发送一个遏制发送数据的命令后,,*Arduino上13号数字口的LED,然后Arduino遏制通过串口向电脑发送亮度值。

这个场景包罗了Arduino和电脑的双向通讯。

示例给与WinForm,界面如下:

在事件处理方法中调用RefreshInfoTextBox方法

“串口列表”中自动加载电脑上的可用串口名称。

点击“开始读取”按钮,按照选择的串口名称实例化一个串口东西,指定串口的DataReceived事件措置惩罚惩罚要领。然后挪用ChangeArduinoSendStatus要领向Arduino发送“serial start”命令。

点击“遏制读取”按钮,向Arduino发送“serial stop”命令,*串口并销毁实例。

点击“开始发送”或“遏制发送”按钮,挪用ChangeArduinoSendStatus要领向Arduino发送“serial start”或“serial stop”命令,让Arduino开始通过串口向电脑发送数据或遏制向电脑发送数据。

串口在接收到数据后出发DataReceived事件,在事件措置惩罚惩罚要领中挪用RefreshInfoTextBox要领,读取串口的数据并追加到界面的文本框。注意:串口的DataReceived事件是由后台线程执行,要把读取到的数据显示在WinFrom界面,需要使用控件的Invoke要领才华刷新界面。

 

C#核心代码如下:

private SerialPort port = null;
/// <summary>
/// 初始化串口实例
/// </summary>
private void InitialSerialPort()
{
    try
    {
        string portName = this.cmbSerials.SelectedItem.ToString();
        port = new SerialPort(portName, 9600);
        port.Encoding = Encoding.ASCII;
        port.DataReceived += port_DataReceived;
        port.Open();
        this.ChangeArduinoSendStatus(true);
    }
    catch (Exception ex)
    {
        MessageBox.Show("初始化串口产生错误:" + ex.Message, "提示信息", MessageBoxButtons.OK, MessageBoxIcon.Information);
    }
}
 
/// <summary>
/// *并销毁串口实例
/// </summary>
private void DisposeSerialPort()
{
    if (port != null)
    {
        try
        {
            this.ChangeArduinoSendStatus(false);
            if (port.IsOpen)
            {
                port.Close();
            }
            port.Dispose();
        }
        catch (Exception ex)
        {
            MessageBox.Show("*串口产生错误:" + ex.Message, "提示信息", MessageBoxButtons.OK, MessageBoxIcon.Information);
        }
    }
}
 
/// <summary>
/// 转变Arduino串口的发送状态
/// </summary>
/// <param>是否允许发送数据</param>
private void ChangeArduinoSendStatus(bool allowSend)
{
    if (port != null && port.IsOpen)
    {
        if (allowSend)
        {
            port.WriteLine("serial start");
        }
        else
        {
            port.WriteLine("serial stop");
        }
    }
}
 
/// <summary>
/// 从串口读取数据并转换为字符串形式
/// </summary>
/// <returns></returns>
private string ReadSerialData()
{
    string value = "";
    try
    {
        if (port != null && port.BytesToRead > 0)
        {
            value = port.ReadExisting();
        }
    }
    catch (Exception ex)
    {
        MessageBox.Show("读取串口数据产生错误:" + ex.Message, "提示信息", MessageBoxButtons.OK, MessageBoxIcon.Information);
    }
 
    return value;
}
 
/// <summary>
/// 在读取到数据时刷新文本框的信息
/// </summary>
private void RefreshInfoTextBox()
{
    string value = this.ReadSerialData();
    Action<string> setValueAction = text => this.txtInfo.Text += text;
 
    if (this.txtInfo.InvokeRequired)
    {
        this.txtInfo.Invoke(setValueAction, value);
    }
    else
    {
        setValueAction(value);
    }
}

 

Arduino代码

代码注释很详细,就不再做解释。