项目任务

创作任务
实现以下功能
在这里插入图片描述
在这里插入图片描述
global.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace 串口编程
{
///
/// 静态类的
///
public static class Globar
{
static Globar()
{ }
/****************************************************************
* 对话框
* MessageBox.Show(“你确定要关闭吗!”, “提示信息”, MessageBoxButtons.OKCancel, MessageBoxIcon.Information);
* *************************************************************/

}

}
halcon.cs(准备不用)
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using HalconDotNet;//引用halcon
using System.Windows.Forms;//有个方法用到窗体控件,所以要引用窗体
using System.IO;//要读写文件

namespace 串口编程
{
static class my_Halcon
{
static my_Halcon()
{
}

    public static  HTuple WindowID;                         //Halcon窗体
    public static  HObject Image = null;                    //Halcon图像
    public static HTuple hv_XiangJiHandle = new HTuple();   //Halcon相机句柄
    /**************************************************************
     * 创建Halcon图像窗体
     * ***********************************************************/
    public static void CreateHalconWindow(PictureBox thisPictureBox)
    {
        HTuple FatherWindow = thisPictureBox.Handle;
        //设置窗口的背景颜色
        HOperatorSet.SetWindowAttr("background_color", "blue");
        //打开图像窗口
        HOperatorSet.OpenWindow(0, 0, thisPictureBox.Width, thisPictureBox.Height, FatherWindow, "visible", "", out WindowID);
    }
    
    /**************************************************************
     * 打开相机
     * ***********************************************************/
    public static void Open_camera()
    {
        //打开相机
        hv_XiangJiHandle.Dispose();
        HOperatorSet.OpenFramegrabber("DirectShow", 1, 1, 0, 0, 0, 0, "default", 8, "rgb",
    -1, "false", "default", "[0] XW500", 0, -1, out hv_XiangJiHandle);
        
        
        //HOperatorSet.OpenFramegrabber("DirectShow", 1, 1, 0, 0, 0, 0, "default", 8, "rgb",
        //    -1, "false", "default", "[0] Lenovo EasyCamera", 0, -1, out hv_XiangJiHandle);

        //通过指定的图像采集设备启动图像的异步采集
        HOperatorSet.GrabImageStart(hv_XiangJiHandle, -1);
    }
    /**************************************************************
     * 关闭相机
     * ***********************************************************/
    public static void Close_camera()
    {
        //关闭相机

        if (Image!=null)
            Image.Dispose();
        HOperatorSet.CloseFramegrabber(hv_XiangJiHandle);   
        hv_XiangJiHandle.Dispose();
    }
    /**************************************************************
     * 采集并显示图片
     * ***********************************************************/
    public static void Read_Image()
    {
        HTuple width = null, height = null;

        // 初始化局部变量和输出变量 
        HOperatorSet.GenEmptyObj(out Image);

        Image.Dispose();

        //采集图像
        HOperatorSet.GrabImageAsync(out Image, hv_XiangJiHandle, -1);

        //获取图像大小
        HOperatorSet.GetImageSize(Image, out width, out height);

        //通过改变图像的缩放来适应图像在窗口的正常显示
        HOperatorSet.SetPart(WindowID, 0, 0, height, width);

        HOperatorSet.DispObj(Image, WindowID);//显示图像

    }
    /**************************************************************
     * 保存图片
     * ***********************************************************/
    public static void SaveImage()
    {
        //保存图像
        string APP_Path = DrivesFiles.App_Path()+"/image" ;
        string DirName = DateTime.Now.ToString("yyyy年MM月dd日");//日期
        string myPath = APP_Path + "/" + DirName;
        if (DrivesFiles.Dir(myPath) == false)
            DrivesFiles.MkDir(myPath);
        
        string FileName = DateTime.Now.ToString("yyyy年MM月dd日HH时mm分ss秒fff毫秒");
        HOperatorSet.WriteImage(Image, "bmp", 0, myPath+"/" + FileName + ".bmp");
    }
    /**************************************************************
     * 保存报表
     * ***********************************************************/
    public static void SaveReport(string ResulteHeader, string ResultContent)
    {
        string APP_Path = DrivesFiles.App_Path() + "/Report";
        if (DrivesFiles.Dir(APP_Path) == false)
            DrivesFiles.MkDir(APP_Path);
        
        string FileName = DateTime.Now.ToString("yyyy年MM月dd日");//日期
        bool flag = File.Exists(@"Report/" + FileName + ".csv");//判断debug文件夹下是否存在文件
        if (!flag)
        {
            WriteCsv(@"Report/" + FileName + ".csv", ResulteHeader);//写标题
            WriteCsv(@"Report/" + FileName + ".csv", ResultContent);//写内容
        }
        else
        {
            WriteCsv(@"Report/" + FileName + ".csv", ResultContent);//写内容
        }
    }
    /**************************************************************
     * 写csv文件
     * ***********************************************************/
    private static void WriteCsv(string FilePath, string WriteContent)
    {
        //打开一个文件流
        FileStream fs = new FileStream(FilePath, FileMode.Append);
        //处理文本文件的类
        StreamWriter sw = new StreamWriter(fs, Encoding.Default);
        sw.Write(WriteContent + "\n");
        sw.Close();
        fs.Close();
    }


