因为项目需要用到发那科机器的一些数据,在里面踩了无数的坑,终于写好了一个可以满足目前项目需求的程序。
回想起来真是心酸都不足以形容。。

先上一个采集端的界面,界面是很丑陋,但是胜在简单。:
在这里插入图片描述

机器的配置信息我都是写进数据库的,每次开启程序之前都要先查询一次数据库,然后再连接CNC机器一次,以获取相应的机器连接情况。这个也只是方便用户查看而已,没什么实际的作用,因为在这里获取的句柄在采集程序里面是用不了的。
原则上,我是没有用到全局变量,因为使用全局变量有很多问题需要考虑,什么全局加锁啦,什么的。反正我是不懂。

先上一个界面的代码:
先说一下数据库架构。
1:第一张表用来保存所有数据,方便以后统计停机时间什么的。
2:第二张表,只做更新数据,用来查询机器的当前运行状态。
所以我在程序了分了两个方法。


/***************************************************************
*               date:2018-11-30
*               By:Bevan
 * *            sappmis@163.com
 * *  说明:IP,机号添加面板。主要实现多线程开启采集功能。
 * *
 * ***************************************************************/
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.Data.SqlClient;
using System.Threading;

namespace SmachCNC
{
    public partial class Form1 : Form
    {
        public int sleepTime;
        private List<Thread> threadPool = new List<Thread>(); //创建第一个线程池,用来写数据库
        private List<Thread> threadPool2 = new List<Thread>();  //创建第二个线程池,用来更新实时数据

        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            ip_show(DGVip);
            ChangLabStatue();
            txtip1.Enabled = false;
            txtmachno1.Enabled = false;
            txtmodel.Enabled = false;
            txtname.Enabled = false;
            version.Enabled = false;
        }


        /// <summary>
        /// 将采集方法实例化,以方便多线程调用。我采用的是委托方法,使用多线程开启采集程序,所以需要先将采集方法实例化,以方便给线程传递参数。
        /// </summary>
        public class IndataCnc
        {
            private int sleeptime;
            private string IP;
            private string machno;
            public IndataCnc(string ip, string machno, int sleep)  //这个方法是LinkCnc();采集方法中需要的参数。这里一定要处理好,如果看不懂这个代码,建议多看看多线程方面的文章。或者搜索“”c#多线程调用有参数方法“”。
            {
                this.machno = machno;
                this.IP = ip;
                this.sleeptime = sleep;
            }
            public void funRun()
            {
                LinkCnc Lcnc = new LinkCnc();
                Lcnc.readCncToData(IP, machno, sleeptime);
            }
        }

        /// <summary>
        /// 使用实例化类给方法传参数。另一个方法。
        /// </summary>
        public class UpdataCnc
        {
            private string IP;
            private string machno;

            public UpdataCnc(string ip, string machno)
            {
                this.machno = machno;
                this.IP = ip;
            }
            public void funRun()
            {
                ReadCnc cnc = new ReadCnc();
                cnc.readCncUpData(IP, machno);
            }
        }

        /// <summary>
        /// 改变程序运行状态提示
        /// </summary>
        public void ChangLabStatue()
        {
            if (button2.Text == "启动程序")
            {
                labShowInfo1.Text = "程序已停止";
                labShowInfo1.ForeColor = Color.Red;
            }
            else
            {
                labShowInfo1.Text = "程序正在运行....";
                labShowInfo1.ForeColor = Color.Green;
            }
        }

