创作任务
实现以下功能
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();//关闭相机
}
}
}