C#编程实现威纶通MT8102IE的屏幕校正后恢复出厂设置的选项

复制粘贴代码到VSCode 或LinqPad 中,执行即可,需要.net8。在我的电脑上实验成功,欢迎反馈不同型号的结果。触摸屏重启后手动进入触摸屏校准,执行完成校准后会询问是否恢复下载密码,输入yes之后,会清空内部的项目。
Visual Studio 源码文件和编译成可执行exe文件WeintekTest.rar
WeintekRestTest

using System.Net.Sockets;
using System.Runtime.CompilerServices;
using System.Security.Cryptography.X509Certificates;

namespace WeintekTest;

class Program
{

    static string uploadTelegram = "50010000001a67657466696c65202f6d74383030302f3030312f6d7438303030";//上传数据报文
    static Weintek weintek = new Weintek("192.168.20.51");
    static Weintek weintek2 = new Weintek("192.168.20.51", 20248);

    static void Main(string[] args)
    {
        //Fun1();     
        //Console.Read();
        ClearTool();
    }

    static void DoWork1(string str)
    {
        var rec = weintek.Send(str);
        if (rec == null)
        {
            Console.WriteLine("无返回内容!");
            return;
        }
        Console.WriteLine(BitConverter.ToString(rec).Replace("-", " "));
    }

    static void DoWork2(string str)
    {
        var rec = weintek2.Send(str);
        if (rec == null)
        {
            Console.WriteLine("无返回内容!");
            return;
        }
        Console.WriteLine(BitConverter.ToString(rec).Replace("-", " "));
    }

    static void Fun0()
    {
        var dat = weintek2.Send("400100000000");
        DoWork2(BitConverter.ToString(dat).Replace("-", ""));

        List<string> strs = new List<string>()
        {
            //"400100000000",
            //"40010002004042433534454330444644434235323141414644393642344136334141314442423946413242373542433932394543393446334530363133433637424241463534",
            "4001000400320001384442464236374242424445373841443334333133334442364643353239303941324244393244464433383143393035",
            //"4001000400320001373138464136323446384132423737433941304436384632394530383339303346304243363638323045313344354538",
            "50010000001a67657466696c65202f6d74383030302f3030312f6d7438303030"
            //"5001000000114f535f76657273696f6e20303431303032",
            //"50010000000473746f70"
        };
        foreach (var str in strs)
        {
            DoWork2(str);
        };
    }

    static void Fun1()
    {
        File.WriteAllText("res.txt", "");

        for (int i = 9000; i < 12900; i++)
        {
            string str = $"{DateTime.Now}:LW{i}:\t" + weintek.GetLW(i) + Environment.NewLine;
            //File.AppendAllText("res.txt",str); 
            //Thread.Sleep(10);
        }

        Console.WriteLine("Done!");
        Console.Read();
    }

    static void ClearTool()
    {
        //Console.WriteLine("如要确认执行请按'Y'键:");
        //var key=Console.ReadKey();
        //Console.WriteLine();
        //if(key.Key != ConsoleKey.Y) 
        {
            //Console.WriteLine("已取消执行!");
            //Console.Read();            
            //return;
        }

        Console.WriteLine("请谨慎操作!");
        Console.WriteLine("触摸屏将在稍后重启,请在触摸屏重启后手动进入并执行触摸屏校准!");
        Console.WriteLine("校准完成后,会弹出对话框询问是否重置密码,输入'yes'即可清空内部项目并重置下载密码!");

        for (int i = 10; i > 0; i--)
        {
            //倒计时执行
            Console.WriteLine($"倒计时:{i}秒.");
            Thread.Sleep(1000);
        }

        Console.WriteLine("正在更新日期时间...");
        //更新日期时间
        weintek.SetLW(9022, (short)DateTime.Now.Year);//更新年
        weintek.SetLW(9021, (short)DateTime.Now.Month);//更新月
        weintek.SetLW(9020, (short)DateTime.Now.Day);//更新日
        weintek.SetLW(9019, (short)DateTime.Now.Hour);//更新时
        weintek.SetLW(9018, (short)DateTime.Now.Minute);//更新分
        weintek.SetLW(9017, (short)DateTime.Now.Second);//更新秒

        Console.WriteLine("正在更改系统设置...");
        weintek.SetLB(9020, true);//显示系统控制按钮
        weintek.SetLB(9033, true);//允许上传
        weintek.SetLB(12364, true);//开启屏幕校正后恢复出厂设置的选项
        weintek.SetLB(9048, true);//开启重启保护
        weintek.SetLB(9047, true);//重启触摸屏
        //设定LB寄存器时返回报文实例
        //2024/4/13 10:36:54+_接收内容33:	01-60-00-00-FF-00-00-00-00-00-08-00-01-00-01-00-00-00-01-00-00-00-00-00-00-00-00-00-00-00-00-00-02
        //2024/4/13 10:36:54+_接收内容33:	01-60-00-00-FF-00-00-00-00-00-08-00-01-00-02-00-00-00-01-00-00-00-00-00-00-00-00-00-00-00-00-00-02
        //2024/4/13 10:36:54+_接收内容33:	01-60-00-00-FF-00-00-00-00-00-08-00-01-00-03-00-00-00-01-00-00-00-00-00-00-00-00-00-00-00-00-00-02
        //2024/4/13 10:36:54+_接收内容33:	01-60-00-00-FF-00-00-00-00-00-08-00-01-00-04-00-00-00-01-00-00-00-00-00-00-00-00-00-00-00-00-00-02
        //2024/4/13 10:36:54+_接收内容33:	01-60-00-00-FF-00-00-00-00-00-08-00-01-00-05-00-00-00-01-00-00-00-00-00-00-00-00-00-00-00-00-00-02

        Console.WriteLine("Done!");
        Console.Read();
    }