        /// <summary>
        /// 将数据库中的机器信息带出面板。
        /// </summary>
        public void ip_show(DataGridView dgvw)
        {
            try
            {
                this.Invoke(new EventHandler(delegate
                {
                    string sql = "select * from machinfo order by machno";
                    DataSet ds = new DbHelp().QueryDataset(sql);
                    dsNum = ds.Tables[0].Rows.Count;
                    if (ds.Tables[0].Rows.Count > 0)
                    {
                        for (int i = 0; i < ds.Tables[0].Rows.Count; i++)
                        {
                            dgvw.Rows.Add();
                            dgvw.Rows[i].Cells[0].Value = ds.Tables[0].Rows[i]["machno"];
                            dgvw.Rows[i].Cells[1].Value = ds.Tables[0].Rows[i]["ip"];
                            dgvw.Rows[i].Cells[2].Value = ds.Tables[0].Rows[i]["port"];
                        }
                    }
                }
                ));
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }

        /// <summary>
        /// 判断机器是否连接成功
        /// </summary>
        /// <param name="num"></param>
        /// <returns></returns>
        public string getState(ushort num)
        {
            if (num > 0)
            {
                return "连接成功";
            }
            else return "机器离线";
        }

        /// <summary>
        /// 连接机器取回句柄号
        /// </summary>
        public void GetCncHandle()
        {
            DGVip.DataSource = null;
            string sql = "select * from machinfo";
            DataSet ds = new DbHelp().QueryDataset(sql);
            for (int i = 0; i < ds.Tables[0].Rows.Count; i++)
            {
                string Ip;
                ushort port;
                string statue;
                ushort fwlibHandle = 0;
                Ip = ds.Tables[0].Rows[i]["ip"].ToString();
                port = Convert.ToUInt16(ds.Tables[0].Rows[i]["port"].ToString());
                short ret = Focas1.cnc_allclibhndl3((object)Ip, port, 5, out fwlibHandle);
                statue = getState(fwlibHandle);
                DGVip.Rows[i].Cells[0].Value = ds.Tables[0].Rows[i]["machno"];
                DGVip.Rows[i].Cells[1].Value = ds.Tables[0].Rows[i]["ip"];
                DGVip.Rows[i].Cells[2].Value = ds.Tables[0].Rows[i]["port"];
                DGVip.Rows[i].Cells[3].Value = statue;
                DGVip.Rows[i].Cells[4].Value = fwlibHandle;
            }
        }



        /// <summary>
        /// 开启线程,循环将IP读出并传递给DLL
        /// </summary>
        public void startThreadPool()
        {
            if (txtsleeptime.Text != "")
            {
                sleepTime = Convert.ToInt32(txtsleeptime.Text.Trim());
            }
            else sleepTime = 30;  //这个数值我用的是30秒采集一次。
            try
            {
                for (int i = 0; i < DGVip.Rows.Count; i++)
                {
                    string machno = Convert.ToString(DGVip.Rows[i].Cells[0].Value.ToString());
                    string ip = Convert.ToString(DGVip.Rows[i].Cells[1].Value.ToString());
                    IndataCnc Icnc = new IndataCnc(ip, machno, sleepTime);
                    Thread thread = new Thread(new ThreadStart(Icnc.funRun));
                    this.threadPool.Add(thread);
                }
                foreach (Thread thread1 in this.threadPool)
                {
                    thread1.Start();
                }
            }
            catch (Exception ex) { MessageBox.Show(ex.Message); }
        }

        /// <summary>
        /// 开启第二线程池实时更新数据
        /// </summary>
        public void startThreadPool2()
        {
            for (int i = 0; i < DGVip.Rows.Count; i++)
            {
                string machno = Convert.ToString(DGVip.Rows[i].Cells[0].Value.ToString());
                ushort Handle = Convert.ToUInt16(DGVip.Rows[i].Cells[4].Value.ToString());
                string ip = Convert.ToString(DGVip.Rows[i].Cells[1].Value.ToString());
                UpdataCnc cnc = new SmachCNC.Form1.UpdataCnc(ip, machno);
                Thread thread = new Thread(new ThreadStart(cnc.funRun));
                threadPool2.Add(thread);
            }
            foreach (Thread thread1 in this.threadPool2)
            {
                thread1.Start();
            }
        }

        /// <summary>
        /// 停止按钮,并销毁线程
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void button2_Click(object sender, EventArgs e)
        {
            if (button2.Text == "停止程序")
            {
                stopThread();
                button2.Text = "启动程序";
                ChangLabStatue();
                return;
            }
            if (button2.Text == "启动程序")
            {
                GetCncHandle();
                startThreadPool();
                startThreadPool2();
                button2.Text = "停止程序";
                ChangLabStatue();
            }
        }

        /// <summary>
        /// 停止线程,并释放机器连接.
        /// </summary>
        public void stopThread()
        {
            foreach (Thread thread2 in this.threadPool2)
            {
                thread2.Abort();
            }
            foreach (Thread thread in this.threadPool)
            {
                thread.Abort();
            }
            cancelCncContion();
            this.threadPool2.Clear();
            this.threadPool.Clear();
        }

        /// <summary>
        /// 释放句柄,在停止程序的时候先释放所有句柄,因为这个句柄超过1024就连接不上了。
        /// </summary>
        private void cancelCncContion()
        {
            for (int i = 0; i < DGVip.Rows.Count; i++)
            {
                ushort handle = Convert.ToUInt16(DGVip.Rows[i].Cells[4].Value);
                int ret = Fanuc.cnc_freelibhndl(handle);
            }
        }

//以下代码都是些垃圾代码,用不用都无所谓。
        private void button1_Click(object sender, EventArgs e)
        {
            try
            {
                string machId = txtmachno.Text.Trim();
                string Ip = txtip.Text.Trim();
                ushort port = Convert.ToUInt16(txtport.Text.Trim());
                string btntxt = button2.Text;
                machInfo(machId, Ip, port, btntxt);
            }
            catch
            {
                MessageBox.Show("机号或者IP已经存在.");
            }
        }
        /// <summary>
        /// 判断Ip是否存在
        /// </summary>
        /// <param name="ip"></param>
        /// <returns></returns>
        public bool IsExistIp(string ip)
        {
            if (DGVip.Rows.Count - 1 > 0)
            {
                for (int i = 0; i < DGVip.Rows.Count; i++)
                {
                    if (DGVip.Rows[i].Cells[1].Value.ToString() == ip)
                    {
                        return false;
                    }
                }
            }
            return true;
        }
        /// <summary>
        /// 判断机号是否已经存在表中
        /// </summary>
        /// <param name="MachId"></param>
        /// <returns></returns>
        public bool IsMachId(string MachId)
        {
            if (DGVip.Rows.Count - 1 > 0)
            {
                for (int i = 0; i < DGVip.Rows.Count; i++)
                {
                    if (DGVip.Rows[i].Cells[1].Value.ToString() == MachId)
                    {
                        return false;
                    }
                    //else return false;
                }
            }
            return true;
        }
        /// <summary>
        /// 添加或者修改IP地址的方法体
        /// </summary>
        /// <param name="machId"></param>
        /// <param name="Ip"></param>
        /// <param name="port"></param>
        /// <param name="btnText"></param>
        public void machInfo(string machId, string Ip, ushort port, string btnText)
        {
            string inssql = "insert into machinfo (machno,ip,port)values('" + machId + "','" + Ip + "','" + port + "')";
            string upsql = "update machinfo set ip='" + Ip + "' where machno='" + machId + "'";
            if (button1.Text == "添加") //添加机器的配置
            {
                if (machId.Length > 0 || Ip.Length > 0 || port != 0)//判断文本框是否为空
                {
                    int y = new DbHelp().OperSql(inssql);
                    if (y > 0)
                    {
                        MessageBox.Show("添加成功.");
                        int x = this.DGVip.Rows.Add();
                        DGVip.Rows[x].Cells[0].Value = machId;
                        DGVip.Rows[x].Cells[1].Value = Ip;
                        DGVip.Rows[x].Cells[2].Value = port;
                    }
                }
            }
            else if (button1.Text == "修改")//修改机器的IP地址
            {
                int y = new DbHelp().OperSql(upsql);
                if (y > 0)
                {
                    MessageBox.Show("信息修改成功.");
                }
                DGVip.Rows.Clear();
                ip_show(DGVip);
            }
        }

        /// <summary>
        ///双击显示窗口中的IP将该IP拉取到文本框,以待修改。
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>

        private void DGVip_CellDoubleClick(object sender, DataGridViewCellEventArgs e)
        {
            int index = DGVip.CurrentCell.RowIndex;
            txtmachno.Text = DGVip.Rows[index].Cells[0].Value.ToString();
            txtip.Text = DGVip.Rows[index].Cells[1].Value.ToString();
            txtport.Text = DGVip.Rows[index].Cells[2].Value.ToString();
            txtmachno.Enabled = false;
            button1.Text = "修改";
                    }

        private void button4_Click(object sender, EventArgs e)
        {
            button1.Text = "添加";
            txtip.Text = "";
            txtmachno.Text = "";
            txtport.Text = "";
            txtmachno.Enabled = true;
        }

        private void Form1_FormClosing(object sender, FormClosingEventArgs e)
        {
            stopThread();
        }

        private void txtsleeptime_MouseHover(object sender, EventArgs e)
        {
            ToolTip tp = new ToolTip();
            tp.SetToolTip(txtsleeptime, "这里输入的数值为CNC机床采集的间隔时间。\n如果为空,默认3秒采集一次。");
        }

        private void Form1_MinimumSizeChanged(object sender, EventArgs e)
        {
        }
        private void button3_Click_3(object sender, EventArgs e)
        {
        }
    }
}


