用C#进行仪器控制系列-数字万用表(4)

此为“用C#进行仪器控制系列--数字万用表”的第4篇文章,在此之前已经编写了3篇相关文章了,可参见:

1)用C#进行仪器控制系列——数字万用表(1):该篇文章介绍了如何从零开始创建一个控制台应用程序,实现 Keysight 数字万用表的电压测量,并将结果通过控制台展示;

2)用C#进行仪器控制系列——数字万用表(2):该篇文章在第1篇文章的基础上,以窗体应用程序的形式重写了万用表电压测量程序,并能够自动识别仪器地址,以及能够通过按钮控制测量的开始和停止,电压的显示等。

3)用C#进行仪器控制系列——数字万用表(3):该篇文章在第2篇文章的基础上,通过代码的简单优化,实现了不同测量类型的下拉选择,根据下拉选项执行对应类型的测量功能(电压、电流、电阻、二极管、导通、频率测试等)。

此篇文章是在第3篇文章的基础上,添加波形图表显示功能。

优化需求:添加波形图表显示功能,用以观测数据的变化趋势

通过添加波形图表功能,将测量数据实时传递给波形图表,使其能够在界面中显示测量的历史数据,就可以观测到数据的变化趋势了。最终想要实现的效果如下图所示。

需求实现效果

优化实现过程

1)窗体界面的优化

Chart控件

图表的“Series”属性

修改“Series”属性

调整窗体布局

2)代码优化

主要涉及如下3块代码段的修改:

public Form1()
        {
            InitializeComponent();

            // 设置曲线图样式
            WaveChart.Series[0].ChartType = SeriesChartType.Line;
            WaveChart.Series[0].Color = System.Drawing.Color.Blue;
        }