    public class Weintek
    {
        string _ip;
        int _port = 8000;

        byte _index = 0;
        readonly object lckObj = new object();

        public Weintek(string ip)
        {
            _ip = ip;
            _port = 8000;

        }

        public Weintek(string ip, int port)
        {
            _ip = ip;
            _port = port;

        }

        byte GetIndex()
        {
            lock (lckObj)
            {
                return ++_index;
            }
        }

        int GetEasyWatchIndex()
        {
            return 1;
        }

        public bool GetLB(int regAddress)
        {
            return GetLB(regAddress,1);
        }

        public bool GetLB(int regAddress,int count)
        {
            //读LB12364
            //PC发:	    01600000ff000000000008000c 00e5 0300000100000000000000000000ff 0403 000001000000
            //HMI回true:	01600000ff0000000000080005 00e5 030000010000000000000000000000000000 0010 0000  //大端
            //HMI回false:   01600000ff0000000000080005 00e5 030000010000000000000000000000000000 0000 0000 //大端

            //读LB9047
            //PC发:        01600000ff000000000008000c 00fb 0300000200000000000000000000ff 3502 000001000000

            //读LB9048
            //PC发:        01600000ff000000000008000c 00fe 0300000300000000000000000000ff 3502 000001000000

            try
            {
                bool ret = false;
                string sendHeader = "01600000ff000000000008000c00";
                string sendConstStr1 = "0300000100000000000000000000ff";

                string receiveHeader = "01600000ff000000000008000500";

                var sendStr = sendHeader;
                sendStr += GetIndex().ToString("x2");
                sendStr += sendConstStr1;
                sendStr += GetLBAddress(regAddress).Substring(0, 8);
                sendStr += ToLittleEndian((UInt32)count).ToString("x8");

                var receiveData = Send(sendStr);
                var receiveStr = BitConverter.ToString(receiveData).Replace("-", "").ToLower();
                if (receiveStr.Length > receiveHeader.Length &&
                    receiveStr.StartsWith(receiveHeader) &&
                    string.Compare(sendStr.Substring(sendHeader.Length, 2), receiveStr.Substring(receiveHeader.Length, 2)) == 0)
                {
                    var dat = ToLittleEndian(Convert.ToUInt16(receiveStr.Substring(66, 4), 16));
                    var temp = Convert.ToUInt16(Math.Pow(2, regAddress % 0x10));
                    ret = (dat & temp) > 0;
                    return ret;
                }

                return ret;
            }
            catch (Exception ex)
            {
                Console.WriteLine($"GetLb_{DateTime.Now}:\t" + ex.Message);
                return false;
            }
        }