以上就是界面需要用的代码,注释都写明了函数方法使用的功能。
下面就上采集方法的代码。
方法只要用的是使用库函数连接机器,然后返回一个句柄号,然后就循环用句柄号去连接机器。不能使用IP一直连接机器的,因为有1024次的限制。

/**********************************
*               date:2018-11-30
*               By bevan 
*               sappmis@163.com
*               
*主要实现以下功能:将调用出传递过来的IP,机号,端口号等参数连接CNC,读取坐标,负载,运行状态信息,并写入数据库。
*
*/

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Threading;
namespace SmachCNC
{
    class LinkCnc
    {

        public ushort Handlew(string cncip)    //使用调用出传递多来的IP参数连接机器,返回一个句柄号给调用方法。
        {
            ushort fwlibHandle = 0;
            short ret = Focas1.cnc_allclibhndl3(cncip, 8193, 8, out fwlibHandle);
            return fwlibHandle;  //如果连接机器超时或者不成功都会返回一个数值。
        }

        /// <summary>
        /// 开启采集方法,将需要的数据写入数据库
        /// </summary>
        public void readCncToData(string ip, string cncno, int sleeptime)
        {
            string Ip = ip;
            string machineNo = cncno;
            ushort Handle = Handlew(Ip);  //调用方法传入IP,如果成功返回一个句柄号,不成功则返回其他代码。
            int sleepTime = sleeptime * 1000;   //线程采集时间间隔
            if (Handle==0)    //判断句柄状态。
            {
                string sqlen = "INSERT INTO [dbo].[MachState]([MachNo],[Times])values("+machineNo+",getdate())";
                int x = new DbHelp().OperSql(sqlen );
                Thread.Sleep(sleepTime);
                readCncToData(Ip, machineNo, sleeptime);  //如果连接机器不成功则继续调用自身去重新连接机器。因为程序是不间断工作的,如果没有这个方法这个机器将一直采集不到数据。需要将采集程序重新启动才可以。
                return;
            }
            while (true)  //死循环,用来采集数据。
            {
                Thread.Sleep(sleepTime); //采集数据的时间间隔
                List<Swap> swap = new List<Swap>(); //这个是一个泛型,用来保存数据集合
                swap.AddRange(get_Abs(Handle));
                swap.AddRange(get_MachCoX(Handle));
                swap.AddRange(get_Relatively(Handle));
                swap.AddRange(get_Status(Handle));
                swap.AddRange(get_Load(Handle));
                swap.AddRange(get_program(Handle));
                swap.AddRange(get_feed(Handle));
                swap.AddRange(get_spinfo(Handle));
                swap.AddRange(get_spact(Handle));
                double spact;
                string Mainpro;
                double absX;//绝对座标
                double absY;
                double absZ;
                double absA;
                double relativelyU; //相对座标
                double relativelyW;
                double relativelyV;
                double machCoX; //机械座标
                double machCoY;
                double machCoZ;
                double alarm;
                double aut;
                double dummy;
                double edit;
                double emerg;
                double motion;
                double mstb;
                double run;
                double tmmode;
                double sp1;
                double sp2;
                double sp3;
                double sv1;
                double sv2;
                double sv3;
                double feed;
                int mState;//状态
                int WorkModel;//工作模式1,2,3,4、自动、手动、调试、停机
                absX = Convert.ToDouble(swap[0].Value);
                absY = Convert.ToDouble(swap[1].Value);
                absZ = Convert.ToDouble(swap[2].Value);
                absA = Convert.ToDouble(swap[3].Value);
                machCoX = Convert.ToDouble(swap[4].Value);  //机械座标
                machCoY = Convert.ToDouble(swap[5].Value);
                machCoZ = Convert.ToDouble(swap[6].Value);
                relativelyU = Convert.ToDouble(swap[7].Value); //相对座标
                relativelyV = Convert.ToDouble(swap[8].Value);
                relativelyW = Convert.ToDouble(swap[9].Value);
                alarm = Convert.ToInt32(swap[10].Value);
                aut = Convert.ToInt32(swap[11].Value);
                dummy = Convert.ToInt32(swap[12].Value);
                edit = Convert.ToInt32(swap[13].Value);
                emerg = Convert.ToInt32(swap[14].Value);
                motion = Convert.ToInt32(swap[15].Value);
                mstb = Convert.ToInt32(swap[16].Value);
                run = Convert.ToInt32(swap[17].Value);
                tmmode = Convert.ToInt32(swap[18].Value);
                WorkModel = Convert.ToInt32(swap[19].Value);
                mState = Convert.ToInt32(swap[20].Value);
                sv1 = Convert.ToInt32(swap[21].Value);
                sv2 = Convert.ToInt32(swap[22].Value);
                sv3 = Convert.ToInt32(swap[23].Value);
                // sp1 = Convert.ToInt32(swap[24].Value);
                //sp2 = Convert.ToInt32(swap[25].Value);
                //sp3 = Convert.ToInt32(swap[26].Value);
                Mainpro = Convert.ToString(swap[27].Value);
                feed = Convert.ToDouble(swap[28].Value);
                sp1 = Convert.ToDouble(swap[29].Value);
                sp2 = Convert.ToDouble(swap[30].Value);
                sp3 = Convert.ToDouble(swap[31].Value);
                spact = Convert.ToInt32(swap[32].Value);
                if (aut == 0 && run == 0 && edit == 0 && mstb == 0 && alarm == 0)  //再次判断机器是否在线,如果这几个状态都为0的话,机器估计是不在线了,然后重新调用自身连接机器。
                {
                   
                    string sqlen1 = "INSERT INTO [dbo].[MachState]([MachNo],[times])values(" + machineNo + ",getdate())";
                    int x1 = new DbHelp().OperSql(sqlen1);
                    readCncToData(Ip, machineNo, sleeptime);
                    return;  //中断当前函数,返回函数入口。
                }
                string sql = "INSERT INTO [dbo].[MachState]([MachNo],[mState],[WorkModel],[absX],[absY],[absZ],[relativelyU],[relativelyW],[relativelyV],[MachCoX],[MachCoY],[MachCoZ],[Times],[aut],[run],[edit],[mstb],[alarm],[sp1],[sp2],[sp3],[sv3],[sv2],[sv1],[dummy],[emerg],[motion],[tmmode],[Feed],[mainpro],[AbsA],[spact])VALUES('" + machineNo + "','" + mState + "','" + WorkModel + "'," + absX + "," + absY + "," + absZ + "," + relativelyU + "," + relativelyW + "," + relativelyV + "," + machCoX + "," + machCoY + "," + machCoZ + ",getdate(),'" + aut + "','" + run + "','" + edit + "','" + mstb + "','" + alarm + "'," + sp1 + "," + sp2 + "," + sp3 + "," + sv3 + "," + sv2 + "," + sv1 + ",'" + dummy + "','" + emerg + "','" + motion + "','" + tmmode + "'," + feed + ",'" + Mainpro + "'," + absA + "," + spact + ")";
                int x = new DbHelp().OperSql(sql);
            }
        }




