復(fù)制粘貼代碼到VsCode 或LinqPad 中,執(zhí)行即可,需要.net8。在我的電腦上實驗成功,歡迎反饋不同型號的結(jié)果。
using System.Net.Sockets;
using System.Runtime.CompilerServices;
using System.Security.Cryptography.X509Certificates;
namespace WeintekTest;
class Program
{
static Weintek weintek=new Weintek("192.168.20.51");
static void Main(string[] args)
{
ClearTool();
}
static void Fun0()
{
Console.WriteLine(weintek.GetLB(9047));
Console.WriteLine(weintek.GetLB(9048));
}
static void Fun1()
{
Console.WriteLine("Done!");
Console.Read();
File.WriteAllText("res.txt","");
for(int i=9000;i<12900;i++)
{
string str=$"{DateTime.Now}:LW{i}:\t"+weintek.GetLW(1, i) + Environment.NewLine;
File.AppendAllText("res.txt",str);
}
Console.WriteLine("Done!");
Console.Read();
}
static void ClearTool()
{
//Console.WriteLine("如要確認(rèn)執(zhí)行請按\"Y\"鍵:");
//var key=Console.ReadKey();
//Console.WriteLine();
//if(key.Key != ConsoleKey.Y)
{
//Console.WriteLine("已取消執(zhí)行!");
//Console.Read();
//return;
}
Console.WriteLine("請謹(jǐn)慎操作!");
Console.WriteLine("觸摸屏將在稍后重啟,請在觸摸屏重啟后手動進(jìn)入并執(zhí)行觸摸屏校準(zhǔn)!");
Console.WriteLine("校準(zhǔn)完成后,會彈出對話框詢問是否重置密碼,輸入'yes'即可清空內(nèi)部項目并重置下載密碼!");
for(int i=10;i>0;i--)
{
//倒計時執(zhí)行
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("正在更改系統(tǒng)設(shè)置...");
weintek.SetLB(9020, true);//顯示系統(tǒng)控制按鈕
weintek.SetLB(9033, true);//允許上傳
weintek.SetLB(12364, true);//開啟屏幕校正后恢復(fù)出廠設(shè)置的選項
weintek.SetLB(9048, true);//開啟重啟保護(hù)
weintek.SetLB(9047, true);//重啟觸摸屏
//設(shè)定LB寄存器時返回報文實例
//2024/4/13 10:36:54+_接收內(nèi)容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+_接收內(nèi)容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+_接收內(nèi)容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+_接收內(nèi)容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+_接收內(nèi)容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;
int _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;
}
int GetIndex()
{
lock(lckObj)
{
return ++_index;
}
}
int GetEasyWatchIndex()
{
return 1;
}
public bool GetLB(int regAddress)
{
//讀LB12364
//PC發(fā): 01600000ff000000000008000c 00e5 0300000100000000000000000000ff 0403 000001000000
//HMI回true: 01600000ff0000000000080005 00e5 030000010000000000000000000000000000 0010 0000 //大端
//HMI回false: 01600000ff0000000000080005 00e5 030000010000000000000000000000000000 0000 0000 //大端
//讀LB9047
//PC發(fā): 01600000ff000000000008000c 00fb 0300000200000000000000000000ff 3502 000001000000
//讀LB9048
//PC發(fā): 01600000ff000000000008000c 00fe 0300000300000000000000000000ff 3502 000001000000
try
{
bool ret=false;
string sendHeader="01600000ff000000000008000c";
string sendConstStr1 = "0300000100000000000000000000ff";
string sendConstStr2 = "000001000000";
string receiveHeader="01600000ff0000000000080005";
var sendStr = sendHeader;
sendStr += GetIndex().ToString("x4");
sendStr += sendConstStr1;
sendStr += GetLBAddress(regAddress).Substring(0,4);
sendStr += sendConstStr2;
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,4),receiveStr.Substring(receiveHeader.Length,4))==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(ex.Message);
return false;
}
}
/// <summary>
/// 設(shè)置觸摸屏的LB寄存器(系統(tǒng)寄存器的值)
/// </summary>
/// <param name="ip">觸摸屏的地址</param>
/// <param name="port">鏈接端口號,默認(rèn)值為8000</param>
/// <param name="index">報文序號,返回報文的序號和發(fā)送報文序號相同</param>
/// <param name="regAddress">LB寄存器地址</param>
/// <param name="Value">設(shè)定值</param>
public bool SetLB(int regAddress, bool Value)
{
//設(shè)定LB寄存器時返回報文實例
//2024/4/13 10:36:54+_接收內(nèi)容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+_接收內(nèi)容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+_接收內(nèi)容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+_接收內(nèi)容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+_接收內(nèi)容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="01600000ff000000000008000c";
string sendConstStr = "0000000100000000000000020000ff";//前面的01是EasyWatch序號,排第一個的為01,第二個的為02,在此處無關(guān)緊要
string receiveHeader="01600000FF0000000000080001";
var sendStr = sendHeader;
sendStr += GetIndex().ToString("x4");
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))
{
return true;
}
return false;
}
catch (Exception ex)
{
Console.WriteLine(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">寄存器個數(shù),當(dāng)前只支持1個寄存器</param>
/// <returns>返回值</returns>
public Int16 GetLW(int regAddress, int count)
{
//讀LW9009
//PC發(fā): 01600000ff000000000008000c00be0300003600000000000000000008ff3123000001000000
//HMI回: 01600000ff000000000008000500be03000036000000000000000000000000000040400000
//PC發(fā): 01600000ff000000000008000c00bc0300003600000000000000000008ff3123000001000000
//HMI回: 01600000ff000000000008000500bc03000036000000000000000000000000000040400000
try
{
UInt16 ret = 0;
string sendHeader = "01600000ff000000000008000c";
string sendRegConstStr = "0300003600000000000000000008ff";
string receiveHeader = "01600000ff0000000000080005";
string sendStr = sendHeader;
sendStr += GetIndex().ToString("x4");
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, 4), receiveStr.Substring(receiveHeader.Length, 4)) == 0 //包序號校驗成功
)
{
var s1 = receiveStr.Substring(66, 4);
ret = Convert.ToUInt16(s1, 16);
return (Int16)ToLittleEndian(ret);
}
return -1;
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
return -1;
}
}
public bool SetLW(int regAddress, Int16 value)
{
//寫LW9022=2024 (0xE807)|9022=0x3e23
//PC發(fā): 01600000ff000000000008000e 00d9 0300005100000000000000010008ff 3e23 0000 0100 e807 0000
//HMI回: 01600000ff0000000000080001 00d9 030000510000000000000000000000000001
// 01600000ff00000000000800010001030000510000000000000000000000000001
try
{
string sendHeader = "01600000ff000000000008000e";
string sendRegConstStr = "0300005100000000000000010008ff";
string receiveHeader = "01600000ff0000000000080001";
string sendStr = sendHeader;
sendStr += GetIndex().ToString("x4");
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, 4), receiveStr.Substring(receiveHeader.Length, 4)) == 0 //包序號校驗成功
)
{
return true;
}
return false;
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
return false;
}
}
byte[] Send(string str)
{
try
{
using (var client = new TcpClient())
{
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()}+_接收內(nèi)容{receiveData.Length}:\t" + BitConverter.ToString(receiveData));
return receiveData;
}
}catch(Exception ex)
{
Console.WriteLine(ex.Message);
return null;
}
}
/// <summary>
/// 十六進(jìn)制字符串轉(zhuǎn)字節(jié)數(shù)組
/// </summary>
/// <param name="str">要轉(zhuǎn)換的字符串</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>
/// 大端轉(zhuǎn)小端和小端轉(zhuǎn)大端的操作是相同的,共用同一個即可
/// </summary>
/// <param name="dat">要轉(zhuǎn)換的內(nèi)容</param>
/// <returns></returns>
static UInt16 ToLittleEndian(UInt16 dat)
{
return BitConverter.ToUInt16(BitConverter.GetBytes(dat).Reverse().ToArray());
}
/// <summary>
/// 大端轉(zhuǎn)小端和小端轉(zhuǎn)大端的操作是相同的,共用同一個即可
/// </summary>
/// <param name="dat">要轉(zhuǎn)換的內(nèi)容</param>
/// <returns></returns>
static UInt32 ToLittleEndian(UInt32 dat)
{
return BitConverter.ToUInt32(BitConverter.GetBytes(dat).Reverse().ToArray());
}
}
}
[ 此帖被xiapeng01在2024-04-13 15:55重新編輯 ]