    public static void 矩形ROI()
    {
        HObject ho_Image, ho_Circle;

        // Local control variables 
        HTuple hv_NewRow = null, hv_NewColumn = null, hv_NewRadius = null;
        // Initialize local and output iconic variables 
        HOperatorSet.GenEmptyObj(out ho_Image);
        HOperatorSet.GenEmptyObj(out ho_Circle);

        //设置显示对象颜色
        HOperatorSet.SetColor(WindowID, "red");

        //设置区域填充模式为margin
        HOperatorSet.SetDraw(WindowID, "margin");

        //创建一个圆形ROI
        HOperatorSet.DrawCircle(WindowID, out hv_NewRow, out hv_NewColumn, out hv_NewRadius);

        //生成一个圆
        ho_Circle.Dispose();
        HOperatorSet.GenCircle(out ho_Circle, hv_NewRow, hv_NewColumn, hv_NewRadius);

        //显示圆
        HOperatorSet.DispObj(ho_Circle, WindowID);

        ho_Image.Dispose();
        ho_Circle.Dispose();
    }

}//end static class my_Halcon

}

register.cs 注册表

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Win32;//注册表要引用这个

//关于c#使用vs调试出现不允许所请求的注册表访问权
//https://blog.csdn.net/qq_32965233/article/details/79651871?utm_medium=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-1.control&depth_1-utm_source=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-1.control

namespace 串口编程
{
static class my_regedit
{
///
/// 构造函数
///
static my_regedit()
{

    }
    /**************************************************************
     * //C#读写注册表参考文章
     * //https://www.cnblogs.com/candyzhmm/p/7922079.html
     *************************************************************/
    ///<summary>
    /// 一、引用using Microsoft.Win32;
    /// </summary>

    /// <summary>
    /// 二、创建注册表项:CreateSubKey(name)方法
    ///添加SubKey时候首先要打开一个表项,并设置参数为true,才能成功创建子项
    /// </summary>
    private static void CreateApp(string AppName)
    {
        //VB:[HKEY_CURRENT_USER\Software\VB and VBA Program Settings]
        //SOFTWARE在LocalMachine分支下
        RegistryKey Section1 = Registry.CurrentUser.OpenSubKey("SOFTWARE", true);//打开表项
        RegistryKey Section3 = Section1.OpenSubKey("VB and VBA Program Settings", true);//打开表项
        RegistryKey CreateApp = Section3.CreateSubKey(AppName);//新建子项
        RegistryKey SectionApp = CreateApp.OpenSubKey(AppName, true);//打开刚才新建的子项
    }
    private static void CreateSection(string AppName, string SectionName)
    {
        RegistryKey Section1 = Registry.CurrentUser.OpenSubKey("SOFTWARE", true);//打开表项
        RegistryKey Section3 = Section1.OpenSubKey("VB and VBA Program Settings", true);//打开表项
        RegistryKey SectionApp = Section3.OpenSubKey(AppName, true);//
        RegistryKey CreateSection = SectionApp.CreateSubKey(SectionName);//新建子项
        RegistryKey SectionSection = CreateSection.OpenSubKey(SectionName, true);
    }

    /// <summary>
    /// 三、删除注册表项:DeleteSubKey(name,true)方法
    /// 删除注册表项:DeleteSubKey(name,true)方法
    /// </summary>
    public static void DeleteApp(string AppName)
    {
        RegistryKey Section1 = Registry.CurrentUser;
        RegistryKey Section2 = Section1.OpenSubKey("SOFTWARE", true);
        RegistryKey Section3 = Section2.OpenSubKey("VB and VBA Program Settings", true);
        Section3.DeleteSubKey(AppName, true);
    }
    public static void DeleteSection(string AppName, string Section)
    {
        RegistryKey Section1 = Registry.CurrentUser;
        RegistryKey Section2 = Section1.OpenSubKey("SOFTWARE", true);
        RegistryKey Section3 = Section2.OpenSubKey("VB and VBA Program Settings", true);
        RegistryKey SectionApp = Section3.OpenSubKey(AppName, true);
        SectionApp.DeleteSubKey(Section, true);
    }