        /// <summary>
        /// 读取绝对
        /// </summary>
        /// <param name="mun"></param>
        /// <returns></returns>
        public List<Swap> get_Abs(ushort mun)//座标相关,绝对座标
        {
            List<Swap> swap = new List<Swap>();
            swap.Clear();
            Focas1.ODBST oDBST = new Focas1.ODBST();
            Focas1.ODBAXIS oDBAXI = new Focas1.ODBAXIS();
            for (int i = 0; i < 4; i++)
            {
                Focas1.cnc_absolute2(mun, (short)(i + 1), 8, oDBAXI);
                swap.Add(new Swap("abs" + i, (oDBAXI.data[0] / 1000).ToString()));
            }

            return swap;
        }

        /// <summary>
        /// 获取相对坐标
        /// </summary>
        /// <param name="mun"></param>
        /// <returns></returns>
        public List<Swap> get_Relatively(ushort mun)
        {
            List<Swap> swap = new List<Swap>();
            swap.Clear();
            Focas1.ODBST oDBST = new Focas1.ODBST();
            Focas1.ODBAXIS oDBAXI = new Focas1.ODBAXIS();

            double[] num = new double[100];
            for (int i = 0; i < 3; i++)
            {
                Focas1.cnc_relative2(mun, (short)(i + 1), 8, oDBAXI);
                double num1 = (double)oDBAXI.data[0] / 1000;
                swap.Add(new Swap("Relatively" + i, num1.ToString()));
            }
            return swap;
        }