if (btnStart.Text == "开始测试")
                {
                    btnStart.Text = "停止测试";

                    // 清空曲线图数据
                    WaveChart.Series[0].Points.Clear();
// 循环读取万用表数据
                while (true)
                {
                    // 发送采集命令
                    messageBasedSession.WriteString(":READ?", true);

                    // 读取返回值
                    string response = messageBasedSession.ReadString();

                    // 在控件和图表中输出结果
                    this.Invoke((MethodInvoker)delegate
                    {
                        resultTextBox.Text = ChangeDataToD(response.Trim());
                        WaveChart.Series[0].Points.AddY(double.Parse(resultTextBox.Text));
                    });
                }

优化效果验证

程序优化后的运行效果如下图所示,可通过下拉选择测量类型,实现不同的测试需求,然后通过Text Box显示控件和Chart波形图表显示数据。

运行效果

通过验证,可以完美的实现测量需求。


附:本文中涉及到的完整源代码

using System;
using System.Resources;
using System.Windows.Forms;
using Ivi.Visa.Interop;
using System.Threading;
using System.Linq.Expressions;
using System.Windows.Forms.DataVisualization.Charting;

namespace WinForm_ComPorts
{
    public partial class Form1 : Form
    {

        private Ivi.Visa.Interop.ResourceManager resourceManager;
        private FormattedIO488 messageBasedSession;
        private Thread measurementThread;



        public Form1()
        {
            InitializeComponent();

            // 设置曲线图样式
            WaveChart.Series[0].ChartType = SeriesChartType.Line;
            WaveChart.Series[0].Color = System.Drawing.Color.Blue;
        }


        #region 端口号下拉选择框下拉事件响应代码
        /// 
        /// 端口号下拉选择框下拉事件响应代码
        /// 
        /// 
        /// 
        private void cboComPorts_DropDown(object sender, EventArgs e)
        {
            try
            {
                // 清除下拉列表
                this.cboComPorts.Items.Clear();
                // 获取设备的所有串口资源
                string[] comNames = System.IO.Ports.SerialPort.GetPortNames();
                // 添加可用串口号到下拉框中
                foreach (string s in comNames)
                {
                    this.cboComPorts.Items.Add(s);
                }
                // 创建VISA资源对象实例
                Ivi.Visa.Interop.ResourceManager rm = new Ivi.Visa.Interop.ResourceManager();
                // 获取设备的所有仪器资源
                string[] usbNames = rm.FindRsrc("?*INSTR");
                // 添加可用USB资源到下拉框中
                foreach (string s in usbNames)
                {
                    if (s.Contains("0x"))
                        this.cboComPorts.Items.Add(s);
                }
            }

            catch (Exception)
            {
                MessageBox.Show("系统内不存在此类仪器~", "ERROR");
            }
        }
        #endregion


        #region 开始测试/停止测试按钮事件响应代码
        /// 
        /// 开始测试/停止测试按钮事件响应代码
        /// 
        /// 
        /// 
        private void btnStart_Click(object sender, EventArgs e)
        {
            try
            {
                if (btnStart.Text == "开始测试")
                {
                    btnStart.Text = "停止测试";

                    // 清空曲线图数据
                    WaveChart.Series[0].Points.Clear();

                    // 创建ResourceManager和MessageBasedSession对象
                    resourceManager = new Ivi.Visa.Interop.ResourceManager();
                    messageBasedSession = new FormattedIO488();

                    // 打开万用表连接,万用表的USB通讯地址通过端口号下拉列表的值传递过来
                    messageBasedSession.IO = (IMessage)resourceManager.Open(cboComPorts.Text.ToString(), AccessMode.NO_LOCK, 5000, "");

                    //获取测量类型,根据测量类型选择相应的采集指令
                    string ConfigCommand = "";
                    switch (cboMeasType.Text)
                    {
                        case "DC Voltage":
                            ConfigCommand = ":CONF:VOLT:DC AUTO,DEF";
                            break;
                        case "AC Voltage":
                            ConfigCommand = ":CONF:VOLT:AC AUTO,DEF";
                            break;
                        case "DC Current":
                            ConfigCommand = ":CONF:CURR:DC AUTO,DEF";
                            break;
                        case "AC Current":
                            ConfigCommand = ":CONF:CURR:AC AUTO,DEF";
                            break;
                        case "Resistance 2-wire":
                            ConfigCommand = ":CONF:RES AUTO";
                            break;
                        case "Resistance 4-wire":
                            ConfigCommand = ":CONF:FRES AUTO";
                            break;
                        case "Diode":
                            ConfigCommand = ":CONF:DIOD";
                            break;
                        case "Continuity":
                            ConfigCommand = ":CONF:CONT";
                            break;
                        case "Frequency":
                            ConfigCommand = ":CONF:FREQ";
                            break;
                        default:
                            ConfigCommand = ":CONF:VOLT:DC AUTO,DEF";
                            break;
                    }

                    // 设置采集模式和测量范围
                    messageBasedSession.WriteString(ConfigCommand, true);

                    // 创建线程执行连续测量
                    measurementThread = new Thread(new ThreadStart(MeasureThread));
                    measurementThread.Start();
                }
                else
                {
                    btnStart.Text = "开始测试";

                    // 停止测量线程
                    if (measurementThread != null && measurementThread.IsAlive)
                    {
                        measurementThread.Abort();
                        measurementThread.Join();
                    }

                    // 关闭连接
                    if (messageBasedSession != null)
                    {
                        messageBasedSession.IO.Close();
                        // messageBasedSession.Dispose();
                    }

                    if (resourceManager != null)
                    {
                        // resourceManager.Dispose();
                        // MessageBox.Show("资源释放");
                    }
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show("发生错误:" + ex.Message);
            }
        }
        #endregion


        #region 测量线程代码
        /// 
        /// 测量线程,读取万用表的数据,并将结果反馈至resultTextBox控件
        /// 
        private void MeasureThread()
        {
            try
            {
                // 循环读取万用表数据
                while (true)
                {
                    // 发送采集命令
                    messageBasedSession.WriteString(":READ?", true);

                    // 读取返回值
                    string response = messageBasedSession.ReadString();

                    // 在控件和图表中输出结果
                    this.Invoke((MethodInvoker)delegate
                    {
                        resultTextBox.Text = ChangeDataToD(response.Trim());
                        WaveChart.Series[0].Points.AddY(double.Parse(resultTextBox.Text));
                    });
                }
            }

            catch (ThreadAbortException)
            {
                // 线程被中断
                // MessageBox.Show("线程被中断");

                // 查询错误
                messageBasedSession.WriteString(":SYST:ERR?");
                // 读取返回的错误信息
                string response = messageBasedSession.ReadString();
                // 若仪器返回了“-410”错误(读取万用表读数时被中断导致)或无错误,则忽略
                if (response.Contains("-410") || response.Contains("No error")) { }
                else
                {
                    MessageBox.Show(response);
                }
            }

            catch (Exception ex)
            {
                MessageBox.Show("发生错误:" + ex.Message);
            }
        }
        #endregion


        #region 数据显示格式转换代码
        /// 
        /// 将科学计数法表示的字符串数据转换为double型数据显示格式
        /// 
        /// 
        /// 返回double型数据格式的字符串
        private string ChangeDataToD(string strData)
        {
            Double dData = 0.0;
            if (strData.Contains("E"))
            {
                dData = Double.Parse(strData);
            }
            return dData.ToString();

        }
        #endregion

    }
}
展开阅读全文

页面更新:2024-03-05

标签:波形   万用表   篇文章   线程   图表   控件   测量   仪器   代码   测试   系列   数据

1 2 3 4 5

上滑加载更多 ↓
推荐阅读:
友情链接:
更多:

本站资料均由网友自行发布提供,仅用于学习交流。如有版权问题,请与我联系,QQ:4156828  

© CopyRight 2008-2024 All Rights Reserved. Powered By bs178.com 闽ICP备11008920号-3
闽公网安备35020302034844号

Top