    /// <summary>
    /// 四、添加键值:SetValue(name,value)方法
    /// 将path写入OPenLog子项
    /// </summary>
    public static void WriteKeyValue(string AppName, string SectionName, string KeyName, object KeyValue)
    {
        RegistryKey Section1 = Registry.CurrentUser;
        RegistryKey Section2 = Section1.OpenSubKey("SOFTWARE", true);
        RegistryKey Section3 = Section2.OpenSubKey("VB and VBA Program Settings", true);
        RegistryKey SectionApp = Section3.OpenSubKey(AppName, true);
        RegistryKey SectionSection = SectionApp.OpenSubKey(SectionName, true);
        SectionSection.SetValue(KeyName, KeyValue);
    }
    public static object ReadKeyValue(string AppName, string SectionName, string KeyName)
    {
        RegistryKey Section1 = Registry.CurrentUser;
        RegistryKey Section2 = Section1.OpenSubKey("SOFTWARE", true);
        RegistryKey Section3 = Section2.OpenSubKey("VB and VBA Program Settings", true);
        RegistryKey SectionApp = Section3.OpenSubKey(AppName, true);
        RegistryKey SectionSection = SectionApp.OpenSubKey(SectionName, true);
        return SectionSection.GetValue(KeyName);
    }
    /// <summary>
    /// 五、删除键值:DeleteValue(name)方法
    /// </summary>
    /// <param name="path"></param>
    public static void DeleteRegistFile(string AppName, string SectionName, string KeyName)
    {
        RegistryKey Section1 = Registry.CurrentUser;
        RegistryKey Section2 = Section1.OpenSubKey("SOFTWARE", true);
        RegistryKey Section3 = Section2.OpenSubKey("VB and VBA Program Settings", true);
        RegistryKey SectionApp = Section3.OpenSubKey(AppName, true);
        RegistryKey SectionSection = SectionApp.OpenSubKey(SectionName, true);
        SectionSection.DeleteValue(KeyName);
    }

    /// <summary>
    ///六、判断注册表项是否存在:
    /// 判断注册表项是否存在
    /// </summary>
    /// <returns>bool</returns>
    public static bool IsHaveAppName(string AppName)
    {
        string[] SectionNames;
        RegistryKey Section1 = Registry.CurrentUser;
        RegistryKey Section2 = Section1.OpenSubKey("SOFTWARE", true);
        RegistryKey Section3 = Section2.OpenSubKey("VB and VBA Program Settings", true);
        SectionNames = Section3.GetSubKeyNames();
        foreach (string SectionName in SectionNames)
        {
            if (SectionName == AppName)
            {
                Section1.Close();
                return true;
            }
        }
        Section1.Close();
        return false;
    }
    public static bool IsHaveSectionName(string AppName, string SectionName)
    {
        string[] SectionNames;
        RegistryKey Section1 = Registry.CurrentUser;
        RegistryKey Section2 = Section1.OpenSubKey("SOFTWARE", true);
        RegistryKey Section3 = Section2.OpenSubKey("VB and VBA Program Settings", true);
        RegistryKey SectionApp = Section3.OpenSubKey(AppName, true);
        SectionNames = SectionApp.GetSubKeyNames();
        foreach (string strSection in SectionNames)
        {
            if (strSection == SectionName)
            {
                Section1.Close();
                return true;
            }
        }
        Section1.Close();
        return false;
    }

    /// <summary>
    /// 七、判断键值是否存在:
    /// 判断该路径是否已经存在
    /// </summary>
    /// <param name="path">路径</param>
    /// <returns></returns>
    