        /// <summary>
        /// 读取机械坐标
        /// </summary>
        /// <param name="mun"></param>
        /// <returns></returns>
        public List<Swap> get_MachCoX(ushort mun)
        {
            List<Swap> swap = new List<Swap>();
            swap.Clear();
            Focas1.ODBST oDBST = new Focas1.ODBST();
            Focas1.ODBAXIS oDBAXI = new Focas1.ODBAXIS();
            for (short i = 0; i < 3; i = (short)(i + 1))
            {
                Focas1.cnc_machine(mun, (short)(i + 1), 8, oDBAXI);

                double num1 = (double)oDBAXI.data[0] / 10000;
                swap.Add(new Swap("MachCo" + i, num1.ToString()));
            }
            return swap;
        }



        /// <summary>
        /// 读取机器状态信息
        /// </summary>
        /// <param name="mun"></param>
        /// <returns></returns>
        public List<Swap> get_Status(ushort mun)
        {
            List<Swap> swap = new List<Swap>();
            swap.Clear();
            Focas1.ODBST statu = new Focas1.ODBST();
            Focas1.cnc_statinfo(mun, statu);

            int edit1 = Convert.ToInt32(statu.edit.ToString());
            int run1 = Convert.ToInt32(statu.run.ToString());
            int aut1 = Convert.ToInt32(statu.aut.ToString());
            int WorkModel;
            int mState;
            if (run1 == 0 && aut1 == 0)
            {
                WorkModel = 0; //关机
                mState = 0;

            }
            else if (run1 == 3 && aut1 == 1)
            {
                WorkModel = 1; //正常运行
                mState = 1;
            }

            else if (aut1 == 3 && run1 == 0)
            {
                WorkModel = 2; //调机
                mState = 1;
            }
            else if (aut1 == 4)
            {
                WorkModel = 3; //手轮
                mState = 1;
            }
            else
            {
                WorkModel = 4; //闲置
                mState = 1;
            }
            swap.Add(new Swap("alarm", statu.alarm.ToString()));
            swap.Add(new Swap("aut", statu.aut.ToString()));
            swap.Add(new Swap("dummy", statu.dummy.ToString()));
            swap.Add(new Swap("edit", statu.edit.ToString()));
            swap.Add(new Swap("emerg", statu.emergency.ToString()));
            swap.Add(new Swap("motion", statu.motion.ToString()));
            swap.Add(new Swap("mstb", statu.mstb.ToString()));
            swap.Add(new Swap("run", statu.run.ToString()));
            swap.Add(new Swap("tmmode", statu.tmmode.ToString()));
            swap.Add(new Swap("workmodel", WorkModel.ToString()));
            swap.Add(new Swap("state", mState.ToString()));
            return swap;
        }




