• 三菱PLC上位机通信组件MX Component的使用


    安装MX Component Version 4后,安装目录下 “ActSamples” 有官方示范代码。

    然而自己折腾了两天才发现,内置方法只能对单字进行操作。

    自己封装了int32双字的操作,以及Ascii字符串转ushort数组的方法。

    建议配合MX工具集里面的“PLC Monitor Utility” 查看读写操作是否正确。

    using ActUtlTypeLib;
    using System;
    using System.Globalization;
    using System.Windows.Forms;
    
    public class MX32 {
        private static ActUtlTypeClass act;
        public static int PlcStatus = -1;
        public static int MXRet = -99; //只有单步的返回值是准确的
    
        public static int[] ReadRandom(string[] dName) {
            string name2 = "";
            for (int i = 0; i < dName.Length; i++) {
                if (short.TryParse(dName[i].Substring(1, dName[i].Length - 1), out short sn) && sn % 2 == 0) {
                    name2 += dName[i] + "
    " + dName[i].Substring(0, 1) + (sn + 1).ToString() + "
    ";
                } else {
                    //MessageBox.Show("元件名错误,或元件位号错吴!", "", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    return new int[] { };
                }
            }
            int[] tmp = new int[dName.Length * 2];
            MXRet = act.ReadDeviceRandom(name2.Trim(), dName.Length * 2, out tmp[0]);
            if (MXRet == 0) return int16To32(tmp);
            else return new int[] { };
        }
    
        public static int ReadRandom(string dName) {
            string name2 = "";
            if (short.TryParse(dName.Substring(1, dName.Length - 1), out short sn) && sn % 2 == 0) {
                name2 += dName + "
    " + dName.Substring(0, 1) + (sn + 1).ToString();
            } else {
                //MessageBox.Show("元件名错误,或元件位号错吴!", "", MessageBoxButtons.OK, MessageBoxIcon.Error);
                return -99;
            }
            int[] tmp = new int[2];
            MXRet = act.ReadDeviceRandom(name2, 2, out tmp[0]);
            if (MXRet == 0) return int16To32(tmp)[0];
            else return -99;
        }
    
        public static bool WriteRandom(string dName, int dValue) {
            string name2 = "";
            if (short.TryParse(dName.Substring(1, dName.Length - 1), out short sn) && sn % 2 == 0) {
                name2 += dName + "
    " + dName.Substring(0, 1) + (sn + 1).ToString();
            } else {
                //MessageBox.Show("元件名错误,或元件位号错吴!", "", MessageBoxButtons.OK, MessageBoxIcon.Error);
                return false;
            }
            int[] tmp = int32To16(new int[] { dValue });
            MXRet = act.WriteDeviceRandom(name2.Trim(), 2, ref tmp[0]);
            return MXRet == 0;
        }
    
        public static bool WriteRandom(string[] dName, int[] dValue) {
            string name2 = "";
            for (int i = 0; i < dName.Length; i++) {
                if (short.TryParse(dName[i].Substring(1, dName[i].Length - 1), out short sn) && sn % 2 == 0) {
                    name2 += dName[i] + "
    " + dName[i].Substring(0, 1) + (sn + 1).ToString() + "
    ";
                } else {
                    //MessageBox.Show("元件名错误,或元件位号错吴!", "", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    return false;
                }
            }
            int[] tmp = int32To16(dValue);
            MXRet = act.WriteDeviceRandom(name2.Trim(), dValue.Length * 2, ref tmp[0]);
            return MXRet == 0;
        }
    
        public static int[] ReadBlock(string dName, int dataLen) {
            int[] tmp = new int[dataLen * 2];
            MXRet = act.ReadDeviceBlock(dName, dataLen * 2, out tmp[0]);
            if (MXRet == 0) return int16To32(tmp);
            else return new int[] { };
        }
    
    
        public static bool WriteBlock(string dName, int[] dValue) {
            int[] tmp = int32To16(dValue);
            MXRet = act.WriteDeviceBlock(dName, tmp.Length, ref tmp[0]);
            return MXRet == 0;
        }
    
        public static bool WriteBlockUShort(string dName, int[] sValue) {
            MXRet = act.WriteDeviceBlock(dName, sValue.Length, ref sValue[0]);
            return MXRet == 0;
        }
    
    
        public static void Open() {
            if (PlcStatus != 1) {
                act = new ActUtlTypeClass();
                act.ActLogicalStationNumber = DAL.PLCSN;
                act.ActPassword = DAL.PLCPSWD;
                int iret = -10;
                try {
                    iret = act.Open();
                } catch {
                    try {
                        act.Close();
                        iret = act.Open();
                    } catch {
                        iret = -10;
                    }
                }
                if (iret == 0) PlcStatus = 1; else PlcStatus = iret;
            }
        }
    
        public static void Exit() {
            if (PlcStatus == 1) {
                try {
                    act.Close();
                    act = null;
                } catch {
                }
            }
        }
    
        /// <summary>
        /// 将读取到的int16数组,每2个int16组合转换高低字节后,生成1个int32,写入数组
        /// </summary>
        /// <param name="in16"></param>
        /// <returns></returns>
        private static int[] int16To32(int[] in16) {
            int[] ret = new int[in16.Length / 2];
            for (int i = 0; i < in16.Length; i = i + 2)
                ret[i / 2] = int.Parse(string.Format("{0:X2}", in16[i + 1])
                    + string.Format("{0:X2}", in16[i]), NumberStyles.HexNumber);
            return ret;
        }
    
        /// <summary>
        /// 将int32数组,每1个int32拆分成2个uint16
        /// </summary>
        /// <param name="in32"></param>
        /// <returns></returns>
        private static int[] int32To16(int[] in32) {
            int[] ret = new int[in32.Length * 2];
            for (int i = 0; i < in32.Length; i++) {
                string ins = string.Format("{0:X2}", in32[i]);
                if (in32[i] <= ushort.MaxValue) {
                    ret[i * 2] = in32[i];
                    ret[i * 2 + 1] = 0;
                } else {
                    ret[i * 2] = int.Parse(ins.Substring(ins.Length - 4, 4), NumberStyles.HexNumber);
                    ret[i * 2 + 1] = int.Parse(ins.Substring(0, ins.Length - 4), NumberStyles.HexNumber);
                }
            }
            return ret;
        }
    
        /// <summary>
        /// 将ASCII字符串转换成UShort数组(MX Component中,无ushort,代用int类型)
        /// </summary>
        /// <param name="str"></param>
        /// <returns></returns>
        public static int[] stringToInt(string str) {
            int k = str.Length / 2;
            int[] ret = new int[k + str.Length % 2];
            char[] cr = str.Trim().ToCharArray();
            for (int i = 0; i < k * 2; i = i + 2)
                ret[i / 2] =
                    ushort.Parse(string.Format("{0:X2}", (int)cr[i + 1]) + string.Format("{0:X2}", (int)cr[i]), NumberStyles.HexNumber);
            if (str.Length % 2 > 0)
                ret[k + str.Length % 2 - 1] =
                    ushort.Parse(string.Format("{0:X2}", (int)cr[str.Length - 1]), NumberStyles.HexNumber);
            return ret;
        }
    }
  • 相关阅读:
    mysql 权限问题
    触发器作用
    带有循环功能的存储过程
    带有条件判断的存储过程
    数据存储 三大范式-----------待续
    存储过程自 带条件判断的存储过程
    线程异步更新UI
    TextBox只能输入数字
    C#中无边框窗体移动或拖控件移动窗体
    classloader原理
  • 原文地址:https://www.cnblogs.com/leavind/p/14519002.html
Copyright © 2020-2023  润新知