using System; using System.Collections.Generic; using System.Drawing; using System.Windows.Forms; using System.Threading; using System.Diagnostics; using StandardLibrary; using System.IO; using BZFAStandardLib; using System.Text; using System.IO.Ports; using System.Xml.Linq; using AxActUtlTypeLib; using Newtonsoft.Json.Linq; using Newtonsoft.Json; namespace MainForm { public partial class Form_Auto : Form { InovancePlc PLC_huichuan = new InovancePlc(0, "192.168.1.10", 502); AxActUtlType PLC_sanling=new AxActUtlType();//三菱PLC private object obj = new object(); private int plcConnect = 1;//三菱PLC连接标志位 bool Scanner1Status = false;//扫枪连接标志位 bool Scanner2Status = false; bool Scanner3Status = false; private SerialPort Scanner1 = new SerialPort(AutoTool.Scom1, 115200);//扫枪串口 public WebParameter web_Parameter = new WebParameter();//配置参数 #region MES变量定义 /// /// mes函数执行成功 /// public const int MesBackOK = 0; /// /// MES的句柄 /// public static int hMes = 0; public static int WriteLogFile(StringBuilder data) { //MessageBox.Show(data.ToString()); return 0; } HQMES.MESBackFunc tempFunc;// 必须要加一个变量,这样不会被回收 #endregion public Form_Auto() { InitializeComponent(); CheckForIllegalCrossThreadCalls = false; } #region 控件随窗体自动变化 /// /// 自动调整空间大小; /// private Size m_szInit;//初始窗体大小; private Dictionary m_dicSize = new Dictionary(); protected override void OnLoad(EventArgs e) { m_szInit = this.Size;//获取初始大小; this.GetInitSize(this); base.OnLoad(e); } private void GetInitSize(Control ctrl) { foreach (Control c in ctrl.Controls) { m_dicSize.Add(c, new System.Drawing.Rectangle(c.Location, c.Size)); this.GetInitSize(c); } } protected override void OnResize(EventArgs e) { //计算当前大小和初始大小的比例; float fx = (float)this.Width / m_szInit.Width; float fy = (float)this.Height / m_szInit.Height; foreach (var v in m_dicSize) { v.Key.Left = (int)(v.Value.Left * fx); v.Key.Top = (int)(v.Value.Top * fy); v.Key.Width = (int)(v.Value.Width * fx); v.Key.Height = (int)(v.Value.Height * fy); } base.OnResize(e); } protected override CreateParams CreateParams { get { CreateParams cp = base.CreateParams; cp.ExStyle |= 0x02000000; return cp; } } #endregion private void Form_Auto_Load(object sender, EventArgs e) { this.Controls.Add(PLC_sanling); Thread doworkThr = new Thread(flushDoWork); doworkThr.IsBackground = true; doworkThr.Start(); #region PLC初始化 try { PLC_sanling.ActLogicalStationNumber = 1; PLC_sanling.ActPassword = ""; plcConnect = PLC_sanling.Open(); if (plcConnect==0) { PLCtimer.Enabled = true; labPLCStatus.BackColor = Color.Green; labPLCStatus.Text = "已连接"; AddMessage("与PLC通讯连接成功"); } else { PLCtimer.Enabled = false; labPLCStatus.BackColor = Color.Red; labPLCStatus.Text = "未连接"; AddMessage("与PLC通讯连接失败"); } } catch (Exception ex) { plcConnect = 1; MessageBox.Show(ex.ToString()); AddMessage("与PLC通讯连接异常,检查通讯线路"); } #endregion #region 扫枪串口初始化 try { Scanner1.Open(); Scanner1Status = true; if (Scanner1Status) { COMstatus.BackColor = Color.Green; COMstatus.Text = "已连接"; AddMessage("与扫码枪1连接成功"); } else { COMstatus.BackColor = Color.Red; COMstatus.Text = "未连接"; AddMessage("与扫码枪1连接失败"); } } catch (Exception ex) { MessageBox.Show(ex.ToString()); AddMessage("扫码枪1连接异常,检查通讯线路"); } #endregion #region MES初始化 MesInit(); #endregion ReadXmlStatistics(); AutoTool.save += SaveXmlStatistics; } short[] D7000 = new short[10]; short[] D7010 = new short[5]; short[] D7021 = new short[4]; short temp0 = 0; short temp1 = 1; short temp2 = 2; string[] SN = new string[] { }; private void flushDoWork()//工作主线程 { while (true) { if (D7000[0] == 1)//扫码工位PLC请开启扫码 { PLC_sanling.WriteDeviceBlock2("D7000", 1, ref temp0); FixtureSN.Text=Scaner();//扫枪扫码 if (FixtureSN.Text != "") { //MES获取信息 D7010[0] = 1; D7010[1] = 1; D7010[2] = 1; D7010[3] = 1; D7010[4] = 1; PLC_sanling.WriteDeviceBlock2("D7010",5, ref D7010[0]);//给PLC产品状态 } else { PLC_sanling.WriteDeviceBlock2("D7010",1,ref temp2);//扫码失败 AddMessage("条码扫描失败!"); } InRefresh(D7010[1],D7010[2],D7010[3],D7010[4]);//刷新按钮状态 }//D7000 if (D7000[1] == 1)//机械手工位PLC请记录载具4穴状态 { PLC_sanling.WriteDeviceBlock2("D7001",1,ref temp0); PLC_sanling.ReadDeviceBlock2("D7021",4,out D7021[0]);//从PLC读取当前产品状态 //MES上传 OutRefresh(D7021[0],D7021[1],D7021[2],D7021[3]); PLC_sanling.WriteDeviceBlock2("D7020",1,ref temp1); }//D7001 if (D7000[2] == 1)//人工1工位PLC请开启扫码 { PLC_sanling.WriteDeviceBlock2("D7002",1,ref temp0); //扫枪扫码 //MES获取信息 PLC_sanling.WriteDeviceBlock2("D7030", 5, ref D7010[0]); }//D7002 if (D7000[3] == 1)//人工2工位PLC请开启扫码 { PLC_sanling.WriteDeviceBlock2("D7003", 1, ref temp0); //扫枪扫码 //MES获取信息 PLC_sanling.WriteDeviceBlock2("D7040", 5, ref D7010[0]); }//D7003 Thread.Sleep(800); } } private void PLCtimer_Tick(object sender, EventArgs e)//读取PLC寄存器 { // PLCtimer.Stop(); // PLC.H3u_Read_Int16(InovancePlc.Soft.REGI_H3U_DW, 1000, 7, ref RealValue); try { PLC_sanling.ReadDeviceBlock2("D7000", 10, out D7000[0]); } catch(Exception ex) { PLCtimer.Enabled = false; labPLCStatus.BackColor = Color.Red; labPLCStatus.Text = "未连接"; AddMessage("与PLC通讯连接失败"); } // PLCtimer.Start(); } private void AddMessage(string message) { messageLog(message); string time = DateTime.Now.ToString("yyyy.MM.dd-HH:mm:ss"); string msgShow = time + "--> " + message + "\r\n"; this.BeginInvoke(new Action(() => { dataGridView_current.Rows.Insert(0, time, message); if (dataGridView_current.Rows.Count >= 100) dataGridView_current.Rows.RemoveAt(dataGridView_current.Rows.Count - 1); })); } private void messageLog(string msg) { string path = AppDomain.CurrentDomain.BaseDirectory + "MsgLog\\"; if (!Directory.Exists(path)) Directory.CreateDirectory(path);//判断路径是否存在,不存在则创建路径 string FLogFile = path + "Log\\" + DateTime.Now.ToString("yyyy.MM.dd") + ".txt"; string now = DateTime.Now.ToString("yyyy.MM.dd HH:mm:ss") + "--->"; try { if (File.Exists(FLogFile))//判断log文件是否存在; TxtFile.WriteTxtFile(FLogFile, now + msg + "\r\n"); //存在则直接写入; else TxtFile.NewTxtFile(FLogFile, now + msg + "\r\n"); //不存在则新建并写入; } catch (Exception ex) { MessageBox.Show("异常:" + ex.Message, "Log保存", MessageBoxButtons.OK, MessageBoxIcon.Error); } } private void COMstatus_Click(object sender, EventArgs e) { try { if (!Scanner1.IsOpen) { Scanner1.Open(); Scanner1Status = true; if (Scanner1Status) { COMstatus.BackColor = Color.Green; COMstatus.Text = "已连接"; AddMessage("与扫码枪连接成功"); } else { COMstatus.BackColor = Color.Red; COMstatus.Text = "未连接"; AddMessage("与扫码枪连接失败"); } } else { AddMessage("串口已经打开!"); } } catch (Exception ex) { MessageBox.Show(ex.ToString()); AddMessage("扫码枪连接异常,检查通讯线路"); } //if (!isSFIS) //{ // if (sfis.WebServiceLogin()) // { // ScanerStatus.BackColor = Color.Green; // currentOP.Text = web_Parameter.op; // isSFIS = true; // } // else // { // MessageBox.Show("登录SFIS系统失败,请检查后重新登录"); // AddMessage("登录失败,请检查SFIS网络!"); // } //} //else //{ // sfis.WebServiceLogout(); // isSFIS = false; // ScanerStatus.BackColor = Color.Red; //} } private void saveCsv(string SN,string result) { lock (obj) { StreamWriter sw1 = null; string savePath = "D:\\TestData"; if (!Directory.Exists(savePath)) { Directory.CreateDirectory(savePath); } string dataPathStr = savePath + "\\" + DateTime.Now.ToString("yyyy-MM-dd") + ".csv"; if (!File.Exists(dataPathStr)) { sw1 = new StreamWriter(dataPathStr, true, Encoding.UTF8); sw1.WriteLine("txtBarcode,Y/M/D,H:M:S,RESULT,data1,data2,data3,data4"); sw1.Dispose(); } sw1 = new StreamWriter(dataPathStr, true, Encoding.UTF8); sw1.WriteLine(SN + "," + DateTime.Now.ToString("yyyy/MM/dd") + "," + DateTime.Now.ToString("HH:mm:ss") + "," + result); sw1.Dispose(); } } //private void Temperature1Show(double data) //{ // this.BeginInvoke(new Action(() => // { // hole1.Temperature=(float) temperature1.TemperatureValue; // })); //} #region 数据统计 private string strPath2 = "statistics.xml"; public void CreadXmlStatistics() { XDocument docCount; docCount = new XDocument( new XDeclaration("1.0", "utf-8", "yes"), new XElement("ProductData", new XElement("Count", new XElement("passNum", 0), new XElement("failNum", 0)) ) ); docCount.Save(strPath2); } private void ReadXmlStatistics() { try { if (!File.Exists(strPath2)) { CreadXmlStatistics(); } //加载XML文件 XDocument xdoc = XDocument.Load(strPath2); //获取XML文件根节点 XElement rootNode = xdoc.Root; //获取根节点下面对应的值 XElement childNode0 = rootNode.Element("Count").Element("passNum"); XElement childNode1 = rootNode.Element("Count").Element("failNum"); OK.Text = childNode0.Value; NG.Text = childNode1.Value; Total.Text = (int.Parse(OK.Text) + int.Parse(NG.Text)).ToString(); } catch (Exception ex) { MessageBox.Show(ex.ToString()); } } private void SaveXmlStatistics() { lock (obj) { if (!File.Exists(strPath2)) { CreadXmlStatistics(); } //加载XML文件 XDocument xdoc = XDocument.Load(strPath2); //获取XML文件根节点 XElement rootNode = xdoc.Root; rootNode.Element("Count").ReplaceNodes( new XElement("passNum", OK.Text), new XElement("failNum", NG.Text)); xdoc.Save(strPath2); } } #endregion private void btnClear_Click(object sender, EventArgs e) { DialogResult result = MessageBox.Show("请确认是否对计数清零?", "清零", MessageBoxButtons.OKCancel, MessageBoxIcon.Information); if (result == DialogResult.OK) { OK.Text = ""; NG.Text = ""; Total.Text = ""; SaveXmlStatistics(); AddMessage("统计计数清零成功!"); } } private void labPLCStatus_Click(object sender, EventArgs e) { try { PLC_sanling.ActLogicalStationNumber = 1; PLC_sanling.ActPassword = ""; plcConnect = PLC_sanling.Open(); if (plcConnect == 0) { PLCtimer.Enabled = true; labPLCStatus.BackColor = Color.Green; labPLCStatus.Text = "已连接"; AddMessage("与PLC通讯连接成功"); } else { PLCtimer.Enabled = false; labPLCStatus.BackColor = Color.Red; labPLCStatus.Text = "未连接"; AddMessage("与PLC通讯连接失败"); } } catch (Exception ex) { plcConnect = 1; MessageBox.Show(ex.ToString()); AddMessage("与PLC通讯连接异常,检查通讯线路"); } } private string Scaner() { string rtn = ""; Scanner1.DiscardInBuffer(); if (Scanner1.IsOpen) { Scanner1.Write("TRIGGER"); Thread.Sleep(300); rtn = Scanner1.ReadExisting(); AddMessage("扫描条码:"+rtn); } else { rtn = "扫枪串口打开失败"; AddMessage("扫枪串口未打开"); } return rtn; } #region MES函数 private void MesInit() { int len = 102400; StringBuilder strdata = new StringBuilder(len); if (hMes == 0) { tempFunc = WriteLogFile; // 必须要加一个变量,这样不会被回收 这个回调函数赋值只能放在这个位置,防止当多次点击init之后可能会出现回调函数被回收的现象 if (0 == HQMES.MesInit(tempFunc, ref hMes, strdata, ref len)) { JObject jt = (JObject)JsonConvert.DeserializeObject(strdata.ToString()); string version = ""; version = jt.GetValue("H_MSG") == null ? "" : jt.GetValue("H_MSG").ToString();//获取meshelepr的版本 AddMessage("初始化链接MES成功!MEShelper版本:" + version);//strdata会返回一个meshelper的版本号表示初始化成功 MESstatus.BackColor = Color.Green; MESstatus.Text = "已连接"; } else { hMes = 0; AddMessage("初始化链接MES 失败 !"); MESstatus.BackColor = Color.Red; MESstatus.Text = "未连接"; } ; } else { AddMessage("请勿重复初始化MES链接!"); } } private void MesStart(string SN) { if (hMes != 0) { int len = 102400; StringBuilder strdata = new StringBuilder(len); //StringBuilder SN = new StringBuilder("12345678901002"); //StringBuilder ActionName = new StringBuilder("BT"); //StringBuilder toolName = new StringBuilder("PRESSTOOL"); string ActionName = web_Parameter.Station; string toolName = web_Parameter.Tool; string data = ""; string msg = ""; string retdata = ""; string needload = ""; if (0 == HQMES.MesStart(hMes, SN, ActionName, toolName, strdata, ref len)) { AddMessage("链接MES 成功 !" + strdata.ToString()); //start参数的解析,具体字段定义请参考《华勤MESHelper接口工具使用说明》 JObject jo = (JObject)JsonConvert.DeserializeObject(strdata.ToString()); data = jo.GetValue("DATA") == null ? "" : jo.GetValue("DATA").ToString(); //data是一个json字符串,其中包含mes返回的主要字段,按照这个参考继续解析出来 例如获取CSN JObject jb = (JObject)JsonConvert.DeserializeObject(data); string CSN = jb.GetValue("CSN") == null ? "" : jb.GetValue("CSN").ToString(); // msg = jo.GetValue("H_MSG") == null ? "" : jo.GetValue("H_MSG").ToString(); retdata = jo.GetValue("G_RET_DATA") == null ? "" : jo.GetValue("G_RET_DATA").ToString();//标记工具需要回传给MES的字段,是json格式,将其解析出来可以得到字段,工具必须将该字段赋值并回传给MES,在endmes函数回传 needload = jo.GetValue("NeedLoad") == null ? "" : jo.GetValue("NeedLoad").ToString();//标记工具是否需要重启 //解析结束 } else { JObject jo = (JObject)JsonConvert.DeserializeObject(strdata.ToString()); msg = jo.GetValue("H_MSG") == null ? "" : jo.GetValue("H_MSG").ToString();//mes返回的错误信息最好将其在工具界面展示出来给操作人员查看 AddMessage("链接MES 失败 !" + strdata.ToString()); } } else { AddMessage("请初始化MES链接!"); } } private void MesStart2(string SN) { if (hMes != 0) { int len = 102400; StringBuilder strdata = new StringBuilder(len); //StringBuilder SN = new StringBuilder("12345678901002"); //StringBuilder ActionName = new StringBuilder("BT"); //StringBuilder toolName = new StringBuilder("PRESSTOOL"); string ActionName = web_Parameter.Station; string toolName = web_Parameter.Tool; string SNType = "9";//表示流程检查的输入数据类型:1 SN 2 IMEI 3 CSN 4 蓝牙 5 WiFi 6 入网证 if (0 ==HQMES.MesStart2(hMes, SN, SNType, ActionName, toolName, strdata, ref len)) { //这个函数返回的值跟MesStart一样,请参考MesStart的解析参数的操作 AddMessage("链接MES 成功 !" + strdata.ToString()); } else { AddMessage("链接MES 失败 !" + strdata.ToString()); var jObject = JObject.Parse(strdata.ToString()); var ss = jObject["Data"]["AutoUnlock"]; } } else { MessageBox.Show("请初始化MES链接!"); } } private void MesEnd(string SN,string ErrorCode) { if (hMes != 0) { int len = 102400; StringBuilder strdata = new StringBuilder(len); strdata.Append(web_Parameter.ErrorCode);//错误代码 string ActionName =web_Parameter.Station;//工具动作 string toolName = web_Parameter.Tool;//工具版本 //string ErrorCode = textBox1.Text;//错误码 0表示测试成功,其它表示失败 string nextws = "";//表示下一个工位 string msg = "";//过站的错误信息 if (0 ==HQMES.MesEnd(hMes, SN, ActionName, toolName, ErrorCode, strdata, ref len)) { JObject jo = (JObject)JsonConvert.DeserializeObject(strdata.ToString()); msg = jo.GetValue("H_MSG") == null ? "" : jo.GetValue("H_MSG").ToString(); nextws = jo.GetValue("G_NEXTWS") == null ? "" : jo.GetValue("G_NEXTWS").ToString(); AddMessage("保存数据到MES 成功 !" + strdata.ToString()); } else { JObject jo = (JObject)JsonConvert.DeserializeObject(strdata.ToString()); msg = jo.GetValue("H_MSG") == null ? "" : jo.GetValue("H_MSG").ToString();//表示过站的错误信息,最好展示在工具的界面方便操作人员查看 AddMessage("保存数据到MES 失败 !" + strdata.ToString()); } } else { AddMessage("请初始化MES链接!"); } } private void MesEnd2(string SN,string AllData) { if (hMes != 0) { int len = 102400; StringBuilder strdata = new StringBuilder(len); strdata.Append(web_Parameter.ErrDescription); string ActionName = web_Parameter.Station; string toolName = web_Parameter.Tool; string ErrorCode = web_Parameter.ErrorCode; // string AllData = textBox2.Text;//表示需要回传给mes的字段,json字符串形式传递 string SNType = "9";// //start //假设需要回传的字段为a,值为1,将字段a上抛 //JObject data = new JObject(); //data.Add("a", "1"); //AllData = data.ToString(); //当遇到数据较多的时候,可以使用Dictionary类型存储数据,然后序列化 //end if (0 ==HQMES.MesEnd2(hMes, SN, SNType, ActionName, toolName, ErrorCode/*G_CODE*/, AllData, strdata/*G_DESC*/, ref len)) { //这个函数返回的值跟MesEnd一样,请参考MesEnd的解析参数的操作 AddMessage("保存数据到MES 成功 !/r/n" + strdata.ToString()); } else { AddMessage("保存数据到MES 失败 !/r/n" + strdata.ToString()); } } else { AddMessage("请初始化MES链接!"); } } #endregion private void InRefresh(short d1,short d2,short d3,short d4) { //this.BeginInvoke(new Action(() => //{ //})); Status1.BackColor = (d1 == 1 ? Color.Green : Color.Red); Status2.BackColor = (d2 == 1 ? Color.Green : Color.Red); Status3.BackColor = (d3 == 1 ? Color.Green : Color.Red); Status4.BackColor = (d4 == 1 ? Color.Green : Color.Red); } private void OutRefresh(short d1, short d2, short d3, short d4) { SN1.BackColor = (d1 == 1 ? Color.Green : Color.Red); SN2.BackColor = (d2 == 1 ? Color.Green : Color.Red); SN3.BackColor = (d3 == 1 ? Color.Green : Color.Red); SN4.BackColor = (d4 == 1 ? Color.Green : Color.Red); } private void test_Click(object sender, EventArgs e) { Jstructrue demo1 = new Jstructrue(); Jstructrue demo2 = new Jstructrue(); demo2.name = "SN"; demo2.value = "1234567"; demo1.name = "data"; demo1.value = JsonConvert.SerializeObject(demo2); string y = JsonConvert.SerializeObject(demo1); // var json = new JsonSerializer().Deserialize(new JsonTextReader(new StringReader(y))); AddMessage(y); JObject a=(JObject)JsonConvert.DeserializeObject(y); string b = a.GetValue("value").ToString(); AddMessage(b); Scaner(); } public class Jstructrue//转换成json格式 { public string name { get; set; } public string value { get; set; } } } }