        /// <summary>
        /// 读取机器主轴负载信息,这个信息我都不知道是不是准确的,我估计很大几率是不准确的
        /// </summary>
        /// <param name="mun"></param>
        /// <returns></returns>
        public List<Swap> get_Load(ushort mun)
        {
            Fanuc.ODBSVLOAD sv = new Focas1.ODBSVLOAD();
            Fanuc.ODBSPLOAD sp = new Focas1.ODBSPLOAD();
            List<Swap> swap = new List<Swap>();
            swap.Clear();
            short q1 = 6;
            Focas1.cnc_rdsvmeter(mun, ref q1, sv);
            short q2 = 0;
            Focas1.cnc_rdspmeter(mun, q2, ref q1, sp);
            swap.Add(new Swap("sv1", sv.svload1.data.ToString()));
            swap.Add(new Swap("sv2", sv.svload2.data.ToString()));
            swap.Add(new Swap("sv3", sv.svload3.data.ToString()));
            swap.Add(new Swap("sp1", sp.spload1.spload.data.ToString()));
            swap.Add(new Swap("sp2", sp.spload2.spload.data.ToString()));
            swap.Add(new Swap("sp3", sp.spload3.spload.data.ToString()));
            return swap;
        }

        /// <summary>
        /// 
        /// 读取机器进给量
        /// </summary>
        /// <param name="mun"></param>
        /// <returns></returns>
        public List<Swap> get_feed(ushort mun)
        {
            Fanuc.ODBSVLOAD sv = new Focas1.ODBSVLOAD();
            Focas1.IODBPMC0 pmc = new Focas1.IODBPMC0();
            List<Swap> swap = new List<Swap>();
            swap.Clear();
            Focas1.pmc_rdpmcrng(mun, 0, 0, 12, 13, 10, pmc);
            swap.Add(new Swap("feed", (this.Transform((int)pmc.cdata[0]).ToString())));
            swap.Add(new Swap("RemaFeed", (this.Transform((int)pmc.cdata[1]).ToString())));
            return swap;
        }