        /// <summary>
        /// 设置触摸屏的LB寄存器(系统寄存器的值)
        /// </summary>
        /// <param name="ip">触摸屏的地址</param>
        /// <param name="port">链接端口号,默认值为8000</param>
        /// <param name="index">报文序号,返回报文的序号和发送报文序号相同</param>
        /// <param name="regAddress">LB寄存器地址</param>
        /// <param name="Value">设定值</param>
        public bool SetLB(int regAddress, bool Value)
        {
            //设定LB寄存器时返回报文实例
            //2024/4/13 10:36:54+_接收内容33:	01-60-00-00-FF-00-00-00-00-00-08-00-01-00-01-00-00-00-01-00-00-00-00-00-00-00-00-00-00-00-00-00-02
            //2024/4/13 10:36:54+_接收内容33:	01-60-00-00-FF-00-00-00-00-00-08-00-01-00-02-00-00-00-01-00-00-00-00-00-00-00-00-00-00-00-00-00-02
            //2024/4/13 10:36:54+_接收内容33:	01-60-00-00-FF-00-00-00-00-00-08-00-01-00-03-00-00-00-01-00-00-00-00-00-00-00-00-00-00-00-00-00-02
            //2024/4/13 10:36:54+_接收内容33:	01-60-00-00-FF-00-00-00-00-00-08-00-01-00-04-00-00-00-01-00-00-00-00-00-00-00-00-00-00-00-00-00-02
            //2024/4/13 10:36:54+_接收内容33:	01-60-00-00-FF-00-00-00-00-00-08-00-01-00-05-00-00-00-01-00-00-00-00-00-00-00-00-00-00-00-00-00-02
            try
            {
                string sendHeader = "01600000ff000000000008000c00";
                string sendConstStr = "0000000100000000000000020000ff";//前面的01是EasyWatch序号,排第一个的为01,第二个的为02,在此处无关紧要

                string receiveHeader = "01600000FF000000000008000100";

                var sendStr = sendHeader;
                sendStr += GetIndex().ToString("x2");
                sendStr += sendConstStr;
                sendStr += GetLBAddress(regAddress);
                sendStr += Value ? "ff" : "00";
                sendStr += "0000";

                var receiveData = Send(sendStr);
                var receiveStr = BitConverter.ToString(receiveData).Replace("-", "").ToLower();
                if (receiveStr.Length > receiveHeader.Length
                && receiveStr.StartsWith(receiveHeader)
                && string.Compare(sendStr.Substring(sendHeader.Length, 2), receiveStr.Substring(receiveHeader.Length, 2)) == 0
                )
                {
                    return true;
                }

                return false;
            }
            catch (Exception ex)
            {
                Console.WriteLine($"SetLb_{DateTime.Now}:\t" + ex.Message);
                return false;
            }
        }

        static string GetLBAddress(int addr)
        {
            string ret = "";
            string str = addr.ToString("X5");
            ret += str.Substring(2, 2);
            ret += str.Substring(0, 2);
            ret += "00000";
            ret += str.Substring(4, 1);
            return ret;
        }

        public Int16 GetLW(int regAddress)
        {
            return GetLW(regAddress, 1);
        }

        /// <summary>
        /// 读取LW寄存器的值
        /// </summary>
        /// <param name="ip">触摸屏IP地址</param>
        /// <param name="port">端口</param>
        /// <param name="index">包序号</param>
        /// <param name="regAddress">LW寄存器地址</param>
        /// <param name="count">寄存器个数,当前只支持1个寄存器</param>
        /// <returns>返回值</returns>
        public Int16 GetLW(int regAddress, int count)
        {
            //读LW9009
            //PC发:	01600000ff000000000008000c00 be 0300003600000000000000000008ff 3123 0000 0100 0000
            //HMI回:   01600000ff000000000008000500 be 030000360000000000000000000000000000 4040 0000

            //PC发:	01600000ff000000000008000c00 bc 0300003600000000000000000008ff 3123 0000 0100 0000
            //HMI回:	01600000ff000000000008000500 bc 030000360000000000000000000000000000 4040 0000
            try
            {
                UInt16 ret = 0;
                string sendHeader = "01600000ff000000000008000c00";
                string sendRegConstStr = "0300003600000000000000000008ff";

                string receiveHeader = "01600000ff000000000008000500";

                string sendStr = sendHeader;
                sendStr += GetIndex().ToString("x2");
                sendStr += sendRegConstStr;
                sendStr += ToLittleEndian((UInt16)regAddress).ToString("x4");
                sendStr += "0000";
                sendStr += ToLittleEndian((UInt16)count).ToString("x4");
                sendStr += "0000";

                var receiveData = Send(sendStr);
                var receiveStr = BitConverter.ToString(receiveData).Replace("-", "").ToLower();

                if (receiveStr.Length > receiveHeader.Length && //长度无无异常
                    receiveStr.StartsWith(receiveHeader) && //接收头校验成功
                    string.Compare(sendStr.Substring(sendHeader.Length, 2), receiveStr.Substring(receiveHeader.Length, 2)) == 0 //包序号校验成功
                )
                {
                    var s1 = receiveStr.Substring(66, 4);
                    ret = Convert.ToUInt16(s1, 16);
                    return (Int16)ToLittleEndian(ret);
                }
                return -1;

            }
            catch (Exception ex)
            {
                Console.WriteLine($"GetLw_{DateTime.Now}:\t" + ex.Message);
                return -1;
            }
        }