    public static bool IsHaveKey(string AppName, string SectionName, string KeyName)
    {
        string[] KeyNames;
        RegistryKey Section1 = Registry.CurrentUser;
        RegistryKey Section2 = Section1.OpenSubKey("SOFTWARE", true);
        RegistryKey Section3 = Section2.OpenSubKey("VB and VBA Program Settings", true);
        RegistryKey SectionApp = Section3.OpenSubKey(AppName, true);
        RegistryKey SectionSection = SectionApp.OpenSubKey(SectionName, true);
        KeyNames = SectionSection.GetSubKeyNames();
        foreach (string strName in KeyNames)
        {
            if (strName == KeyName)
            {
                Section1.Close();
                return false;
            }
        }
        Section1.Close();
        return true;
    }
    /******************************************
     * VB中有三个函数,用于操作注册表
     * GetSetting
     * SaveSetting
     * DeleteSetting
     * 这三个函数只能在
     * [HKEY_CURRENT_USER\Software\VB and VBA Program Settings]
     * 创建“子键”、“值项”、“键值”
     * 
     * 语法
     * GetSetting(AppName As String, Section As String, Key As String, [Default]) As String
     * SaveSetting(AppName As String, Section As String, Key As String, Setting As String)
     * ****************************************/
    public static Boolean SaveSetting(string AppName, string Section, string KeyName, object KeyValue)
    {
        //如果APP不存在,则新建APP
        if (IsHaveAppName(AppName) == false)
            CreateApp(AppName);
        //如果文件夹不存在,则新建文件夹
        if (IsHaveSectionName(AppName, Section) == false)
            CreateSection(AppName, Section);
        WriteKeyValue(AppName, Section, KeyName, KeyValue);
        return true;
    }
    public static object GetSetting(string AppName, string Section, string KeyName,  object MoRenValue)
    {
        //如果APP不存在,则新建APP
        if (IsHaveAppName(AppName) == false)
            return MoRenValue;
        else if (IsHaveSectionName(AppName, Section) == false)
            return MoRenValue;
        else if (IsHaveKey(AppName, Section, KeyName) == false)
            return MoRenValue;
        else
            return ReadKeyValue(AppName, Section, KeyName);

    }
}

}
线程cs
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.Threading;//多线程类