        /// <summary>
        /// 转换倍速
        /// </summary>
        /// <param name="s"></param>
        /// <returns></returns>
        public int Transform(int s)
        {
            if (s == 0)
            {
                return 0;
            }
            string str = "";
            int num = 0;
            while (s > 0)
            {
                str = string.Concat(str, s % 2);
                s /= 2;
                num++;
            }
            string str1 = "";
            for (int i = num - 1; i >= 0; i--)
            {
                char chr = str[i];
                str1 = string.Concat(str1, chr.ToString());
            }
            str1 = str1.Replace('1', '2');
            str1 = str1.Replace('0', '1');
            str1 = str1.Replace('2', '0');
            int num1 = 0;
            int num2 = int.Parse(str1);
            int num3 = 0;
            while (num2 != 0)
            {
                int num4 = num2 % 10;
                num2 /= 10;
                num1 = num1 + num4 * (int)Math.Pow(2, (double)num3);
                num3++;
            }
            return num1;
        }

        /// <summary>
        /// 获取主轴速度
        /// </summary>
        /// <param name="mun"></param>
        /// <returns></returns>
        public List<Swap> get_spinfo(ushort mun)
        {
            List<Swap> swap = new List<Swap>();
            swap.Clear();
            Focas1.ODBSPN odbspn = new Focas1.ODBSPN();
            for (int i = 0; i < 3; i++)
            {
                Focas1.cnc_rdspload(mun, -1, odbspn);
                swap.Add(new Swap("spq" + i, odbspn.data[i].ToString()));
            }
            return swap;
        }