        public bool SetLW(int regAddress, Int16 value)
        {
            //写LW9022=2024	(0xE807)|9022=0x3e23
            //PC发:	01600000ff000000000008000e 00d9 0300005100000000000000010008ff 3e23 0000 0100 e807 0000
            //HMI回:	     01600000ff0000000000080001 00d9 030000510000000000000000000000000001
            //              01600000ff0000000000080001 0001 030000510000000000000000000000000001
            try
            {
                string sendHeader = "01600000ff000000000008000e00";
                string sendRegConstStr = "0300005100000000000000010008ff";

                string receiveHeader = "01600000ff000000000008000100";

                string sendStr = sendHeader;
                sendStr += GetIndex().ToString("x2");
                sendStr += sendRegConstStr;
                sendStr += ToLittleEndian((UInt16)regAddress).ToString("x4");
                sendStr += "0000";
                sendStr += ToLittleEndian(1).ToString("x4");//数量
                sendStr += ToLittleEndian((UInt16)value).ToString("x4");
                sendStr += "0000";

                var receiveData = Send(sendStr);
                var receiveStr = BitConverter.ToString(receiveData).Replace("-", "").ToLower();

                if (receiveStr.Length > receiveHeader.Length && //长度无无异常
                    receiveStr.StartsWith(receiveHeader) && //接收头校验成功
                    string.Compare(sendStr.Substring(sendHeader.Length, 2), receiveStr.Substring(receiveHeader.Length, 2)) == 0 //包序号校验成功
                )
                {
                    return true;
                }
                return false;

            }
            catch (Exception ex)
            {
                Console.WriteLine($"SetLw_{DateTime.Now}:\t" + ex.Message);
                return false;
            }
        }


        //1234=0x04D2(LE)/0xD204(BE)
        //16bit读写
        //RW1234
        //读值
        //值为0
        //PC发:	01600000ff000000000008000c00 01 000000030000000000000000008dff d204 0000 0100 0000
        //HMI回:	01600000ff000000000008000500 01 000000030000000000000000000000000000 0000 0000

        //值为1234
        //PC发:	01600000ff000000000008000c00 21 000000030000000000000000008dff d204 0000 0100 0000
        //HMI回:	01600000ff000000000008000500 21 000000030000000000000000000000000000 d204 0000

        //写值1234
        //PC发:	01600000ff000000000008000e00 20 000000030000000000000001008dff d204 0000 0100 d204 0000
        //HMI回:	01600000ff000000000008000100 20 000000030000000000000000000000000001


        //32bit写
        //RW1234=4567	4567=0x11D7(LE)/D711(BE)
        //PC发:	01600000ff000000000008001000 43 000000030000000000000001008dff d204 0000 0200 d7110000 0000
        //HMI回:	01600000ff000000000008000100 43 000000030000000000000000000000000001

        //32bit读
        //PC发:	01600000ff000000000008000c00 44 000000030000000000000000008dff d204 0000 0200 0000
        //HMI回:	01600000ff000000000008000700 44 000000030000000000000000000000000000 d7110000 0000

        public Int16 GetRW(int regAddress)
        {
            return GetRW(regAddress, 1);
        }

