安装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; } }