        /// <summary>
        /// 获取实际主轴速度
        /// </summary>
        /// <param name="mun"></param>
        /// <returns></returns>
        public List<Swap> get_spact(ushort mun)
        {
            List<Swap> swap = new List<Swap>();
            swap.Clear();
            Focas1.ODBACT2 act2 = new Focas1.ODBACT2();
            Focas1.cnc_acts2(mun, -1, act2);
            swap.Add(new Swap("spact", act2.data[0].ToString()));
            return swap;
        }


        /// <summary>
        /// 读取刀具信息
        /// </summary>
        /// <param name="mun"></param>
        /// <returns></returns>
        public List<Swap> get_toolInfo(ushort mun)
        {
            List<Swap> swap = new List<Swap>();
            swap.Clear();
            Focas1.IODBTD iodb = new Focas1.IODBTD();
            for (int i = 0; i < 2; i++)
            {

                Focas1.cnc_rd1tlifedata(mun, 0, 0, iodb);
                swap.Add(new Swap("tool_grno" + i, iodb.datano.ToString()));//组编号
                swap.Add(new Swap("tool_no" + i, iodb.tool_num.ToString()));//刀具编号
                swap.Add(new Swap("tool_inf" + i, iodb.tool_inf.ToString()));//xinxi 
                swap.Add(new Swap("tool_H" + i, iodb.h_code.ToString()));//长度补偿
                swap.Add(new Swap("tool_D" + i, iodb.d_code.ToString()));//半径补偿

            }
            return swap;
        }

        /// <summary>
        /// 当前主程序号
        /// </summary>
        /// <param name="mun"></param>
        /// <returns></returns>
        public List<Swap> get_program(ushort mun)
        {
            List<Swap> swap = new List<Swap>();
            Focas1.ODBEXEPRG EXEPRG = new Focas1.ODBEXEPRG();
            Focas1.PRGDIR3 pRGDIR3 = new Focas1.PRGDIR3();
            Focas1.cnc_exeprgname(mun, EXEPRG);
            short num = 2;
            int oNum = EXEPRG.o_num;
            short num1 = 1;
            Focas1.cnc_rdprogdir3(mun, num, ref oNum, ref num1, pRGDIR3);
            swap.Add(new Swap("workpart", pRGDIR3.dir1.comment.ToString()));
            return swap;
        }
    }
}

另一个更新数据的方法我就不贴了,跟这个大同小异,只是将insert 改成update方法而已。
总的说来这些代码看着不多,但是坑超多,反正用遍地是坑来形容都不过分。
还有西门子机器的采集,等过段时间再贴了。最近项目很赶。。。也是超多坑。。。

Logo

助力广东及东莞地区开发者,代码托管、在线学习与竞赛、技术交流与分享、资源共享、职业发展,成为松山湖开发者首选的工作与学习平台

更多推荐