        public Int16 GetRW(int regAddress, int count)
        {

            try
            {
                UInt16 ret = 0;
                string sendHeader = "01600000ff000000000008000c00";
                string sendRegConstStr = "000000030000000000000000008dff";

                string receiveHeader = "01600000ff000000000008000500";

                string sendStr = sendHeader;
                sendStr += GetIndex().ToString("x2");
                sendStr += sendRegConstStr;
                sendStr += ToLittleEndian((UInt16)regAddress).ToString("x4");
                sendStr += "0000";
                sendStr += ToLittleEndian((UInt16)count).ToString("x4");
                sendStr += "0000";

                var receiveData = Send(sendStr);
                var receiveStr = BitConverter.ToString(receiveData).Replace("-", "").ToLower();

                if (receiveStr.Length > receiveHeader.Length && //长度无无异常
                    receiveStr.StartsWith(receiveHeader) && //接收头校验成功
                    string.Compare(sendStr.Substring(sendHeader.Length, 2), receiveStr.Substring(receiveHeader.Length, 2)) == 0 //包序号校验成功
                )
                {
                    var s1 = receiveStr.Substring(66, 4);
                    ret = Convert.ToUInt16(s1, 16);
                    return (Int16)ToLittleEndian(ret);
                }
                return -1;

            }
            catch (Exception ex)
            {
                Console.WriteLine($"GetLw_{DateTime.Now}:\t" + ex.Message);
                return -1;
            }
        }


        public bool SetRW(int regAddress, Int16 value)
        {
            try
            {
                string sendHeader = "01600000ff000000000008000e00";
                string sendRegConstStr = "000000030000000000000001008dff";

                string receiveHeader = "01600000ff000000000008000100";

                string sendStr = sendHeader;
                sendStr += GetIndex().ToString("x2");
                sendStr += sendRegConstStr;
                sendStr += ToLittleEndian((UInt16)regAddress).ToString("x4");
                sendStr += "0000";
                sendStr += ToLittleEndian(1).ToString("x4");
                sendStr += ToLittleEndian((UInt16)value).ToString("x4");
                sendStr += "0000";

                var receiveData = Send(sendStr);
                var receiveStr = BitConverter.ToString(receiveData).Replace("-", "").ToLower();

                if (receiveStr.Length > receiveHeader.Length && //长度无无异常
                    receiveStr.StartsWith(receiveHeader) && //接收头校验成功
                    string.Compare(sendStr.Substring(sendHeader.Length, 2), receiveStr.Substring(receiveHeader.Length, 2)) == 0 //包序号校验成功
                )
                {
                    return true;
                }
                return false;

            }
            catch (Exception ex)
            {
                Console.WriteLine($"SetLw_{DateTime.Now}:\t" + ex.Message);
                return false;
            }
        }




        readonly object lckSend = new object();

        public byte[] Send(string str)
        {
            //lock(lckSend)
            {
                try
                {
                    using (TcpClient client = new TcpClient())
                    {
                        client.ReceiveTimeout = 500;
                        client.Connect(_ip, _port);
                        var s = client.GetStream();
                        var sendData = HexStringToByteArray(str);
                        s.Write(sendData);

                        byte[] buffer = new byte[1024];
                        int n = s.Read(buffer);
                        byte[] receiveData = new byte[n];
                        Array.Copy(buffer, receiveData, n);
                        //Console.WriteLine($"{DateTime.Now.ToString()}+_接收内容{receiveData.Length}:\t" + BitConverter.ToString(receiveData));
                        return receiveData;
                    }
                }
                catch (Exception ex)
                {
                    Console.WriteLine($"Send_{DateTime.Now}:\t" + ex.Message);
                    return null;
                }
            }
        }

        /// <summary>
        /// 十六进制字符串转字节数组,.Net7以后Convert带有ToHexString()和FromHexString()方法,此处保留
        /// </summary>
        /// <param name="str">要转换的字符串</param>
        /// <returns></returns>
        static byte[] HexStringToByteArray(string str)
        {
            return Enumerable.Range(0, str.Length).Where(x => (x % 2) == 0).Select(y => (byte)Convert.ToByte(str.Substring(y, 2), 16)).ToArray();
        }

        /// <summary>
        /// 大端转小端和小端转大端的操作是相同的,共用同一个即可
        /// </summary>
        /// <param name="dat">要转换的内容</param>
        /// <returns></returns>
        static UInt16 ToLittleEndian(UInt16 dat)
        {
            return BitConverter.ToUInt16(BitConverter.GetBytes(dat).Reverse().ToArray());
        }

        /// <summary>
        /// 大端转小端和小端转大端的操作是相同的,共用同一个即可
        /// </summary>
        /// <param name="dat">要转换的内容</param>
        /// <returns></returns>
        static UInt32 ToLittleEndian(UInt32 dat)
        {
            return BitConverter.ToUInt32(BitConverter.GetBytes(dat).Reverse().ToArray());
        }
    }


}

 

版权声明:本文内容来源于网络搜集无法获知原创作者,仅供个人学习用途,若侵犯到您的权益请联系我们及时删除。邮箱:1370723259@qq.com

发表评论