namespace 串口编程
{
//静态类 static class
static class my_Thread
{
static my_Thread()
{
}
/***************************************************
* 读取FIFO中的数据,串口控件进行发送
* ************************************************/
public static Boolean Flag_Enable_Thread串口发送;
public static void Start_Thread串口发送()
{
//创建无参的线程
Thread thread_串口发送 = new Thread(new ThreadStart(Thread串口发送));
//调用Start方法执行线程
thread_串口发送.Start();
my_Thread.Flag_Enable_Thread串口发送 = true;
}
static void Thread串口发送()
{
do
{
System.Threading.Thread.Sleep(5); //毫秒
if (Form1.Com_status == 0)//空闲状态
{
string string_Temp = “”;
try
{
//首先判断串口是否开启
if (Form1.静态form1.serialPort1.IsOpen)
{
//串口处于开启状态,将发送区文本发送
if (FIFO_COM.Get_FiFO(ref Form1.静态form1.Send_Com_buf, ref PLC_FX_编程口协议.string_Now_Send_PLC_FX_Order))
{
Form1.静态form1.serialPort1.Write(Form1.静态form1.Send_Com_buf, 0, Form1.静态form1.Send_Com_buf.Length);
Form1.Com_status = (byte)Form1.my_Com_status.等待响应;//串口通讯状态=等待响应
for (byte i = 0; i < Form1.静态form1.Send_Com_buf.Length; i++)
string_Temp = string_Temp + Convert.ToString(Form1.静态form1.Send_Com_buf[i] / 0x10) + Convert.ToString(Form1.静态form1.Send_Com_buf[i] % 0x10) + " ";
if (Form1.静态form1.textBox_send.Text.Length >= 100)
Form1.静态form1.textBox_send.Text = “”;
Form1.静态form1.textBox_send.Text = Form1.静态form1.textBox_send.Text + Environment.NewLine + string_Temp;
Form1.静态form1.textBox_send.SelectionStart = Form1.静态form1.textBox_send.Text.Length;
Form1.静态form1.textBox_send.ScrollToCaret();
}
}
}
catch (Exception ex)
{
//捕获到异常,创建一个新的对象,之前的不可以再用
Form1.静态form1.serialPort1 = new System.IO.Ports.SerialPort();
//响铃并显示异常给用户
System.Media.SystemSounds.Beep.Play();
MessageBox.Show(ex.Message);
}
}
} while (my_Thread.Flag_Enable_Thread串口发送 == true);

    }
    /***************************************************
     * 通讯超时
     * ************************************************/
    /// <summary>
    /// timer_通讯超时
    /// sub_Send_FX_Order函数:serialPort1发送串口数据后,使能 timer_通讯超时
    /// SerialPort1_DataReceived:serialPort1接收到响应数据后,
    /// 根据判断,s_通讯等待计时 = 0
    /// 当 s_通讯等待计时 >= s_通讯超时设定时间 则判断为通讯超时
    /// 通讯超时,则将FIFO_COM.Com_status = 0;以便于再次发送串口命令
    /// </summary>
    public static Boolean Flag_Enable_Thread通讯超时;
    public static int s_通讯超时设定时间 = 200;
    public static void Start_Thread通讯超时()
    {
        //创建无参的线程
        Thread thread_通讯超时 = new Thread(new ThreadStart(Thread通讯超时));
        //调用Start方法执行线程
        thread_通讯超时.Start();
        my_Thread.Flag_Enable_Thread通讯超时 = true;
    }
    static void Thread通讯超时()
    {
        do
        {
            //首先判断串口是否开启
            if (Form1.静态form1.serialPort1.IsOpen)
            {
                if (Form1.Com_status != 0)//空闲状态
                {
                    System.Threading.Thread.Sleep(50); //毫秒
                    Form1.s_通讯等待计时 = Form1.s_通讯等待计时 + 50;
                    if (Form1.s_通讯等待计时 >= s_通讯超时设定时间)
                    {
                        Form1.s_通讯等待计时 = 0;
                        Form1.Com_status = 0;//空闲状态
                        Form1.静态form1.lab_串口信息.Text = "通讯超时";
                    }

                }
                else
                {
                    Form1.s_通讯等待计时 = 0;
                }
            }
            else
                Form1.静态form1.lab_串口信息.Text = "串口已关闭";
        } while (true);

    }
    /***************************************************
     * 参数主界面读取PLC数据的进程
     * ************************************************/
    public static Boolean Flag_Enable_Thread主界面;
    public static void Start_Thread主界面()
    {
        //创建无参的线程
        Thread thread_主界面 = new Thread(new ThreadStart(Thread主界面));
        //调用Start方法执行线程
        thread_主界面.Start();
        my_Thread.Flag_Enable_Thread主界面 = true;
    }
    static void Thread主界面()
    {
        do
        {
            System.Threading.Thread.Sleep(30); //毫秒
            //Delay(50); //毫秒 
            if (Form1.静态form1.serialPort1.IsOpen)
            {
                Form1.静态form1.FXPLC_Order0_Read_to_FIFO("M0251", 1);
            }
        } while (my_Thread.Flag_Enable_Thread主界面 == true);

    }
    /***************************************************
     * 参数设置界面读取PLC数据的进程
     * ************************************************/
    public static Boolean Flag_Enable_Thread参数设置;
    public static void Start_Thread参数设置()
    {
        //创建无参的线程
        Thread thread_参数设置 = new Thread(new ThreadStart(Thread参数设置));
        //调用Start方法执行线程
        thread_参数设置.Start();
        my_Thread.Flag_Enable_Thread参数设置 = true;
    }
    static void Thread参数设置()
    {
        do
        {
            System.Threading.Thread.Sleep(30); //毫秒
            //Delay(50); //毫秒 
            if (Form1.静态form1.serialPort1.IsOpen)
            {
                Form1.静态form1.FXPLC_Order0_Read_to_FIFO("D0150", 6);
                Form1.静态form1.FXPLC_Order0_Read_to_FIFO("D0200", 22);
                Form1.静态form1.FXPLC_Order0_Read_to_FIFO("S0000", 1);
                Form1.静态form1.FXPLC_Order0_Read_to_FIFO("Y0000", 2);
                Form1.静态form1.FXPLC_Order0_Read_to_FIFO("M0048", 2);
                Form1.静态form1.FXPLC_Order0_Read_to_FIFO("M0496", 2);
            }
        } while (my_Thread.Flag_Enable_Thread参数设置 == true);

    }
    /***************************************************
     * 视觉识别线程
     * ************************************************/
    public static Boolean Flag_Enable_Thread视觉识别;
    public static Boolean Flag_Enable_SaveImage;//是否保存图片的标志位
    public static void Start_Thread视觉识别()
    {
        //创建无参的线程
        Thread thread_视觉识别 = new Thread(new ThreadStart(Thread视觉识别));
        my_Thread.Flag_Enable_Thread视觉识别 = true;
        //调用Start方法执行线程
        thread_视觉识别.Start();
    }
    static void Thread视觉识别()
    {
        my_Halcon.Open_camera();//打开相机
        do
        {
            if (PLC_FX_编程口协议.PLC_FX_M[251] == true)
            {
                my_Halcon.Read_Image();//采集并显示图片
                if (Flag_Enable_SaveImage==true)
                    my_Halcon.SaveImage();//保存图片
            }
            System.Threading.Thread.Sleep(30); //毫秒
        } while (my_Thread.Flag_Enable_Thread视觉识别 == true);
        my_Halcon.Close_camera();//关闭相机
    }
    
}

}

猜你喜欢

转载自blog.csdn.net/tel_1392/article/details/113785217